xref: /csrg-svn/sys/vax/stand/uda.c (revision 35050)
123247Smckusick /*
2*35050Skarels  * Copyright (c) 1982, 1986, 1988 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*35050Skarels  *	@(#)uda.c	7.9 (Berkeley) 07/09/88
723247Smckusick  */
85153Ssam 
95153Ssam /*
105153Ssam  * UDA50/RAxx disk device driver
115153Ssam  */
125153Ssam 
1332613Sbostic #include "param.h"
1432613Sbostic #include "inode.h"
15*35050Skarels #include "buf.h"
1632613Sbostic #include "fs.h"
1732613Sbostic #include "disklabel.h"
189186Ssam 
19*35050Skarels #include "../vax/pte.h"
20*35050Skarels 
215153Ssam #include "saio.h"
225153Ssam #include "savax.h"
235153Ssam 
245153Ssam /*
2532613Sbostic  * Unused, but needed in udareg.h
265153Ssam  */
2732613Sbostic #define NRSP	1
2832613Sbostic #define NCMD	1
295153Ssam 
3033408Skarels #include "../vaxuba/udareg.h"
319186Ssam #include "../vaxuba/ubareg.h"
32*35050Skarels #include "../vaxuba/ubavar.h"
3333408Skarels #include "../vax/mscp.h"
345153Ssam 
35*35050Skarels #define	NRA		8	/* max. unit number on controller */
36*35050Skarels #define	SECTSIZ 	512	/* sector size in bytes */
37*35050Skarels 
3833543Sbostic #define	MAXCTLR		1		/* all addresses must be specified */
3933543Sbostic u_short udastd[MAXCTLR] = { 0772150 };
405153Ssam 
4133543Sbostic struct udadevice *udaddr[MAXNUBA][MAXCTLR];
425153Ssam 
4332613Sbostic struct	uda1 {
4432613Sbostic 	struct	uda1ca uda1_ca;	/* communications area */
4532613Sbostic 	struct	mscp uda1_rsp;	/* response packet */
4632613Sbostic 	struct	mscp uda1_cmd;	/* command packet */
4732613Sbostic } uda1;
485153Ssam 
4933543Sbostic 				/* Unibus address of uda structure */
5033543Sbostic struct	uda1 *ud_ubaddr[MAXNUBA][MAXCTLR];
5133543Sbostic struct	disklabel ralabel[MAXNUBA][MAXCTLR][NRA];
52*35050Skarels static	u_long ramedia[MAXNUBA][MAXCTLR][NRA];
5330547Skarels char	lbuf[SECTSIZ];
545153Ssam 
5511111Ssam raopen(io)
565153Ssam 	register struct iob *io;
575153Ssam {
58*35050Skarels 	register struct disklabel *lp;
5930547Skarels 	register struct udadevice *addr;
60*35050Skarels 	register struct uda1 *ubaaddr;
6133764Sbostic 	register int uba, unit;
6233543Sbostic 	static int udainit[MAXNUBA][MAXCTLR];
6333764Sbostic 	struct iob tio;
645153Ssam 
65*35050Skarels 	if ((u_int)(uba = io->i_adapt) >= nuba)
66*35050Skarels 		return (EADAPT);
6733543Sbostic 	if ((u_int)io->i_ctlr >= MAXCTLR)
6833543Sbostic 		return (ECTLR);
69*35050Skarels 	if ((u_int)(unit = io->i_unit) >= NRA)
70*35050Skarels 		return (EUNIT);
7133543Sbostic 	addr = udaddr[uba][io->i_ctlr] =
7233543Sbostic 	    (struct udadevice *)ubamem(uba, udastd[io->i_ctlr]);
7333764Sbostic 	if (badaddr((char *)addr, sizeof(short)))
7430547Skarels 		return (ENXIO);
75*35050Skarels 	if ((ubaaddr = ud_ubaddr[uba][io->i_ctlr]) == 0) {
7633764Sbostic 		tio = *io;
7733764Sbostic 		tio.i_ma = (caddr_t)&uda1;
7833764Sbostic 		tio.i_cc = sizeof(uda1);
79*35050Skarels 		ud_ubaddr[uba][io->i_ctlr] = ubaaddr =
80*35050Skarels 		    (struct uda1 *)ubasetup(&tio, 2);
815153Ssam 	}
8233543Sbostic 	if (udainit[uba][io->i_ctlr] == 0) {
8330547Skarels 		addr->udaip = 0;
8433764Sbostic 		while ((addr->udasa & UDA_STEP1) == 0);
8530547Skarels 		addr->udasa = UDA_ERR;
8633764Sbostic 		while ((addr->udasa & UDA_STEP2) == 0);
87*35050Skarels 		addr->udasa = (int)&ubaaddr->uda1_ca.ca_rspdsc;
8833764Sbostic 		while ((addr->udasa & UDA_STEP3) == 0);
89*35050Skarels 		addr->udasa = (int)&ubaaddr->uda1_ca.ca_rspdsc >> 16;
9033764Sbostic 		while ((addr->udasa & UDA_STEP4) == 0);
9130547Skarels 		addr->udasa = UDA_GO;
92*35050Skarels 		uda1.uda1_ca.ca_rspdsc = (long)&ubaaddr->uda1_rsp.mscp_cmdref;
93*35050Skarels 		uda1.uda1_ca.ca_cmddsc = (long)&ubaaddr->uda1_cmd.mscp_cmdref;
9432613Sbostic 		/* uda1.uda1_cmd.mscp_cntflgs = 0; */
9533408Skarels 		if (udcmd(M_OP_SETCTLRC, io)) {
9632613Sbostic 			printf("ra: open error, SETCTLRC\n");
9733543Sbostic 			return (ENXIO);
9817231Smckusick 		}
9933543Sbostic 		udainit[uba][io->i_ctlr] = 1;
10027075Skarels 	}
10133543Sbostic 	lp = &ralabel[uba][io->i_ctlr][unit];
102*35050Skarels 	if (ramedia[uba][io->i_ctlr][unit] == 0) {
10333543Sbostic 		uda1.uda1_cmd.mscp_unit = unit;
10433408Skarels 		if (udcmd(M_OP_ONLINE, io)) {
10532613Sbostic 			printf("ra: open error, ONLINE\n");
10633543Sbostic 			return (ENXIO);
10717231Smckusick 		}
108*35050Skarels 		ramedia[uba][io->i_ctlr][unit] =
109*35050Skarels 		    uda1.uda1_rsp.mscp_onle.onle_mediaid;
11030547Skarels 		tio = *io;
11130547Skarels 		tio.i_bn = LABELSECTOR;
11230547Skarels 		tio.i_ma = lbuf;
11330547Skarels 		tio.i_cc = SECTSIZ;
11430547Skarels 		tio.i_flgs |= F_RDDATA;
11533764Sbostic 		if (rastrategy(&tio, READ) != SECTSIZ)
11633764Sbostic 			return (ERDLAB);
11733408Skarels 		*lp = *(struct disklabel *)(lbuf + LABELOFFSET);
118*35050Skarels 		if (lp->d_magic != DISKMAGIC || lp->d_magic2 != DISKMAGIC) {
11933764Sbostic #ifdef COMPAT_42
12030547Skarels 			printf("ra%d: unlabeled\n", unit);
12130547Skarels 			ramaptype(io, lp);
12230547Skarels #else
12333764Sbostic 			return (EUNLAB);
12430547Skarels #endif
125*35050Skarels 		}
1265153Ssam 	}
12733543Sbostic 	if ((u_int)io->i_part >= lp->d_npartitions ||
12833543Sbostic 	    (io->i_boff = lp->d_partitions[io->i_part].p_offset) == -1)
12933543Sbostic 		return (EPART);
13030547Skarels 	return (0);
1315153Ssam }
1325153Ssam 
13333408Skarels int
13430547Skarels udcmd(op, io)
1355153Ssam 	int op;
13630547Skarels 	register struct iob *io;
1375153Ssam {
13833408Skarels 	register struct uda1 *u = &uda1;
13932613Sbostic 	register struct mscp *mp;
14033764Sbostic 	register int i;
1415153Ssam 
14233408Skarels 	u->uda1_cmd.mscp_opcode = op;
14333408Skarels 	u->uda1_cmd.mscp_msglen = MSCP_MSGLEN;
14433408Skarels 	u->uda1_rsp.mscp_msglen = MSCP_MSGLEN;
14533408Skarels 	u->uda1_ca.ca_rspdsc |= MSCP_OWN|MSCP_INT;
14633408Skarels 	u->uda1_ca.ca_cmddsc |= MSCP_OWN|MSCP_INT;
14733764Sbostic 	i = udaddr[io->i_adapt][io->i_ctlr]->udaip;	/* start uda polling */
148*35050Skarels #ifdef lint
149*35050Skarels 	i = i;
150*35050Skarels #endif
15133408Skarels 	mp = &u->uda1_rsp;
1525153Ssam 	for (;;) {
15333408Skarels 		if (u->uda1_ca.ca_cmdint)
15433408Skarels 			u->uda1_ca.ca_cmdint = 0;
15533408Skarels 		if (u->uda1_ca.ca_rspint == 0)
15632613Sbostic 			continue;
15733408Skarels 		u->uda1_ca.ca_rspint = 0;
15832613Sbostic 		if (mp->mscp_opcode == (op | M_OP_END))
1595153Ssam 			break;
16033408Skarels 		printf("unexpected rsp type %x op %x ignored\n",
16133408Skarels 			MSCP_MSGTYPE(mp->mscp_msgtc), mp->mscp_opcode);
16233408Skarels 		u->uda1_ca.ca_rspdsc |= MSCP_OWN | MSCP_INT;
1635153Ssam 	}
16432613Sbostic 	if ((mp->mscp_status&M_ST_MASK) != M_ST_SUCCESS)
16533408Skarels 		return (-1);
16633408Skarels 	return (0);
1675153Ssam }
1685153Ssam 
16911111Ssam rastrategy(io, func)
1705153Ssam 	register struct iob *io;
171*35050Skarels 	int func;
1725153Ssam {
1735153Ssam 	register struct mscp *mp;
174*35050Skarels 	register int ubinfo;
1755153Ssam 
1765153Ssam 	ubinfo = ubasetup(io, 1);
17732613Sbostic 	mp = &uda1.uda1_cmd;
17833543Sbostic 	mp->mscp_unit = io->i_unit;
17932613Sbostic 	mp->mscp_seq.seq_lbn = io->i_bn;
18032613Sbostic 	mp->mscp_seq.seq_bytecount = io->i_cc;
181*35050Skarels 	mp->mscp_seq.seq_buffer = UBAI_ADDR(ubinfo) | (UBAI_BDP(ubinfo) << 24);
18233408Skarels 	if (udcmd(func == READ ? M_OP_READ : M_OP_WRITE, io)) {
1835153Ssam 		printf("ra: I/O error\n");
1845153Ssam 		ubafree(io, ubinfo);
185*35050Skarels 		return (-1);
1865153Ssam 	}
1875153Ssam 	ubafree(io, ubinfo);
188*35050Skarels 	return (io->i_cc);
1895153Ssam }
19010024Ssam 
19130547Skarels #ifdef COMPAT_42
192*35050Skarels u_long rc25_off[] = { 0, 15884, 0, -1, -1, -1, 25916, -1 };
19332613Sbostic u_long rx50_off[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
19432613Sbostic u_long rd52_off[] = { 0, 15884, 0, 0, 0, 0, 25650, 0 };
19532613Sbostic u_long rd53_off[] = { 0, 15884, 0, 0, 0, 33440, 49324, 15884 };
19630547Skarels u_long ra60_off[] = { 0, 15884, 0, 49324, 131404, 49324, 242606, 49324 };
197*35050Skarels #define ra70_off ra60_off
19830547Skarels u_long ra80_off[] = { 0, 15884, 0, -1, 49324, 49324, 49910, 131404 };
19930547Skarels #ifndef	UCBRA
20030547Skarels #ifdef RA_COMPAT
20130547Skarels u_long ra81_off[] = { 0, 16422, 0, 49324, 131404, 412490, 375564, 83538 };
20230547Skarels #else
20330547Skarels u_long ra81_off[] = { 0, 16422, 0, 375564, 391986, 699720, 375564, 83538 };
20430547Skarels #endif
20530547Skarels #else
20630547Skarels u_long ra81_off[] = { 0, 15884, 0, 242606, 258490, 565690, 242606, 49324 };
20730547Skarels #endif
208*35050Skarels u_long ra82_off[] = { 0, 15884, 0, 375345, 391590, 699390, 375345, 83790 };
20930547Skarels 
210*35050Skarels struct mediamap {
211*35050Skarels 	u_long	id;		/* media ID */
212*35050Skarels 	u_long	*off;		/* offsets */
213*35050Skarels } ra_map[] = {
214*35050Skarels 	{ MSCP_MKDRIVE2('R', 'A', 60),		ra60_off },
215*35050Skarels 	{ MSCP_MKDRIVE2('R', 'A', 70),		ra70_off },
216*35050Skarels 	{ MSCP_MKDRIVE2('R', 'A', 80),		ra80_off },
217*35050Skarels 	{ MSCP_MKDRIVE2('R', 'A', 81),		ra81_off },
218*35050Skarels 	{ MSCP_MKDRIVE2('R', 'A', 82),		ra82_off },
219*35050Skarels 	{ MSCP_MKDRIVE2('R', 'C', 25),		rc25_off },
220*35050Skarels 	{ MSCP_MKDRIVE3('R', 'C', 'F', 25),	rc25_off },
221*35050Skarels 	{ MSCP_MKDRIVE2('R', 'D', 52),		rd52_off },
222*35050Skarels 	{ MSCP_MKDRIVE2('R', 'D', 53),		rd53_off },
223*35050Skarels 	{ MSCP_MKDRIVE2('R', 'X', 50),		rx50_off },
224*35050Skarels 	0
22532613Sbostic };
22632613Sbostic 
22730547Skarels ramaptype(io, lp)
22830547Skarels 	register struct iob *io;
22930547Skarels 	register struct disklabel *lp;
23030547Skarels {
23130547Skarels 	register struct partition *pp;
232*35050Skarels 	register u_long i;
233*35050Skarels 	register struct mediamap *map;
23430547Skarels 
235*35050Skarels 	i = MSCP_MEDIA_DRIVE(ramedia[io->i_adapt][io->i_ctlr][io->i_unit]);
236*35050Skarels 	for (map = ra_map; map->id != 0; map++) {
237*35050Skarels 		if (map->id == i) {
238*35050Skarels 			lp->d_npartitions = 8;
239*35050Skarels 			for (pp = lp->d_partitions, i = 0; i < 8; pp++, i++)
240*35050Skarels 				pp->p_offset = map->off[i];
241*35050Skarels 			return;
242*35050Skarels 		}
24330547Skarels 	}
244*35050Skarels 	printf("ra%d: media type 0x%x unsupported\n", io->i_unit, i);
245*35050Skarels 	lp->d_npartitions = 0;
24630547Skarels }
24730547Skarels #endif
248