xref: /csrg-svn/sys/vax/stand/uda.c (revision 33764)
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*33764Sbostic  *	@(#)uda.c	7.8 (Berkeley) 03/22/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 
3533543Sbostic #define	MAXCTLR		1		/* all addresses must be specified */
3633543Sbostic u_short udastd[MAXCTLR] = { 0772150 };
375153Ssam 
3833543Sbostic struct udadevice *udaddr[MAXNUBA][MAXCTLR];
395153Ssam 
4032613Sbostic struct	uda1 {
4132613Sbostic 	struct	uda1ca uda1_ca;	/* communications area */
4232613Sbostic 	struct	mscp uda1_rsp;	/* response packet */
4332613Sbostic 	struct	mscp uda1_cmd;	/* command packet */
4432613Sbostic } uda1;
455153Ssam 
4633543Sbostic 				/* Unibus address of uda structure */
4733543Sbostic struct	uda1 *ud_ubaddr[MAXNUBA][MAXCTLR];
4833543Sbostic struct	disklabel ralabel[MAXNUBA][MAXCTLR][NRA];
4933543Sbostic static	u_int ratype[MAXNUBA][MAXCTLR][NRA];
5030547Skarels char	lbuf[SECTSIZ];
515153Ssam 
5211111Ssam raopen(io)
535153Ssam 	register struct iob *io;
545153Ssam {
5532613Sbostic 	register struct disklabel *lp, *dlp;
5630547Skarels 	register struct udadevice *addr;
5732613Sbostic 	register struct uda1 *ubaddr;
58*33764Sbostic 	register int uba, unit;
5933543Sbostic 	static int udainit[MAXNUBA][MAXCTLR];
60*33764Sbostic 	struct iob tio;
615153Ssam 
6233543Sbostic 	if ((u_int)io->i_ctlr >= MAXCTLR)
6333543Sbostic 		return (ECTLR);
6430547Skarels 	unit = io->i_unit;
6533543Sbostic 	uba = io->i_adapt;
6633543Sbostic 	addr = udaddr[uba][io->i_ctlr] =
6733543Sbostic 	    (struct udadevice *)ubamem(uba, udastd[io->i_ctlr]);
68*33764Sbostic 	if (badaddr((char *)addr, sizeof(short)))
6930547Skarels 		return (ENXIO);
7033543Sbostic 	if (ud_ubaddr[uba][io->i_ctlr] == 0) {
71*33764Sbostic 		tio = *io;
72*33764Sbostic 		tio.i_ma = (caddr_t)&uda1;
73*33764Sbostic 		tio.i_cc = sizeof(uda1);
74*33764Sbostic 		ud_ubaddr[uba][io->i_ctlr] = (struct uda1 *)ubasetup(&tio, 2);
755153Ssam 	}
7633543Sbostic 	ubaddr = ud_ubaddr[uba][io->i_ctlr];
7733543Sbostic 	if (udainit[uba][io->i_ctlr] == 0) {
7830547Skarels 		addr->udaip = 0;
79*33764Sbostic 		while ((addr->udasa & UDA_STEP1) == 0);
8030547Skarels 		addr->udasa = UDA_ERR;
81*33764Sbostic 		while ((addr->udasa & UDA_STEP2) == 0);
8232613Sbostic 		addr->udasa = (short)&ubaddr->uda1_ca.ca_rspdsc;
83*33764Sbostic 		while ((addr->udasa & UDA_STEP3) == 0);
8430547Skarels 		addr->udasa =
8532613Sbostic 		    (short)(((int)&ubaddr->uda1_ca.ca_rspdsc) >> 16);
86*33764Sbostic 		while ((addr->udasa & UDA_STEP4) == 0);
8730547Skarels 		addr->udasa = UDA_GO;
8832613Sbostic 		uda1.uda1_ca.ca_rspdsc = (long)&ubaddr->uda1_rsp.mscp_cmdref;
8932613Sbostic 		uda1.uda1_ca.ca_cmddsc = (long)&ubaddr->uda1_cmd.mscp_cmdref;
9032613Sbostic 		/* uda1.uda1_cmd.mscp_cntflgs = 0; */
9133408Skarels 		if (udcmd(M_OP_SETCTLRC, io)) {
9232613Sbostic 			printf("ra: open error, SETCTLRC\n");
9333543Sbostic 			return (ENXIO);
9417231Smckusick 		}
9533543Sbostic 		udainit[uba][io->i_ctlr] = 1;
9627075Skarels 	}
9733543Sbostic 	lp = &ralabel[uba][io->i_ctlr][unit];
9833543Sbostic 	if (ratype[uba][io->i_ctlr][unit] == 0) {
9933543Sbostic 		uda1.uda1_cmd.mscp_unit = unit;
10033408Skarels 		if (udcmd(M_OP_ONLINE, io)) {
10132613Sbostic 			printf("ra: open error, ONLINE\n");
10233543Sbostic 			return (ENXIO);
10317231Smckusick 		}
10433543Sbostic 		ratype[uba][io->i_ctlr][unit] =
10533543Sbostic 		    uda1.uda1_rsp.mscp_onle.onle_drivetype;
10630547Skarels 		tio = *io;
10730547Skarels 		tio.i_bn = LABELSECTOR;
10830547Skarels 		tio.i_ma = lbuf;
10930547Skarels 		tio.i_cc = SECTSIZ;
11030547Skarels 		tio.i_flgs |= F_RDDATA;
111*33764Sbostic 		if (rastrategy(&tio, READ) != SECTSIZ)
112*33764Sbostic 			return (ERDLAB);
11333408Skarels 		*lp = *(struct disklabel *)(lbuf + LABELOFFSET);
114*33764Sbostic 		if (lp->d_magic != DISKMAGIC || lp->d_magic2 != DISKMAGIC)
115*33764Sbostic #ifdef COMPAT_42
116*33764Sbostic 		{
11730547Skarels 			printf("ra%d: unlabeled\n", unit);
11830547Skarels 			ramaptype(io, lp);
119*33764Sbostic 		}
12030547Skarels #else
121*33764Sbostic 			return (EUNLAB);
12230547Skarels #endif
1235153Ssam 	}
12433543Sbostic 	if ((u_int)io->i_part >= lp->d_npartitions ||
12533543Sbostic 	    (io->i_boff = lp->d_partitions[io->i_part].p_offset) == -1)
12633543Sbostic 		return (EPART);
12730547Skarels 	return (0);
1285153Ssam }
1295153Ssam 
13033408Skarels int
13130547Skarels udcmd(op, io)
1325153Ssam 	int op;
13330547Skarels 	register struct iob *io;
1345153Ssam {
13533408Skarels 	register struct uda1 *u = &uda1;
13632613Sbostic 	register struct mscp *mp;
137*33764Sbostic 	register int i;
1385153Ssam 
13933408Skarels 	u->uda1_cmd.mscp_opcode = op;
14033408Skarels 	u->uda1_cmd.mscp_msglen = MSCP_MSGLEN;
14133408Skarels 	u->uda1_rsp.mscp_msglen = MSCP_MSGLEN;
14233408Skarels 	u->uda1_ca.ca_rspdsc |= MSCP_OWN|MSCP_INT;
14333408Skarels 	u->uda1_ca.ca_cmddsc |= MSCP_OWN|MSCP_INT;
144*33764Sbostic 	i = udaddr[io->i_adapt][io->i_ctlr]->udaip;	/* start uda polling */
14533408Skarels 	mp = &u->uda1_rsp;
1465153Ssam 	for (;;) {
14733408Skarels 		if (u->uda1_ca.ca_cmdint)
14833408Skarels 			u->uda1_ca.ca_cmdint = 0;
14933408Skarels 		if (u->uda1_ca.ca_rspint == 0)
15032613Sbostic 			continue;
15133408Skarels 		u->uda1_ca.ca_rspint = 0;
15232613Sbostic 		if (mp->mscp_opcode == (op | M_OP_END))
1535153Ssam 			break;
15433408Skarels 		printf("unexpected rsp type %x op %x ignored\n",
15533408Skarels 			MSCP_MSGTYPE(mp->mscp_msgtc), mp->mscp_opcode);
15633408Skarels 		u->uda1_ca.ca_rspdsc |= MSCP_OWN | MSCP_INT;
1575153Ssam 	}
15832613Sbostic 	if ((mp->mscp_status&M_ST_MASK) != M_ST_SUCCESS)
15933408Skarels 		return (-1);
16033408Skarels 	return (0);
1615153Ssam }
1625153Ssam 
16311111Ssam rastrategy(io, func)
1645153Ssam 	register struct iob *io;
1655153Ssam {
1665153Ssam 	register struct mscp *mp;
1675153Ssam 	int ubinfo;
1685153Ssam 
1695153Ssam 	ubinfo = ubasetup(io, 1);
17032613Sbostic 	mp = &uda1.uda1_cmd;
17133543Sbostic 	mp->mscp_unit = io->i_unit;
17232613Sbostic 	mp->mscp_seq.seq_lbn = io->i_bn;
17332613Sbostic 	mp->mscp_seq.seq_bytecount = io->i_cc;
17432613Sbostic 	mp->mscp_seq.seq_buffer = (ubinfo & 0x3ffff) | (((ubinfo>>28)&0xf)<<24);
17533408Skarels 	if (udcmd(func == READ ? M_OP_READ : M_OP_WRITE, io)) {
1765153Ssam 		printf("ra: I/O error\n");
1775153Ssam 		ubafree(io, ubinfo);
1785153Ssam 		return(-1);
1795153Ssam 	}
1805153Ssam 	ubafree(io, ubinfo);
1815153Ssam 	return(io->i_cc);
1825153Ssam }
18310024Ssam 
18430547Skarels #ifdef COMPAT_42
18530547Skarels u_long ra25_off[] = { 0, 15884, 0, -1, -1, -1, 25916, -1 };
18632613Sbostic u_long rx50_off[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
18732613Sbostic u_long rd52_off[] = { 0, 15884, 0, 0, 0, 0, 25650, 0 };
18832613Sbostic u_long rd53_off[] = { 0, 15884, 0, 0, 0, 33440, 49324, 15884 };
18930547Skarels u_long ra60_off[] = { 0, 15884, 0, 49324, 131404, 49324, 242606, 49324 };
19030547Skarels u_long ra80_off[] = { 0, 15884, 0, -1, 49324, 49324, 49910, 131404 };
19130547Skarels #ifndef	UCBRA
19230547Skarels #ifdef RA_COMPAT
19330547Skarels u_long ra81_off[] = { 0, 16422, 0, 49324, 131404, 412490, 375564, 83538 };
19430547Skarels #else
19530547Skarels u_long ra81_off[] = { 0, 16422, 0, 375564, 391986, 699720, 375564, 83538 };
19630547Skarels #endif
19730547Skarels #else
19830547Skarels u_long ra81_off[] = { 0, 15884, 0, 242606, 258490, 565690, 242606, 49324 };
19930547Skarels #endif
20030547Skarels 
20132613Sbostic u_long	*ra_off[] = {
20232613Sbostic 	0,		/* 0 = unused */
20332613Sbostic 	ra80_off,	/* 1 = ra80 */
20432613Sbostic 	ra25_off,	/* 2 = rc25 removable */
20532613Sbostic 	ra25_off,	/* 3 = rc25 fixed */
20632613Sbostic 	ra60_off,	/* 4 = ra60 */
20732613Sbostic 	ra81_off,	/* 5 = ra81 */
20832613Sbostic 	0,		/* 6 = ? */
20932613Sbostic 	rx50_off,	/* 7 = rx50 */
21032613Sbostic 	rd52_off,	/* 8 = rd52 */
21132613Sbostic 	rd53_off,	/* 9 = rd53 */
21232613Sbostic };
21332613Sbostic 
21433408Skarels #define NOFFS	(sizeof(ra_off)/sizeof(ra_off[0]))
21532613Sbostic 
21630547Skarels ramaptype(io, lp)
21730547Skarels 	register struct iob *io;
21830547Skarels 	register struct disklabel *lp;
21930547Skarels {
22030547Skarels 	register struct partition *pp;
221*33764Sbostic 	register u_long *off;
22233408Skarels 	register u_int i;
22330547Skarels 
22433543Sbostic 	if ((i = ratype[io->i_adapt][io->i_ctlr][io->i_unit]) >= NOFFS ||
22533543Sbostic 	    (off = ra_off[i]) == 0) {
22632613Sbostic 		printf("ra%d: ra type %d unsupported\n", io->i_unit, i);
22730547Skarels 		lp->d_npartitions = 0;
22830547Skarels 		return;
22930547Skarels 	}
23030547Skarels 	lp->d_npartitions = 8;
23132613Sbostic 	for (pp = lp->d_partitions, i = 0; i < 8; pp++, i++)
23230547Skarels 		pp->p_offset = *off++;
23330547Skarels }
23430547Skarels #endif
235