xref: /csrg-svn/sys/vax/stand/kdb.c (revision 33519)
1*33519Sbostic /*
2*33519Sbostic  * Copyright (c) 1988 Regents of the University of California.
3*33519Sbostic  * All rights reserved.
4*33519Sbostic  *
5*33519Sbostic  * Redistribution and use in source and binary forms are permitted
6*33519Sbostic  * provided that this notice is preserved and that due credit is given
7*33519Sbostic  * to the University of California at Berkeley. The name of the University
8*33519Sbostic  * may not be used to endorse or promote products derived from this
9*33519Sbostic  * software without specific prior written permission. This software
10*33519Sbostic  * is provided ``as is'' without express or implied warranty.
11*33519Sbostic  *
12*33519Sbostic  *	@(#)kdb.c	7.1 (Berkeley) 02/22/88
13*33519Sbostic  */
14*33519Sbostic 
15*33519Sbostic /*
16*33519Sbostic  * KDB50/RAxx disk device driver
17*33519Sbostic  */
18*33519Sbostic #include "../machine/pte.h"
19*33519Sbostic 
20*33519Sbostic #include "param.h"
21*33519Sbostic #include "inode.h"
22*33519Sbostic #include "fs.h"
23*33519Sbostic #include "disklabel.h"
24*33519Sbostic 
25*33519Sbostic #include "saio.h"
26*33519Sbostic #include "savax.h"
27*33519Sbostic 
28*33519Sbostic #define	NKRA		8	/* max unit number on ctlr */
29*33519Sbostic #define	SECTSIZ		512	/* sector size in bytes */
30*33519Sbostic 
31*33519Sbostic /*
32*33519Sbostic  * Parameters for the communications area
33*33519Sbostic  */
34*33519Sbostic #define	NRSP	1
35*33519Sbostic #define	NCMD	1
36*33519Sbostic 
37*33519Sbostic #include "../vax/bireg.h"
38*33519Sbostic #include "../vax/kdbreg.h"
39*33519Sbostic #include "../vax/mscp.h"
40*33519Sbostic 
41*33519Sbostic struct kdb {
42*33519Sbostic 	struct kdbca	kdb_ca;
43*33519Sbostic 	struct mscp	kdb_rsp;
44*33519Sbostic 	struct mscp	kdb_cmd;
45*33519Sbostic } kdb;
46*33519Sbostic 
47*33519Sbostic int	kdbinit[MAXNKDB];
48*33519Sbostic char	kratype[MAXNKDB * NKRA];
49*33519Sbostic struct	disklabel kralabel[MAXNUBA * NKRA];
50*33519Sbostic char	lbuf[SECTSIZ];
51*33519Sbostic 
52*33519Sbostic kraopen(io)
53*33519Sbostic 	register struct iob *io;
54*33519Sbostic {
55*33519Sbostic 	register struct mscp *mp;
56*33519Sbostic 	register struct kdb_regs *kr;
57*33519Sbostic 	register struct disklabel *lp;
58*33519Sbostic 	register int i, unit;
59*33519Sbostic 	daddr_t off;
60*33519Sbostic 
61*33519Sbostic 	i = io->i_unit >> 3;
62*33519Sbostic 	if (i >= nkdb) {
63*33519Sbostic 		printf("nonexistent device");
64*33519Sbostic 		return (ENXIO);
65*33519Sbostic 	}
66*33519Sbostic 	kr = (struct kdb_regs *)kdbaddr[i];
67*33519Sbostic 	if (kdbinit[i] == 0) {
68*33519Sbostic 		kr->kdb_bi.bi_csr |= BICSR_NRST;
69*33519Sbostic 		DELAY(10000);	/* ??? */
70*33519Sbostic 		/* clear any bus errors */
71*33519Sbostic 		kr->kdb_bi.bi_ber = ~(BIBER_MBZ|BIBER_NMR|BIBER_UPEN);
72*33519Sbostic 		while ((kr->kdb_sa & KDB_STEP1) == 0)
73*33519Sbostic 			;
74*33519Sbostic 		kr->kdb_bi.bi_bcicsr |= BCI_STOPEN | BCI_IDENTEN;
75*33519Sbostic 		kr->kdb_sw = KDB_ERR;
76*33519Sbostic 		while ((kr->kdb_sa & KDB_STEP2) == 0)
77*33519Sbostic 			;
78*33519Sbostic 		kr->kdb_sw = (int)&kdb.kdb_ca.ca_rspdsc[0];
79*33519Sbostic 		while ((kr->kdb_sa & KDB_STEP3) == 0)
80*33519Sbostic 			;
81*33519Sbostic 		kr->kdb_sw = (int)&kdb.kdb_ca.ca_rspdsc[0] >> 16;
82*33519Sbostic 		while ((kr->kdb_sa & KDB_STEP4) == 0)
83*33519Sbostic 			;
84*33519Sbostic 		kr->kdb_sw = KDB_GO;
85*33519Sbostic 		kdb.kdb_ca.ca_rspdsc[0] = (long)&kdb.kdb_rsp.mscp_cmdref;
86*33519Sbostic 		kdb.kdb_ca.ca_cmddsc[0] = (long)&kdb.kdb_cmd.mscp_cmdref;
87*33519Sbostic 		if (kdbcmd(kr, M_OP_SETCTLRC)) {
88*33519Sbostic 			printf("open error, SETCTLRC");
89*33519Sbostic 			return (EIO);
90*33519Sbostic 		}
91*33519Sbostic 		kdbinit[i] = 1;
92*33519Sbostic 	}
93*33519Sbostic 	unit = io->i_unit;
94*33519Sbostic 	lp = &kralabel[unit];
95*33519Sbostic 	if (kratype[unit] == 0) {
96*33519Sbostic 		struct iob tio;
97*33519Sbostic 
98*33519Sbostic 		kdb.kdb_cmd.mscp_unit = UNITTODRIVE(unit);
99*33519Sbostic 		if (kdbcmd(kr, M_OP_ONLINE)) {
100*33519Sbostic 			printf("open error, ONLINE");
101*33519Sbostic 			return (EIO);
102*33519Sbostic 		}
103*33519Sbostic 		kratype[unit] = kdb.kdb_rsp.mscp_onle.onle_drivetype;
104*33519Sbostic 		tio = *io;
105*33519Sbostic 		tio.i_bn = LABELSECTOR;
106*33519Sbostic 		tio.i_ma = lbuf;
107*33519Sbostic 		tio.i_cc = SECTSIZ;
108*33519Sbostic 		tio.i_flgs |= F_RDDATA;
109*33519Sbostic 		if (krastrategy(&tio, READ) != SECTSIZ) {
110*33519Sbostic 			printf("can't read disk label\n");
111*33519Sbostic 			return (EIO);
112*33519Sbostic 		}
113*33519Sbostic 		*lp = *(struct disklabel *)(lbuf + LABELOFFSET);
114*33519Sbostic 		if (lp->d_magic != DISKMAGIC || lp->d_magic2 != DISKMAGIC) {
115*33519Sbostic 			printf("kra%d: unlabeled\n", unit);
116*33519Sbostic #ifdef COMPAT_42
117*33519Sbostic 			kramaptype(io, lp);
118*33519Sbostic #else
119*33519Sbostic 			return (ENXIO);
120*33519Sbostic #endif
121*33519Sbostic 		}
122*33519Sbostic 	}
123*33519Sbostic 	if ((unsigned)io->i_boff >= lp->d_npartitions ||
124*33519Sbostic 	    (io->i_boff = lp->d_partitions[io->i_boff].p_offset) == -1) {
125*33519Sbostic 		printf("kra: bad partition");
126*33519Sbostic 		return (EUNIT);
127*33519Sbostic 	}
128*33519Sbostic 	return (0);
129*33519Sbostic }
130*33519Sbostic 
131*33519Sbostic kdbcmd(kr, op)
132*33519Sbostic 	struct kdb_regs *kr;
133*33519Sbostic 	int op;
134*33519Sbostic {
135*33519Sbostic 	register struct kdb *k = &kdb;
136*33519Sbostic 	register struct mscp *mp;
137*33519Sbostic 	int i;
138*33519Sbostic 
139*33519Sbostic 	k->kdb_cmd.mscp_opcode = op;
140*33519Sbostic 	k->kdb_rsp.mscp_msglen = MSCP_MSGLEN;
141*33519Sbostic 	k->kdb_cmd.mscp_msglen = MSCP_MSGLEN;
142*33519Sbostic 	k->kdb_ca.ca_rspdsc[0] |= MSCP_OWN | MSCP_INT;
143*33519Sbostic 	k->kdb_ca.ca_cmddsc[0] |= MSCP_OWN | MSCP_INT;
144*33519Sbostic 	i = kr->kdb_ip;
145*33519Sbostic 	mp = &k->kdb_rsp;
146*33519Sbostic 	for (;;) {
147*33519Sbostic 		if (k->kdb_ca.ca_cmdint)
148*33519Sbostic 			k->kdb_ca.ca_cmdint = 0;
149*33519Sbostic 		if (k->kdb_ca.ca_rspint == 0)
150*33519Sbostic 			continue;
151*33519Sbostic 		k->kdb_ca.ca_rspint = 0;
152*33519Sbostic 		if (mp->mscp_opcode == (op | M_OP_END))
153*33519Sbostic 			break;
154*33519Sbostic 		printf("unexpected rsp type %x op %x ignored\n",
155*33519Sbostic 			MSCP_MSGTYPE(mp->mscp_msgtc), mp->mscp_opcode);
156*33519Sbostic 	}
157*33519Sbostic 	if ((mp->mscp_status & M_ST_MASK) != M_ST_SUCCESS)
158*33519Sbostic 		return (-1);
159*33519Sbostic 	return (0);
160*33519Sbostic }
161*33519Sbostic 
162*33519Sbostic krastrategy(io, func)
163*33519Sbostic 	register struct iob *io;
164*33519Sbostic {
165*33519Sbostic 	register struct mscp *mp;
166*33519Sbostic 
167*33519Sbostic 	mp = &kdb.kdb_cmd;
168*33519Sbostic 	mp->mscp_unit = io->i_unit & 7;
169*33519Sbostic 	mp->mscp_seq.seq_lbn = io->i_bn;
170*33519Sbostic 	mp->mscp_seq.seq_bytecount = io->i_cc;
171*33519Sbostic 	mp->mscp_seq.seq_buffer = (long)io->i_ma | KDB_PHYS;
172*33519Sbostic 	if (kdbcmd((struct kdb_regs *)kdbaddr[io->i_unit >> 3],
173*33519Sbostic 		    func == READ ? M_OP_READ : M_OP_WRITE)) {
174*33519Sbostic 		printf("kra: I/O error\n");
175*33519Sbostic 		return (-1);
176*33519Sbostic 	}
177*33519Sbostic 	return (io->i_cc);
178*33519Sbostic }
179*33519Sbostic 
180*33519Sbostic /*ARGSUSED*/
181*33519Sbostic kraioctl(io, cmd, arg)
182*33519Sbostic 	struct iob *io;
183*33519Sbostic 	int cmd;
184*33519Sbostic 	caddr_t arg;
185*33519Sbostic {
186*33519Sbostic 
187*33519Sbostic 	return (ECMD);
188*33519Sbostic }
189*33519Sbostic 
190*33519Sbostic #ifdef COMPAT_42
191*33519Sbostic u_long kra25_off[] = { 0, 15884, 0, -1, -1, -1, 25916, -1 };
192*33519Sbostic u_long kra60_off[] = { 0, 15884, 0, 49324, 131404, 49324, 242606, 49324 };
193*33519Sbostic u_long kra80_off[] = { 0, 15884, 0, -1, 49324, 49324, 49910, 131404 };
194*33519Sbostic u_long kra81_off[] = { 0, 15884, 0, 131404, 49324, 498790, 563050, 131404 };
195*33519Sbostic u_long *kra_off[] = {
196*33519Sbostic 	0,
197*33519Sbostic 	kra80_off,		/* 1 = ra80 */
198*33519Sbostic 	kra25_off,		/* 2 = rc25-r */
199*33519Sbostic 	kra25_off,		/* 3 = rc25-r */
200*33519Sbostic 	kra60_off,		/* 4 = ra60 */
201*33519Sbostic 	kra81_off,		/* 5 = ra81 */
202*33519Sbostic };
203*33519Sbostic #define	NOFFS (sizeof(kra_off) / sizeof(kra_off[0]))
204*33519Sbostic 
205*33519Sbostic kramaptype(io, lp)
206*33519Sbostic 	register struct iob *io;
207*33519Sbostic 	register struct disklabel *lp;
208*33519Sbostic {
209*33519Sbostic 	register struct partition *pp;
210*33519Sbostic 	register u_int i;
211*33519Sbostic 	register u_long *off;
212*33519Sbostic 
213*33519Sbostic 	if ((i = kratype[io->i_unit]) >= NOFFS || (off = kra_off[i]) == 0) {
214*33519Sbostic 		printf("kra%d: type %d unsupported\n", io->i_unit, i);
215*33519Sbostic 		lp->d_npartitions = 0;
216*33519Sbostic 		return;
217*33519Sbostic 	}
218*33519Sbostic 	lp->d_npartitions = 8;
219*33519Sbostic 	for (pp = lp->d_partitions, i = 0; i < 8; pp++, i++)
220*33519Sbostic 		pp->p_offset = *off++;
221*33519Sbostic }
222*33519Sbostic #endif
223