xref: /csrg-svn/sys/vax/stand/kdb.c (revision 40756)
1 /*
2  * Copyright (c) 1988 Regents of the University of California.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms are permitted
6  * provided that the above copyright notice and this paragraph are
7  * duplicated in all such forms and that any documentation,
8  * advertising materials, and other materials related to such
9  * distribution and use acknowledge that the software was developed
10  * by the University of California, Berkeley.  The name of the
11  * University may not be used to endorse or promote products derived
12  * from this software without specific prior written permission.
13  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16  *
17  *	@(#)kdb.c	7.6 (Berkeley) 04/04/90
18  */
19 
20 /*
21  * KDB50/RAxx disk device driver
22  */
23 #include "machine/pte.h"
24 
25 #include "param.h"
26 #include "disklabel.h"
27 
28 #include "saio.h"
29 #include "savax.h"
30 
31 /*
32  * N.B.: on KDB50, controller == adapter
33  * here we just use the controller number
34  */
35 
36 #define	NKRA		8	/* max drive number */
37 #define	SECTSIZ		512	/* sector size in bytes */
38 
39 /*
40  * Parameters for the communications area:
41  * command and response rings both one entry.
42  */
43 #define	NRSP	1
44 #define	NCMD	1
45 
46 #include "../vaxbi/bireg.h"
47 #include "../vaxbi/kdbreg.h"
48 #include "../vax/mscp.h"
49 
50 struct kdb {
51 	struct kdbca	kdb_ca;
52 	struct mscp	kdb_rsp;
53 	struct mscp	kdb_cmd;
54 } kdb;
55 
56 int	kdbinit[MAXNKDB];
57 struct	disklabel kralabel[MAXNKDB][NKRA];
58 u_long	kramedia[MAXNKDB][NKRA];
59 char	lbuf[SECTSIZ];
60 
61 kraopen(io)
62 	register struct iob *io;
63 {
64 	register struct kdb_regs *kr;
65 	register struct disklabel *lp;
66 	register int ctlr, unit;
67 	struct iob tio;
68 
69 	if ((u_int)(ctlr = io->i_ctlr) >= nkdb)
70 		return (EADAPT);
71 	if ((u_int)(unit = io->i_unit) >= NKRA)
72 		return (EUNIT);
73 	kr = (struct kdb_regs *)kdbaddr[ctlr];
74 	if (kdbinit[ctlr] == 0) {
75 		kr->kdb_bi.bi_csr |= BICSR_NRST;
76 		DELAY(10000);	/* ??? */
77 		/* clear any bus errors */
78 		kr->kdb_bi.bi_ber = ~(BIBER_MBZ|BIBER_NMR|BIBER_UPEN);
79 		while ((kr->kdb_sa & KDB_STEP1) == 0)
80 			/* void */;
81 		kr->kdb_bi.bi_bcicsr |= BCI_STOPEN | BCI_IDENTEN;
82 		kr->kdb_sw = KDB_ERR;
83 		while ((kr->kdb_sa & KDB_STEP2) == 0)
84 			/* void */;
85 		kr->kdb_sw = (int)&kdb.kdb_ca.ca_rspdsc[0];
86 		while ((kr->kdb_sa & KDB_STEP3) == 0)
87 			/* void */;
88 		kr->kdb_sw = (int)&kdb.kdb_ca.ca_rspdsc[0] >> 16;
89 		while ((kr->kdb_sa & KDB_STEP4) == 0)
90 			/* void */;
91 		kr->kdb_sw = KDB_GO;
92 		kdb.kdb_ca.ca_rspdsc[0] = (long)&kdb.kdb_rsp.mscp_cmdref;
93 		kdb.kdb_ca.ca_cmddsc[0] = (long)&kdb.kdb_cmd.mscp_cmdref;
94 		if (kdbcmd(M_OP_SETCTLRC, io)) {
95 			printf("kra: open error, SETCTLRC\n");
96 			return (ENXIO);
97 		}
98 		kdbinit[ctlr] = 1;
99 	}
100 	lp = &kralabel[ctlr][unit];
101 	if (kramedia[ctlr][unit] == 0) {
102 		kdb.kdb_cmd.mscp_unit = unit;
103 		if (kdbcmd(M_OP_ONLINE, io)) {
104 			printf("kra: open error, ONLINE\n");
105 			return (ENXIO);
106 		}
107 		kramedia[ctlr][unit] = kdb.kdb_rsp.mscp_onle.onle_mediaid;
108 		tio = *io;
109 		tio.i_bn = LABELSECTOR;
110 		tio.i_ma = lbuf;
111 		tio.i_cc = SECTSIZ;
112 		tio.i_flgs |= F_RDDATA;
113 		if (krastrategy(&tio, READ) != SECTSIZ)
114 			return (ERDLAB);
115 		*lp = *(struct disklabel *)(lbuf + LABELOFFSET);
116 		if (lp->d_magic != DISKMAGIC || lp->d_magic2 != DISKMAGIC) {
117 #ifdef COMPAT_42
118 			printf("kra%d: unlabeled\n", unit);
119 			kramaptype(io, lp);
120 #else
121 			return (EUNLAB);
122 #endif
123 		}
124 	}
125 	if ((u_int)io->i_part >= lp->d_npartitions ||
126 	    (io->i_boff = lp->d_partitions[io->i_part].p_offset) == -1)
127 		return (EPART);
128 	return (0);
129 }
130 
131 kdbcmd(op, io)
132 	int op;
133 	struct iob *io;
134 {
135 	register struct kdb *k = &kdb;
136 	register struct mscp *mp;
137 	register int i;
138 
139 	k->kdb_cmd.mscp_opcode = op;
140 	k->kdb_rsp.mscp_msglen = MSCP_MSGLEN;
141 	k->kdb_cmd.mscp_msglen = MSCP_MSGLEN;
142 	k->kdb_ca.ca_rspdsc[0] |= MSCP_OWN | MSCP_INT;
143 	k->kdb_ca.ca_cmddsc[0] |= MSCP_OWN | MSCP_INT;
144 	i = ((struct kdb_regs *)kdbaddr[io->i_ctlr])->kdb_ip;
145 #ifdef lint
146 	i = i;
147 #endif
148 	mp = &k->kdb_rsp;
149 	for (;;) {
150 		if (k->kdb_ca.ca_cmdint)
151 			k->kdb_ca.ca_cmdint = 0;
152 		if (k->kdb_ca.ca_rspint == 0)
153 			continue;
154 		k->kdb_ca.ca_rspint = 0;
155 		if (mp->mscp_opcode == (op | M_OP_END))
156 			break;
157 		printf("unexpected rsp type %x op %x ignored\n",
158 			MSCP_MSGTYPE(mp->mscp_msgtc), mp->mscp_opcode);
159 		k->kdb_ca.ca_rspdsc[0] |= MSCP_OWN | MSCP_INT;
160 	}
161 	if ((mp->mscp_status & M_ST_MASK) != M_ST_SUCCESS)
162 		return (-1);
163 	return (0);
164 }
165 
166 krastrategy(io, func)
167 	register struct iob *io;
168 	int func;
169 {
170 	register struct mscp *mp;
171 
172 	mp = &kdb.kdb_cmd;
173 	mp->mscp_unit = io->i_unit;
174 	mp->mscp_seq.seq_lbn = io->i_bn;
175 	mp->mscp_seq.seq_bytecount = io->i_cc;
176 	mp->mscp_seq.seq_buffer = (long)io->i_ma | KDB_PHYS;
177 	if (kdbcmd(func == READ ? M_OP_READ : M_OP_WRITE, io)) {
178 		printf("kra: I/O error\n");
179 		return (-1);
180 	}
181 	return (io->i_cc);
182 }
183 
184 #ifdef COMPAT_42
185 u_long kra60_off[] = { 0, 15884, 0, 49324, 131404, 49324, 242606, 49324 };
186 #define kra70_off kra60_off
187 u_long kra80_off[] = { 0, 15884, 0, -1, 49324, 49324, 49910, 131404 };
188 u_long kra81_off[] = { 0, 15884, 0, 131404, 49324, 498790, 563050, 131404 };
189 u_long kra82_off[] = { 0, 15884, 0, 375345, 391590, 699390, 375345, 83790 };
190 
191 struct mediamap {
192 	u_long	id;		/* media ID */
193 	u_long	*off;		/* offsets */
194 } kra_map[] = {
195 	{ MSCP_MKDRIVE2('R', 'A', 60),		kra60_off },
196 	{ MSCP_MKDRIVE2('R', 'A', 70),		kra70_off },
197 	{ MSCP_MKDRIVE2('R', 'A', 80),		kra80_off },
198 	{ MSCP_MKDRIVE2('R', 'A', 81),		kra81_off },
199 	{ MSCP_MKDRIVE2('R', 'A', 82),		kra82_off },
200 	0
201 };
202 
203 kramaptype(io, lp)
204 	register struct iob *io;
205 	register struct disklabel *lp;
206 {
207 	register struct partition *pp;
208 	register u_long i;
209 	register struct mediamap *map;
210 
211 	i = MSCP_MEDIA_DRIVE(kramedia[io->i_ctlr][io->i_unit]);
212 	for (map = kra_map; map->id != 0; map++) {
213 		if (map->id == i) {
214 			lp->d_npartitions = 8;
215 			for (pp = lp->d_partitions, i = 0; i < 8; pp++, i++)
216 				pp->p_offset = map->off[i];
217 			return;
218 		}
219 	}
220 	printf("kra%d: media type 0x%x unsupported\n", io->i_unit, i);
221 	lp->d_npartitions = 0;
222 }
223 #endif
224