xref: /original-bsd/sys/vax/stand/kdb.c (revision f25de740)
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 this notice is preserved and that due credit is given
7  * to the University of California at Berkeley. The name of the University
8  * may not be used to endorse or promote products derived from this
9  * software without specific prior written permission. This software
10  * is provided ``as is'' without express or implied warranty.
11  *
12  *	@(#)kdb.c	7.2 (Berkeley) 05/24/88
13  */
14 
15 /*
16  * KDB50/RAxx disk device driver
17  */
18 #include "../machine/pte.h"
19 
20 #include "param.h"
21 #include "inode.h"
22 #include "fs.h"
23 #include "disklabel.h"
24 
25 #include "saio.h"
26 #include "savax.h"
27 
28 #define	NKRA		8	/* max unit number on ctlr */
29 #define	SECTSIZ		512	/* sector size in bytes */
30 
31 /*
32  * Parameters for the communications area
33  */
34 #define	NRSP	1
35 #define	NCMD	1
36 
37 #include "../vaxbi/bireg.h"
38 #include "../vaxbi/kdbreg.h"
39 #include "../vax/mscp.h"
40 
41 struct kdb {
42 	struct kdbca	kdb_ca;
43 	struct mscp	kdb_rsp;
44 	struct mscp	kdb_cmd;
45 } kdb;
46 
47 int	kdbinit[MAXNKDB];
48 char	kratype[MAXNKDB * NKRA];
49 struct	disklabel kralabel[MAXNUBA * NKRA];
50 char	lbuf[SECTSIZ];
51 
52 kraopen(io)
53 	register struct iob *io;
54 {
55 	register struct mscp *mp;
56 	register struct kdb_regs *kr;
57 	register struct disklabel *lp;
58 	register int i, unit;
59 	daddr_t off;
60 
61 	if ((i = io->i_unit) >= nkdb)
62 		return (EUNIT);
63 	kr = (struct kdb_regs *)kdbaddr[i];
64 	if (kdbinit[i] == 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 			;
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 			;
75 		kr->kdb_sw = (int)&kdb.kdb_ca.ca_rspdsc[0];
76 		while ((kr->kdb_sa & KDB_STEP3) == 0)
77 			;
78 		kr->kdb_sw = (int)&kdb.kdb_ca.ca_rspdsc[0] >> 16;
79 		while ((kr->kdb_sa & KDB_STEP4) == 0)
80 			;
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(kr, M_OP_SETCTLRC)) {
85 			printf("open error, SETCTLRC");
86 			return (EIO);
87 		}
88 		kdbinit[i] = 1;
89 	}
90 	unit = io->i_unit;
91 	lp = &kralabel[unit];
92 	if (kratype[unit] == 0) {
93 		struct iob tio;
94 
95 		kdb.kdb_cmd.mscp_unit = UNITTODRIVE(unit);
96 		if (kdbcmd(kr, M_OP_ONLINE)) {
97 			printf("open error, ONLINE");
98 			return (EIO);
99 		}
100 		kratype[unit] = kdb.kdb_rsp.mscp_onle.onle_drivetype;
101 		tio = *io;
102 		tio.i_bn = LABELSECTOR;
103 		tio.i_ma = lbuf;
104 		tio.i_cc = SECTSIZ;
105 		tio.i_flgs |= F_RDDATA;
106 		if (krastrategy(&tio, READ) != SECTSIZ)
107 			return (ERDLAB);
108 		*lp = *(struct disklabel *)(lbuf + LABELOFFSET);
109 		if (lp->d_magic != DISKMAGIC || lp->d_magic2 != DISKMAGIC)
110 #ifdef COMPAT_42
111 		{
112 			printf("kra%d: unlabeled\n", unit);
113 			kramaptype(io, lp);
114 		}
115 #else
116 			return (EUNLAB);
117 #endif
118 	}
119 	if ((unsigned)io->i_part >= lp->d_npartitions ||
120 	    (io->i_boff = lp->d_partitions[io->i_part].p_offset) == -1)
121 		return (EPART);
122 	return (0);
123 }
124 
125 kdbcmd(kr, op)
126 	struct kdb_regs *kr;
127 	int op;
128 {
129 	register struct kdb *k = &kdb;
130 	register struct mscp *mp;
131 	int i;
132 
133 	k->kdb_cmd.mscp_opcode = op;
134 	k->kdb_rsp.mscp_msglen = MSCP_MSGLEN;
135 	k->kdb_cmd.mscp_msglen = MSCP_MSGLEN;
136 	k->kdb_ca.ca_rspdsc[0] |= MSCP_OWN | MSCP_INT;
137 	k->kdb_ca.ca_cmddsc[0] |= MSCP_OWN | MSCP_INT;
138 	i = kr->kdb_ip;
139 	mp = &k->kdb_rsp;
140 	for (;;) {
141 		if (k->kdb_ca.ca_cmdint)
142 			k->kdb_ca.ca_cmdint = 0;
143 		if (k->kdb_ca.ca_rspint == 0)
144 			continue;
145 		k->kdb_ca.ca_rspint = 0;
146 		if (mp->mscp_opcode == (op | M_OP_END))
147 			break;
148 		printf("unexpected rsp type %x op %x ignored\n",
149 			MSCP_MSGTYPE(mp->mscp_msgtc), mp->mscp_opcode);
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 {
159 	register struct mscp *mp;
160 
161 	mp = &kdb.kdb_cmd;
162 	mp->mscp_unit = io->i_unit & 7;
163 	mp->mscp_seq.seq_lbn = io->i_bn;
164 	mp->mscp_seq.seq_bytecount = io->i_cc;
165 	mp->mscp_seq.seq_buffer = (long)io->i_ma | KDB_PHYS;
166 	if (kdbcmd((struct kdb_regs *)kdbaddr[io->i_unit >> 3],
167 		    func == READ ? M_OP_READ : M_OP_WRITE)) {
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 kra25_off[] = { 0, 15884, 0, -1, -1, -1, 25916, -1 };
176 u_long kra60_off[] = { 0, 15884, 0, 49324, 131404, 49324, 242606, 49324 };
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 *kra_off[] = {
180 	0,
181 	kra80_off,		/* 1 = ra80 */
182 	kra25_off,		/* 2 = rc25-r */
183 	kra25_off,		/* 3 = rc25-r */
184 	kra60_off,		/* 4 = ra60 */
185 	kra81_off,		/* 5 = ra81 */
186 };
187 #define	NOFFS (sizeof(kra_off) / sizeof(kra_off[0]))
188 
189 kramaptype(io, lp)
190 	register struct iob *io;
191 	register struct disklabel *lp;
192 {
193 	register struct partition *pp;
194 	register u_int i;
195 	register u_long *off;
196 
197 	if ((i = kratype[io->i_unit]) >= NOFFS || (off = kra_off[i]) == 0) {
198 		printf("kra%d: type %d unsupported\n", io->i_unit, i);
199 		lp->d_npartitions = 0;
200 		return;
201 	}
202 	lp->d_npartitions = 8;
203 	for (pp = lp->d_partitions, i = 0; i < 8; pp++, i++)
204 		pp->p_offset = *off++;
205 }
206 #endif
207