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