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