xref: /csrg-svn/sys/vax/stand/uda.c (revision 49100)
123247Smckusick /*
235050Skarels  * 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*49100Sbostic  *	@(#)uda.c	7.12 (Berkeley) 05/04/91
723247Smckusick  */
85153Ssam 
95153Ssam /*
105153Ssam  * UDA50/RAxx disk device driver
115153Ssam  */
125153Ssam 
1345803Sbostic #include "sys/param.h"
1445803Sbostic #include "sys/buf.h"
1545803Sbostic #include "sys/disklabel.h"
169186Ssam 
1745803Sbostic #include "../include/pte.h"
1835050Skarels 
1945803Sbostic #include "stand/saio.h"
205153Ssam #include "savax.h"
215153Ssam 
225153Ssam /*
2332613Sbostic  * Unused, but needed in udareg.h
245153Ssam  */
2532613Sbostic #define NRSP	1
2632613Sbostic #define NCMD	1
275153Ssam 
2845803Sbostic #include "../uba/udareg.h"
2945803Sbostic #include "../uba/ubareg.h"
3045803Sbostic #include "../uba/ubavar.h"
3133408Skarels #include "../vax/mscp.h"
325153Ssam 
3335050Skarels #define	NRA		8	/* max. unit number on controller */
3435050Skarels #define	SECTSIZ 	512	/* sector size in bytes */
3535050Skarels 
3633543Sbostic #define	MAXCTLR		1		/* all addresses must be specified */
3733543Sbostic u_short udastd[MAXCTLR] = { 0772150 };
385153Ssam 
3933543Sbostic struct udadevice *udaddr[MAXNUBA][MAXCTLR];
405153Ssam 
4132613Sbostic struct	uda1 {
4232613Sbostic 	struct	uda1ca uda1_ca;	/* communications area */
4332613Sbostic 	struct	mscp uda1_rsp;	/* response packet */
4432613Sbostic 	struct	mscp uda1_cmd;	/* command packet */
4532613Sbostic } uda1;
465153Ssam 
4733543Sbostic 				/* Unibus address of uda structure */
4833543Sbostic struct	uda1 *ud_ubaddr[MAXNUBA][MAXCTLR];
4933543Sbostic struct	disklabel ralabel[MAXNUBA][MAXCTLR][NRA];
5035050Skarels static	u_long ramedia[MAXNUBA][MAXCTLR][NRA];
5130547Skarels char	lbuf[SECTSIZ];
525153Ssam 
raopen(io)5311111Ssam raopen(io)
545153Ssam 	register struct iob *io;
555153Ssam {
5635050Skarels 	register struct disklabel *lp;
5730547Skarels 	register struct udadevice *addr;
5835050Skarels 	register struct uda1 *ubaaddr;
5933764Sbostic 	register int uba, unit;
6033543Sbostic 	static int udainit[MAXNUBA][MAXCTLR];
6133764Sbostic 	struct iob tio;
625153Ssam 
6335050Skarels 	if ((u_int)(uba = io->i_adapt) >= nuba)
6435050Skarels 		return (EADAPT);
6533543Sbostic 	if ((u_int)io->i_ctlr >= MAXCTLR)
6633543Sbostic 		return (ECTLR);
6735050Skarels 	if ((u_int)(unit = io->i_unit) >= NRA)
6835050Skarels 		return (EUNIT);
6933543Sbostic 	addr = udaddr[uba][io->i_ctlr] =
7033543Sbostic 	    (struct udadevice *)ubamem(uba, udastd[io->i_ctlr]);
7133764Sbostic 	if (badaddr((char *)addr, sizeof(short)))
7230547Skarels 		return (ENXIO);
7335050Skarels 	if ((ubaaddr = ud_ubaddr[uba][io->i_ctlr]) == 0) {
7433764Sbostic 		tio = *io;
7533764Sbostic 		tio.i_ma = (caddr_t)&uda1;
7633764Sbostic 		tio.i_cc = sizeof(uda1);
7735050Skarels 		ud_ubaddr[uba][io->i_ctlr] = ubaaddr =
7835050Skarels 		    (struct uda1 *)ubasetup(&tio, 2);
795153Ssam 	}
8033543Sbostic 	if (udainit[uba][io->i_ctlr] == 0) {
8130547Skarels 		addr->udaip = 0;
8233764Sbostic 		while ((addr->udasa & UDA_STEP1) == 0);
8330547Skarels 		addr->udasa = UDA_ERR;
8433764Sbostic 		while ((addr->udasa & UDA_STEP2) == 0);
8535050Skarels 		addr->udasa = (int)&ubaaddr->uda1_ca.ca_rspdsc;
8633764Sbostic 		while ((addr->udasa & UDA_STEP3) == 0);
8735050Skarels 		addr->udasa = (int)&ubaaddr->uda1_ca.ca_rspdsc >> 16;
8833764Sbostic 		while ((addr->udasa & UDA_STEP4) == 0);
8930547Skarels 		addr->udasa = UDA_GO;
9035050Skarels 		uda1.uda1_ca.ca_rspdsc = (long)&ubaaddr->uda1_rsp.mscp_cmdref;
9135050Skarels 		uda1.uda1_ca.ca_cmddsc = (long)&ubaaddr->uda1_cmd.mscp_cmdref;
9232613Sbostic 		/* uda1.uda1_cmd.mscp_cntflgs = 0; */
9333408Skarels 		if (udcmd(M_OP_SETCTLRC, io)) {
9432613Sbostic 			printf("ra: open error, SETCTLRC\n");
9533543Sbostic 			return (ENXIO);
9617231Smckusick 		}
9733543Sbostic 		udainit[uba][io->i_ctlr] = 1;
9827075Skarels 	}
9933543Sbostic 	lp = &ralabel[uba][io->i_ctlr][unit];
10035050Skarels 	if (ramedia[uba][io->i_ctlr][unit] == 0) {
10133543Sbostic 		uda1.uda1_cmd.mscp_unit = unit;
10233408Skarels 		if (udcmd(M_OP_ONLINE, io)) {
10332613Sbostic 			printf("ra: open error, ONLINE\n");
10433543Sbostic 			return (ENXIO);
10517231Smckusick 		}
10635050Skarels 		ramedia[uba][io->i_ctlr][unit] =
10735050Skarels 		    uda1.uda1_rsp.mscp_onle.onle_mediaid;
10830547Skarels 		tio = *io;
10930547Skarels 		tio.i_bn = LABELSECTOR;
11030547Skarels 		tio.i_ma = lbuf;
11130547Skarels 		tio.i_cc = SECTSIZ;
11230547Skarels 		tio.i_flgs |= F_RDDATA;
113*49100Sbostic 		if (rastrategy(&tio, F_READ) != SECTSIZ)
11433764Sbostic 			return (ERDLAB);
11533408Skarels 		*lp = *(struct disklabel *)(lbuf + LABELOFFSET);
11635050Skarels 		if (lp->d_magic != DISKMAGIC || lp->d_magic2 != DISKMAGIC) {
11733764Sbostic #ifdef COMPAT_42
11830547Skarels 			printf("ra%d: unlabeled\n", unit);
11930547Skarels 			ramaptype(io, lp);
12030547Skarels #else
12133764Sbostic 			return (EUNLAB);
12230547Skarels #endif
12335050Skarels 		}
1245153Ssam 	}
12533543Sbostic 	if ((u_int)io->i_part >= lp->d_npartitions ||
12633543Sbostic 	    (io->i_boff = lp->d_partitions[io->i_part].p_offset) == -1)
12733543Sbostic 		return (EPART);
12830547Skarels 	return (0);
1295153Ssam }
1305153Ssam 
13133408Skarels int
udcmd(op,io)13230547Skarels udcmd(op, io)
1335153Ssam 	int op;
13430547Skarels 	register struct iob *io;
1355153Ssam {
13633408Skarels 	register struct uda1 *u = &uda1;
13732613Sbostic 	register struct mscp *mp;
13833764Sbostic 	register int i;
1395153Ssam 
14033408Skarels 	u->uda1_cmd.mscp_opcode = op;
14133408Skarels 	u->uda1_cmd.mscp_msglen = MSCP_MSGLEN;
14233408Skarels 	u->uda1_rsp.mscp_msglen = MSCP_MSGLEN;
14333408Skarels 	u->uda1_ca.ca_rspdsc |= MSCP_OWN|MSCP_INT;
14433408Skarels 	u->uda1_ca.ca_cmddsc |= MSCP_OWN|MSCP_INT;
14533764Sbostic 	i = udaddr[io->i_adapt][io->i_ctlr]->udaip;	/* start uda polling */
14635050Skarels #ifdef lint
14735050Skarels 	i = i;
14835050Skarels #endif
14933408Skarels 	mp = &u->uda1_rsp;
1505153Ssam 	for (;;) {
15133408Skarels 		if (u->uda1_ca.ca_cmdint)
15233408Skarels 			u->uda1_ca.ca_cmdint = 0;
15333408Skarels 		if (u->uda1_ca.ca_rspint == 0)
15432613Sbostic 			continue;
15533408Skarels 		u->uda1_ca.ca_rspint = 0;
15632613Sbostic 		if (mp->mscp_opcode == (op | M_OP_END))
1575153Ssam 			break;
15833408Skarels 		printf("unexpected rsp type %x op %x ignored\n",
15933408Skarels 			MSCP_MSGTYPE(mp->mscp_msgtc), mp->mscp_opcode);
16033408Skarels 		u->uda1_ca.ca_rspdsc |= MSCP_OWN | MSCP_INT;
1615153Ssam 	}
16232613Sbostic 	if ((mp->mscp_status&M_ST_MASK) != M_ST_SUCCESS)
16333408Skarels 		return (-1);
16433408Skarels 	return (0);
1655153Ssam }
1665153Ssam 
rastrategy(io,func)16711111Ssam rastrategy(io, func)
1685153Ssam 	register struct iob *io;
16935050Skarels 	int func;
1705153Ssam {
1715153Ssam 	register struct mscp *mp;
17235050Skarels 	register int ubinfo;
1735153Ssam 
1745153Ssam 	ubinfo = ubasetup(io, 1);
17532613Sbostic 	mp = &uda1.uda1_cmd;
17633543Sbostic 	mp->mscp_unit = io->i_unit;
17732613Sbostic 	mp->mscp_seq.seq_lbn = io->i_bn;
17832613Sbostic 	mp->mscp_seq.seq_bytecount = io->i_cc;
17935050Skarels 	mp->mscp_seq.seq_buffer = UBAI_ADDR(ubinfo) | (UBAI_BDP(ubinfo) << 24);
180*49100Sbostic 	if (udcmd(func == F_READ ? M_OP_READ : M_OP_WRITE, io)) {
1815153Ssam 		printf("ra: I/O error\n");
1825153Ssam 		ubafree(io, ubinfo);
18335050Skarels 		return (-1);
1845153Ssam 	}
1855153Ssam 	ubafree(io, ubinfo);
18635050Skarels 	return (io->i_cc);
1875153Ssam }
18810024Ssam 
18930547Skarels #ifdef COMPAT_42
19035050Skarels u_long rc25_off[] = { 0, 15884, 0, -1, -1, -1, 25916, -1 };
19132613Sbostic u_long rx50_off[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
19232613Sbostic u_long rd52_off[] = { 0, 15884, 0, 0, 0, 0, 25650, 0 };
19332613Sbostic u_long rd53_off[] = { 0, 15884, 0, 0, 0, 33440, 49324, 15884 };
19430547Skarels u_long ra60_off[] = { 0, 15884, 0, 49324, 131404, 49324, 242606, 49324 };
19535050Skarels #define ra70_off ra60_off
19630547Skarels u_long ra80_off[] = { 0, 15884, 0, -1, 49324, 49324, 49910, 131404 };
19730547Skarels #ifndef	UCBRA
19830547Skarels #ifdef RA_COMPAT
19930547Skarels u_long ra81_off[] = { 0, 16422, 0, 49324, 131404, 412490, 375564, 83538 };
20030547Skarels #else
20130547Skarels u_long ra81_off[] = { 0, 16422, 0, 375564, 391986, 699720, 375564, 83538 };
20230547Skarels #endif
20330547Skarels #else
20430547Skarels u_long ra81_off[] = { 0, 15884, 0, 242606, 258490, 565690, 242606, 49324 };
20530547Skarels #endif
20635050Skarels u_long ra82_off[] = { 0, 15884, 0, 375345, 391590, 699390, 375345, 83790 };
20730547Skarels 
20835050Skarels struct mediamap {
20935050Skarels 	u_long	id;		/* media ID */
21035050Skarels 	u_long	*off;		/* offsets */
21135050Skarels } ra_map[] = {
21235050Skarels 	{ MSCP_MKDRIVE2('R', 'A', 60),		ra60_off },
21335050Skarels 	{ MSCP_MKDRIVE2('R', 'A', 70),		ra70_off },
21435050Skarels 	{ MSCP_MKDRIVE2('R', 'A', 80),		ra80_off },
21535050Skarels 	{ MSCP_MKDRIVE2('R', 'A', 81),		ra81_off },
21635050Skarels 	{ MSCP_MKDRIVE2('R', 'A', 82),		ra82_off },
21735050Skarels 	{ MSCP_MKDRIVE2('R', 'C', 25),		rc25_off },
21835050Skarels 	{ MSCP_MKDRIVE3('R', 'C', 'F', 25),	rc25_off },
21935050Skarels 	{ MSCP_MKDRIVE2('R', 'D', 52),		rd52_off },
22035050Skarels 	{ MSCP_MKDRIVE2('R', 'D', 53),		rd53_off },
22135050Skarels 	{ MSCP_MKDRIVE2('R', 'X', 50),		rx50_off },
22235050Skarels 	0
22332613Sbostic };
22432613Sbostic 
ramaptype(io,lp)22530547Skarels ramaptype(io, lp)
22630547Skarels 	register struct iob *io;
22730547Skarels 	register struct disklabel *lp;
22830547Skarels {
22930547Skarels 	register struct partition *pp;
23035050Skarels 	register u_long i;
23135050Skarels 	register struct mediamap *map;
23230547Skarels 
23335050Skarels 	i = MSCP_MEDIA_DRIVE(ramedia[io->i_adapt][io->i_ctlr][io->i_unit]);
23435050Skarels 	for (map = ra_map; map->id != 0; map++) {
23535050Skarels 		if (map->id == i) {
23635050Skarels 			lp->d_npartitions = 8;
23735050Skarels 			for (pp = lp->d_partitions, i = 0; i < 8; pp++, i++)
23835050Skarels 				pp->p_offset = map->off[i];
23935050Skarels 			return;
24035050Skarels 		}
24130547Skarels 	}
24235050Skarels 	printf("ra%d: media type 0x%x unsupported\n", io->i_unit, i);
24335050Skarels 	lp->d_npartitions = 0;
24430547Skarels }
24530547Skarels #endif
246