xref: /csrg-svn/sys/vax/stand/uda.c (revision 33543)
123247Smckusick /*
229315Smckusick  * Copyright (c) 1982, 1986 Regents of the University of California.
323247Smckusick  * All rights reserved.  The Berkeley software License Agreement
423247Smckusick  * specifies the terms and conditions for redistribution.
523247Smckusick  *
6*33543Sbostic  *	@(#)uda.c	7.7 (Berkeley) 02/23/88
723247Smckusick  */
85153Ssam 
95153Ssam /*
105153Ssam  * UDA50/RAxx disk device driver
115153Ssam  */
129806Ssam #include "../machine/pte.h"
135153Ssam 
1432613Sbostic #include "param.h"
1532613Sbostic #include "inode.h"
1632613Sbostic #include "fs.h"
1732613Sbostic #include "disklabel.h"
189186Ssam 
195153Ssam #include "saio.h"
205153Ssam #include "savax.h"
215153Ssam 
2232613Sbostic #define	NRA		8	/* max. unit number on controller */
2330547Skarels #define	SECTSIZ 	512	/* sector size in bytes */
2432613Sbostic 
255153Ssam /*
2632613Sbostic  * Unused, but needed in udareg.h
275153Ssam  */
2832613Sbostic #define NRSP	1
2932613Sbostic #define NCMD	1
305153Ssam 
3133408Skarels #include "../vaxuba/udareg.h"
329186Ssam #include "../vaxuba/ubareg.h"
3333408Skarels #include "../vax/mscp.h"
345153Ssam 
35*33543Sbostic #define	MAXCTLR		1		/* all addresses must be specified */
36*33543Sbostic u_short udastd[MAXCTLR] = { 0772150 };
375153Ssam 
385153Ssam struct iob	cudbuf;
395153Ssam 
40*33543Sbostic struct udadevice *udaddr[MAXNUBA][MAXCTLR];
415153Ssam 
4232613Sbostic struct	uda1 {
4332613Sbostic 	struct	uda1ca uda1_ca;	/* communications area */
4432613Sbostic 	struct	mscp uda1_rsp;	/* response packet */
4532613Sbostic 	struct	mscp uda1_cmd;	/* command packet */
4632613Sbostic } uda1;
475153Ssam 
48*33543Sbostic 				/* Unibus address of uda structure */
49*33543Sbostic struct	uda1 *ud_ubaddr[MAXNUBA][MAXCTLR];
50*33543Sbostic struct	disklabel ralabel[MAXNUBA][MAXCTLR][NRA];
51*33543Sbostic static	u_int ratype[MAXNUBA][MAXCTLR][NRA];
5230547Skarels char	lbuf[SECTSIZ];
535153Ssam 
5411111Ssam raopen(io)
555153Ssam 	register struct iob *io;
565153Ssam {
575153Ssam 	register struct mscp *mp;
5832613Sbostic 	register struct disklabel *lp, *dlp;
5930547Skarels 	register struct udadevice *addr;
6032613Sbostic 	register struct uda1 *ubaddr;
6130547Skarels 	register unit;
62*33543Sbostic 	static int udainit[MAXNUBA][MAXCTLR];
6330547Skarels 	int uba;
645153Ssam 
65*33543Sbostic 	if ((u_int)io->i_ctlr >= MAXCTLR)
66*33543Sbostic 		return (ECTLR);
6730547Skarels 	unit = io->i_unit;
68*33543Sbostic 	uba = io->i_adapt;
69*33543Sbostic 	addr = udaddr[uba][io->i_ctlr] =
70*33543Sbostic 	    (struct udadevice *)ubamem(uba, udastd[io->i_ctlr]);
7130547Skarels 	if (badaddr((char *)addr, sizeof(short))) {
72*33543Sbostic 		printf("ra: nonexistent device\n");
7330547Skarels 		return (ENXIO);
7430547Skarels 	}
75*33543Sbostic 	if (ud_ubaddr[uba][io->i_ctlr] == 0) {
7617231Smckusick 		/*
7730547Skarels 		 * Initialize cudbuf.i_unit so that controllers
7817231Smckusick 		 * on UNIBUSes other than 0 can be used.
7917231Smckusick 		 */
8030547Skarels 		cudbuf.i_unit = unit;
8132613Sbostic 		cudbuf.i_ma = (caddr_t)&uda1;
8232613Sbostic 		cudbuf.i_cc = sizeof(uda1);
83*33543Sbostic 		ud_ubaddr[uba][io->i_ctlr] = (struct uda1 *)ubasetup(&cudbuf, 2);
845153Ssam 	}
85*33543Sbostic 	ubaddr = ud_ubaddr[uba][io->i_ctlr];
86*33543Sbostic 	if (udainit[uba][io->i_ctlr] == 0) {
8730547Skarels 		addr->udaip = 0;
8830547Skarels 		while ((addr->udasa & UDA_STEP1) == 0)
8917231Smckusick 			;
9030547Skarels 		addr->udasa = UDA_ERR;
9130547Skarels 		while ((addr->udasa & UDA_STEP2) == 0)
9217231Smckusick 			;
9332613Sbostic 		addr->udasa = (short)&ubaddr->uda1_ca.ca_rspdsc;
9430547Skarels 		while ((addr->udasa & UDA_STEP3) == 0)
9517231Smckusick 			;
9630547Skarels 		addr->udasa =
9732613Sbostic 		    (short)(((int)&ubaddr->uda1_ca.ca_rspdsc) >> 16);
9830547Skarels 		while ((addr->udasa & UDA_STEP4) == 0)
9917231Smckusick 			;
10030547Skarels 		addr->udasa = UDA_GO;
10132613Sbostic 		uda1.uda1_ca.ca_rspdsc = (long)&ubaddr->uda1_rsp.mscp_cmdref;
10232613Sbostic 		uda1.uda1_ca.ca_cmddsc = (long)&ubaddr->uda1_cmd.mscp_cmdref;
10332613Sbostic 		/* uda1.uda1_cmd.mscp_cntflgs = 0; */
10433408Skarels 		if (udcmd(M_OP_SETCTLRC, io)) {
10532613Sbostic 			printf("ra: open error, SETCTLRC\n");
106*33543Sbostic 			return (ENXIO);
10717231Smckusick 		}
108*33543Sbostic 		udainit[uba][io->i_ctlr] = 1;
10927075Skarels 	}
110*33543Sbostic 	lp = &ralabel[uba][io->i_ctlr][unit];
111*33543Sbostic 	if (ratype[uba][io->i_ctlr][unit] == 0) {
11230547Skarels 		struct iob tio;
11330547Skarels 
114*33543Sbostic 		uda1.uda1_cmd.mscp_unit = unit;
11533408Skarels 		if (udcmd(M_OP_ONLINE, io)) {
11632613Sbostic 			printf("ra: open error, ONLINE\n");
117*33543Sbostic 			return (ENXIO);
11817231Smckusick 		}
119*33543Sbostic 		ratype[uba][io->i_ctlr][unit] =
120*33543Sbostic 		    uda1.uda1_rsp.mscp_onle.onle_drivetype;
12130547Skarels 		tio = *io;
12230547Skarels 		tio.i_bn = LABELSECTOR;
12330547Skarels 		tio.i_ma = lbuf;
12430547Skarels 		tio.i_cc = SECTSIZ;
12530547Skarels 		tio.i_flgs |= F_RDDATA;
12630547Skarels 		if (rastrategy(&tio, READ) != SECTSIZ) {
127*33543Sbostic 			printf("ra: can't read disk label\n");
128*33543Sbostic 			return (ENXIO);
12930547Skarels 		}
13033408Skarels 		*lp = *(struct disklabel *)(lbuf + LABELOFFSET);
13133408Skarels 		if (lp->d_magic != DISKMAGIC || lp->d_magic2 != DISKMAGIC) {
13230547Skarels 			printf("ra%d: unlabeled\n", unit);
13330547Skarels #ifdef COMPAT_42
13430547Skarels 			ramaptype(io, lp);
13530547Skarels #else
13630547Skarels 			return (ENXIO);
13730547Skarels #endif
13833408Skarels 		}
1395153Ssam 	}
140*33543Sbostic 	if ((u_int)io->i_part >= lp->d_npartitions ||
141*33543Sbostic 	    (io->i_boff = lp->d_partitions[io->i_part].p_offset) == -1)
142*33543Sbostic 		return (EPART);
14330547Skarels 	return (0);
1445153Ssam }
1455153Ssam 
14633408Skarels int
14730547Skarels udcmd(op, io)
1485153Ssam 	int op;
14930547Skarels 	register struct iob *io;
1505153Ssam {
15133408Skarels 	register struct uda1 *u = &uda1;
15232613Sbostic 	register struct mscp *mp;
1535153Ssam 	int i;
1545153Ssam 
15533408Skarels 	u->uda1_cmd.mscp_opcode = op;
15633408Skarels 	u->uda1_cmd.mscp_msglen = MSCP_MSGLEN;
15733408Skarels 	u->uda1_rsp.mscp_msglen = MSCP_MSGLEN;
15833408Skarels 	u->uda1_ca.ca_rspdsc |= MSCP_OWN|MSCP_INT;
15933408Skarels 	u->uda1_ca.ca_cmddsc |= MSCP_OWN|MSCP_INT;
160*33543Sbostic 	i = udaddr[io->i_adapt][io->i_ctlr]->udaip;
16133408Skarels 	mp = &u->uda1_rsp;
1625153Ssam 	for (;;) {
16333408Skarels 		if (u->uda1_ca.ca_cmdint)
16433408Skarels 			u->uda1_ca.ca_cmdint = 0;
16533408Skarels 		if (u->uda1_ca.ca_rspint == 0)
16632613Sbostic 			continue;
16733408Skarels 		u->uda1_ca.ca_rspint = 0;
16832613Sbostic 		if (mp->mscp_opcode == (op | M_OP_END))
1695153Ssam 			break;
17033408Skarels 		printf("unexpected rsp type %x op %x ignored\n",
17133408Skarels 			MSCP_MSGTYPE(mp->mscp_msgtc), mp->mscp_opcode);
17233408Skarels 		u->uda1_ca.ca_rspdsc |= MSCP_OWN | MSCP_INT;
1735153Ssam 	}
17432613Sbostic 	if ((mp->mscp_status&M_ST_MASK) != M_ST_SUCCESS)
17533408Skarels 		return (-1);
17633408Skarels 	return (0);
1775153Ssam }
1785153Ssam 
17911111Ssam rastrategy(io, func)
1805153Ssam 	register struct iob *io;
1815153Ssam {
1825153Ssam 	register struct mscp *mp;
1835153Ssam 	int ubinfo;
1845153Ssam 
1855153Ssam 	ubinfo = ubasetup(io, 1);
18632613Sbostic 	mp = &uda1.uda1_cmd;
187*33543Sbostic 	mp->mscp_unit = io->i_unit;
18832613Sbostic 	mp->mscp_seq.seq_lbn = io->i_bn;
18932613Sbostic 	mp->mscp_seq.seq_bytecount = io->i_cc;
19032613Sbostic 	mp->mscp_seq.seq_buffer = (ubinfo & 0x3ffff) | (((ubinfo>>28)&0xf)<<24);
19133408Skarels 	if (udcmd(func == READ ? M_OP_READ : M_OP_WRITE, io)) {
1925153Ssam 		printf("ra: I/O error\n");
1935153Ssam 		ubafree(io, ubinfo);
1945153Ssam 		return(-1);
1955153Ssam 	}
1965153Ssam 	ubafree(io, ubinfo);
1975153Ssam 	return(io->i_cc);
1985153Ssam }
19910024Ssam 
20030547Skarels #ifdef COMPAT_42
20130547Skarels u_long ra25_off[] = { 0, 15884, 0, -1, -1, -1, 25916, -1 };
20232613Sbostic u_long rx50_off[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
20332613Sbostic u_long rd52_off[] = { 0, 15884, 0, 0, 0, 0, 25650, 0 };
20432613Sbostic u_long rd53_off[] = { 0, 15884, 0, 0, 0, 33440, 49324, 15884 };
20530547Skarels u_long ra60_off[] = { 0, 15884, 0, 49324, 131404, 49324, 242606, 49324 };
20630547Skarels u_long ra80_off[] = { 0, 15884, 0, -1, 49324, 49324, 49910, 131404 };
20730547Skarels #ifndef	UCBRA
20830547Skarels #ifdef RA_COMPAT
20930547Skarels u_long ra81_off[] = { 0, 16422, 0, 49324, 131404, 412490, 375564, 83538 };
21030547Skarels #else
21130547Skarels u_long ra81_off[] = { 0, 16422, 0, 375564, 391986, 699720, 375564, 83538 };
21230547Skarels #endif
21330547Skarels #else
21430547Skarels u_long ra81_off[] = { 0, 15884, 0, 242606, 258490, 565690, 242606, 49324 };
21530547Skarels #endif
21630547Skarels 
21732613Sbostic u_long	*ra_off[] = {
21832613Sbostic 	0,		/* 0 = unused */
21932613Sbostic 	ra80_off,	/* 1 = ra80 */
22032613Sbostic 	ra25_off,	/* 2 = rc25 removable */
22132613Sbostic 	ra25_off,	/* 3 = rc25 fixed */
22232613Sbostic 	ra60_off,	/* 4 = ra60 */
22332613Sbostic 	ra81_off,	/* 5 = ra81 */
22432613Sbostic 	0,		/* 6 = ? */
22532613Sbostic 	rx50_off,	/* 7 = rx50 */
22632613Sbostic 	rd52_off,	/* 8 = rd52 */
22732613Sbostic 	rd53_off,	/* 9 = rd53 */
22832613Sbostic };
22932613Sbostic 
23033408Skarels #define NOFFS	(sizeof(ra_off)/sizeof(ra_off[0]))
23132613Sbostic 
23230547Skarels ramaptype(io, lp)
23330547Skarels 	register struct iob *io;
23430547Skarels 	register struct disklabel *lp;
23530547Skarels {
23630547Skarels 	register struct partition *pp;
23733408Skarels 	register u_int i;
23830547Skarels 	register u_long *off;
23930547Skarels 
240*33543Sbostic 	if ((i = ratype[io->i_adapt][io->i_ctlr][io->i_unit]) >= NOFFS ||
241*33543Sbostic 	    (off = ra_off[i]) == 0) {
24232613Sbostic 		printf("ra%d: ra type %d unsupported\n", io->i_unit, i);
24330547Skarels 		lp->d_npartitions = 0;
24430547Skarels 		return;
24530547Skarels 	}
24630547Skarels 	lp->d_npartitions = 8;
24732613Sbostic 	for (pp = lp->d_partitions, i = 0; i < 8; pp++, i++)
24830547Skarels 		pp->p_offset = *off++;
24930547Skarels }
25030547Skarels #endif
251