xref: /csrg-svn/sys/vax/bi/kdb.c (revision 34293)
1*34293Skarels /*
2*34293Skarels  *	@(#)kdb.c	7.1 (Berkeley) 05/14/88
3*34293Skarels  *
4*34293Skarels  * KDB50/MSCP device driver
5*34293Skarels  */
6*34293Skarels 
7*34293Skarels /*
8*34293Skarels  * TODO
9*34293Skarels  *	rethink BI software interface
10*34293Skarels  *	performance: would testing contiguity in kdbmap be worthwhile?
11*34293Skarels  *	write bad block forwarding code
12*34293Skarels  */
13*34293Skarels 
14*34293Skarels #include "kra.h"		/* XXX */
15*34293Skarels 
16*34293Skarels #define	DRIVENAMES	"kra"	/* XXX */
17*34293Skarels 
18*34293Skarels #if NKDB > 0
19*34293Skarels 
20*34293Skarels /*
21*34293Skarels  * CONFIGURATION OPTIONS.  The next three defines are tunable -- tune away!
22*34293Skarels  *
23*34293Skarels  * NRSPL2 and NCMDL2 control the number of response and command
24*34293Skarels  * packets respectively.  They may be any value from 0 to 7, though
25*34293Skarels  * setting them higher than 5 is unlikely to be of any value.
26*34293Skarels  * If you get warnings about your command ring being too small,
27*34293Skarels  * try increasing the values by one.
28*34293Skarels  *
29*34293Skarels  * MAXUNIT controls the maximum slave number (and hence number of drives
30*34293Skarels  * per controller) we are prepared to handle.
31*34293Skarels  */
32*34293Skarels #define	NRSPL2	5		/* log2 number of response packets */
33*34293Skarels #define NCMDL2	5		/* log2 number of command packets */
34*34293Skarels #define	MAXUNIT	8		/* maximum allowed unit number */
35*34293Skarels 
36*34293Skarels #include "../machine/pte.h"
37*34293Skarels 
38*34293Skarels #include "param.h"
39*34293Skarels #include "systm.h"
40*34293Skarels #include "malloc.h"
41*34293Skarels #include "map.h"
42*34293Skarels #include "buf.h"
43*34293Skarels #include "conf.h"
44*34293Skarels #include "dir.h"
45*34293Skarels #include "user.h"
46*34293Skarels #include "proc.h"
47*34293Skarels #include "vm.h"
48*34293Skarels #include "dkstat.h"
49*34293Skarels #include "cmap.h"
50*34293Skarels #include "syslog.h"
51*34293Skarels #include "kernel.h"
52*34293Skarels 
53*34293Skarels #define	NRSP	(1 << NRSPL2)
54*34293Skarels #define	NCMD	(1 << NCMDL2)
55*34293Skarels 
56*34293Skarels #include "../vax/cpu.h"
57*34293Skarels #include "../vax/mscp.h"
58*34293Skarels #include "../vax/mscpvar.h"
59*34293Skarels #include "../vax/mtpr.h"
60*34293Skarels 
61*34293Skarels #include "bireg.h"
62*34293Skarels #include "kdbreg.h"
63*34293Skarels #include "../vaxuba/ubavar.h"
64*34293Skarels 
65*34293Skarels /*
66*34293Skarels  * Conversions from kernel virtual to physical and page table addresses.
67*34293Skarels  * PHYS works only for kernel text and primary (compile time) data addresses.
68*34293Skarels  */
69*34293Skarels #define	PHYS(cast, addr) \
70*34293Skarels 	((cast) ((int)(addr) & 0x7fffffff))
71*34293Skarels 
72*34293Skarels /*
73*34293Skarels  * KDB variables, per controller.
74*34293Skarels  */
75*34293Skarels struct kdbinfo {
76*34293Skarels 	/* software info, per KDB */
77*34293Skarels 	struct	kdb_regs *ki_kdb;	/* KDB registers */
78*34293Skarels 	struct	kdb_regs *ki_physkdb;	/* phys address of KDB registers */
79*34293Skarels 	short	ki_state;		/* KDB50 state; see below */
80*34293Skarels 	short	ki_flags;		/* flags; see below */
81*34293Skarels 	int	ki_micro;		/* microcode revision */
82*34293Skarels 	short	ki_vec;			/* scb vector offset */
83*34293Skarels 	short	ki_wticks;		/* watchdog timer ticks */
84*34293Skarels 
85*34293Skarels 	/*
86*34293Skarels 	 * KDB PTEs must be contiguous.  Some I/O is done on addresses
87*34293Skarels 	 * for which this is true (PTEs in Sysmap and Usrptmap), but
88*34293Skarels 	 * other transfers may have PTEs that are scattered in physical
89*34293Skarels 	 * space.  Ki_map maps a physically contiguous PTE space used
90*34293Skarels 	 * for these tranfsers.
91*34293Skarels 	 */
92*34293Skarels #define KI_MAPSIZ	(NCMD + 2)
93*34293Skarels 	struct	map *ki_map;		/* resource map */
94*34293Skarels #define KI_PTES		256
95*34293Skarels 	struct	pte *ki_pte;		/* contiguous PTE space */
96*34293Skarels 	long	ki_ptephys;		/* phys address of &ki_pte[0] */
97*34293Skarels 
98*34293Skarels 	struct	mscp_info ki_mi;	/* MSCP info (per mscpvar.h) */
99*34293Skarels 	struct	buf ki_tab;		/* controller queue */
100*34293Skarels 
101*34293Skarels 	/* stuff read and written by hardware */
102*34293Skarels 	struct	kdbca ki_ca;		/* communications area */
103*34293Skarels 	struct	mscp ki_rsp[NRSP];	/* response packets */
104*34293Skarels 	struct	mscp ki_cmd[NCMD];	/* command packets */
105*34293Skarels } kdbinfo[NKDB];
106*34293Skarels 
107*34293Skarels #define	ki_ctlr	ki_mi.mi_ctlr
108*34293Skarels 
109*34293Skarels /*
110*34293Skarels  * Controller states
111*34293Skarels  */
112*34293Skarels #define	ST_IDLE		0	/* uninitialised */
113*34293Skarels #define	ST_STEP1	1	/* in `STEP 1' */
114*34293Skarels #define	ST_STEP2	2	/* in `STEP 2' */
115*34293Skarels #define	ST_STEP3	3	/* in `STEP 3' */
116*34293Skarels #define	ST_SETCHAR	4	/* in `Set Controller Characteristics' */
117*34293Skarels #define	ST_RUN		5	/* up and running */
118*34293Skarels 
119*34293Skarels /*
120*34293Skarels  * Flags
121*34293Skarels  */
122*34293Skarels #define	KDB_ALIVE	0x01	/* this KDB50 exists */
123*34293Skarels #define	KDB_GRIPED	0x04	/* griped about cmd ring too small */
124*34293Skarels #define	KDB_INSLAVE	0x08	/* inside kdbslave() */
125*34293Skarels #define	KDB_DOWAKE	0x10	/* wakeup when ctlr init done */
126*34293Skarels 
127*34293Skarels struct kdbstats kdbstats;	/* statistics */
128*34293Skarels 
129*34293Skarels /*
130*34293Skarels  * Device to unit number and partition:
131*34293Skarels  */
132*34293Skarels #define	UNITSHIFT	3
133*34293Skarels #define	UNITMASK	7
134*34293Skarels #define	kdbunit(dev)	(minor(dev) >> UNITSHIFT)
135*34293Skarels #define	kdbpart(dev)	(minor(dev) & UNITMASK)
136*34293Skarels 
137*34293Skarels /* THIS SHOULD BE READ OFF THE PACK, PER DRIVE */
138*34293Skarels /* THESE SHOULD BE SHARED WITH uda.c (but not yet) */
139*34293Skarels struct size {
140*34293Skarels 	daddr_t nblocks;
141*34293Skarels 	daddr_t blkoff;
142*34293Skarels } kra81_sizes[8] = {
143*34293Skarels #ifdef MARYLAND
144*34293Skarels 	67832,	0,		/* A=cyl    0 thru   94 + 2 sectors */
145*34293Skarels 	67828,	67832,		/* B=cyl   95 thru  189 - 2 sectors */
146*34293Skarels 	-1,	0,		/* C=cyl    0 thru 1247 */
147*34293Skarels 	-1,	135660,		/* D=cyl  190 thru 1247 */
148*34293Skarels 	449466,	49324,		/* E xxx */
149*34293Skarels 	64260,	498790,		/* F xxx */
150*34293Skarels 	328022,	563050,		/* G xxx */
151*34293Skarels 	0,	0,
152*34293Skarels #else
153*34293Skarels 	15884,	0,		/* a */
154*34293Skarels 	33440,	15884,		/* b */
155*34293Skarels 	-1,	0,		/* c */
156*34293Skarels 	-1,	49324,		/* d */
157*34293Skarels 	449466,	49324,		/* e */
158*34293Skarels 	64260,	498790,		/* f */
159*34293Skarels 	328022,	563050,		/* g */
160*34293Skarels 	0,	0,
161*34293Skarels #endif
162*34293Skarels }, kra80_sizes[8] = {
163*34293Skarels 	15884,	0,		/* A=blk 0 thru 15883 */
164*34293Skarels 	33440,	15884,		/* B=blk 15884 thru 49323 */
165*34293Skarels 	-1,	0,		/* C=blk 0 thru end */
166*34293Skarels 	0,	0,
167*34293Skarels 	0,	0,
168*34293Skarels 	0,	0,
169*34293Skarels 	82080,	49324,		/* G=blk 49324 thru 131403 */
170*34293Skarels 	-1,	131404,		/* H=blk 131404 thru end */
171*34293Skarels }, kra60_sizes[8] = {
172*34293Skarels 	15884,	0,		/* A=blk 0 thru 15883 */
173*34293Skarels 	33440,	15884,		/* B=blk 15884 thru 49323 */
174*34293Skarels 	-1,	0,		/* C=blk 0 thru end */
175*34293Skarels 	-1,	49324,		/* D=blk 49324 thru end */
176*34293Skarels 	0,	0,
177*34293Skarels 	0,	0,
178*34293Skarels 	82080,	49324,		/* G=blk 49324 thru 131403 */
179*34293Skarels 	-1,	131404,		/* H=blk 131404 thru end */
180*34293Skarels };
181*34293Skarels /* END OF STUFF WHICH SHOULD BE READ IN PER DISK */
182*34293Skarels 
183*34293Skarels /*
184*34293Skarels  * Drive type index decoding table.  `ut_name' is null iff the
185*34293Skarels  * type is not known.
186*34293Skarels  */
187*34293Skarels struct	kdbtypes {
188*34293Skarels 	char	*ut_name;	/* drive type name */
189*34293Skarels 	struct	size *ut_sizes;	/* partition tables */
190*34293Skarels } kdbtypes[] = {
191*34293Skarels 	NULL,		NULL,
192*34293Skarels 	"ra80",		kra80_sizes,	/* 1 = ra80 */
193*34293Skarels 	NULL,		NULL,
194*34293Skarels 	NULL,		NULL,
195*34293Skarels 	"ra60",		kra60_sizes,	/* 4 = ra60 */
196*34293Skarels 	"ra81",		kra81_sizes,	/* 5 = ra81 */
197*34293Skarels };
198*34293Skarels 
199*34293Skarels #define NTYPES 6
200*34293Skarels 
201*34293Skarels /*
202*34293Skarels  * Definition of the driver for autoconf and generic MSCP code.
203*34293Skarels  * SOME OF THIS IS BOGUS (must fix config)
204*34293Skarels  */
205*34293Skarels 
206*34293Skarels #ifdef notdef		/* not when driver is for kra disks */
207*34293Skarels /*
208*34293Skarels  * Some of these variables (per-drive stuff) are shared
209*34293Skarels  * with the UDA50 code (why not, they are the same drives).
210*34293Skarels  * N.B.: kdbdinfo must not be shared.
211*34293Skarels  */
212*34293Skarels #define	kdbutab		udautab		/* shared */
213*34293Skarels #define	kdbslavereply	udaslavereply	/* shared */
214*34293Skarels #endif
215*34293Skarels 
216*34293Skarels int	kdbprobe();		/* XXX */
217*34293Skarels int	kdbslave(), kdbattach();
218*34293Skarels 
219*34293Skarels int	kdbdgram(), kdbctlrdone(), kdbunconf(), kdbiodone();
220*34293Skarels int	kdbonline(), kdbgotstatus(), kdbioerror();
221*34293Skarels 
222*34293Skarels struct	uba_device *kdbdinfo[NKRA];	/* uba_device indeed! */
223*34293Skarels struct	buf kdbutab[NKRA];	/* per drive transfer queue */
224*34293Skarels 
225*34293Skarels u_short kdbstd[] = { 0 };	/* XXX */
226*34293Skarels struct uba_driver kdbdriver =	/* XXX */
227*34293Skarels  { kdbprobe, kdbslave, kdbattach, 0, kdbstd, DRIVENAMES, kdbdinfo, "kdb" };
228*34293Skarels 
229*34293Skarels struct	mscp_driver kdbmscpdriver =
230*34293Skarels  { MAXUNIT, NKRA, UNITSHIFT, kdbutab, kdbdinfo,
231*34293Skarels    kdbdgram, kdbctlrdone, kdbunconf, kdbiodone,
232*34293Skarels    kdbonline, kdbgotstatus, NULL, kdbioerror, NULL,
233*34293Skarels    "kdb", DRIVENAMES };
234*34293Skarels 
235*34293Skarels /*
236*34293Skarels  * Miscellaneous private variables.
237*34293Skarels  */
238*34293Skarels char	kdbsr_bits[] = KDBSR_BITS;
239*34293Skarels 
240*34293Skarels struct	uba_device *kdbip[NKDB][MAXUNIT];
241*34293Skarels 				/* inverting pointers: ctlr & unit => `Unibus'
242*34293Skarels 				   device pointer */
243*34293Skarels 
244*34293Skarels daddr_t	ra_dsize[NKRA];		/* drive sizes, from on line end packets */
245*34293Skarels 
246*34293Skarels struct	mscp kdbslavereply;	/* get unit status response packet, set
247*34293Skarels 				   for kdbslave by kdbunconf, via kdbintr */
248*34293Skarels 
249*34293Skarels int	kdbwstart, kdbwatch();	/* watchdog timer */
250*34293Skarels int	wakeup();
251*34293Skarels 
252*34293Skarels /*
253*34293Skarels  * If kdbprobe is called, return 0 to keep Unibus code from attempting
254*34293Skarels  * to use this device.	XXX rethink
255*34293Skarels  */
256*34293Skarels /* ARGSUSED */
257*34293Skarels kdbprobe(reg, ctlr)
258*34293Skarels 	caddr_t reg;
259*34293Skarels 	int ctlr;
260*34293Skarels {
261*34293Skarels 
262*34293Skarels 	return (0);
263*34293Skarels }
264*34293Skarels 
265*34293Skarels /*
266*34293Skarels  * Configure in a KDB50 controller.
267*34293Skarels  */
268*34293Skarels kdbconfig(kdbnum, va, pa, vec)
269*34293Skarels 	int kdbnum;
270*34293Skarels 	struct biiregs *va, *pa;
271*34293Skarels 	int vec;
272*34293Skarels {
273*34293Skarels 	register struct kdbinfo *ki;
274*34293Skarels #define mi (&ki->ki_mi)
275*34293Skarels 
276*34293Skarels #ifdef lint
277*34293Skarels 	extern int (*kdbint0[])();
278*34293Skarels 
279*34293Skarels 	(*kdbint0[0])(0);	/* this is a config botch */
280*34293Skarels 	kdbintr(0);
281*34293Skarels #endif
282*34293Skarels 
283*34293Skarels 	/*
284*34293Skarels 	 * Set up local KDB status.
285*34293Skarels 	 */
286*34293Skarels 	ki = &kdbinfo[kdbnum];
287*34293Skarels 	ki->ki_kdb = (struct kdb_regs *) va;
288*34293Skarels 	ki->ki_physkdb = (struct kdb_regs *) pa;
289*34293Skarels 	ki->ki_vec = vec;
290*34293Skarels 	ki->ki_map = (struct map *) malloc(KI_MAPSIZ * sizeof (struct map),
291*34293Skarels 	    M_DEVBUF, M_NOWAIT);
292*34293Skarels 	ki->ki_pte = (struct pte *) malloc(KI_PTES * sizeof (struct pte)),
293*34293Skarels 	    M_DEVBUF, M_NOWAIT;
294*34293Skarels 	if (ki->ki_map == NULL || ki->ki_pte == NULL)
295*34293Skarels 		return;
296*34293Skarels 	bzero((caddr_t) ki->ki_map, KI_MAPSIZ * sizeof (struct map));
297*34293Skarels 	bzero((caddr_t) ki->ki_pte, KI_PTES * sizeof (struct pte));
298*34293Skarels 	ki->ki_flags = KDB_ALIVE;
299*34293Skarels 	ki->ki_ptephys = kvtophys(ki->ki_pte);
300*34293Skarels 
301*34293Skarels 	rminit(ki->ki_map, (long)KI_PTES, (long)1, "kdb", KI_MAPSIZ);
302*34293Skarels 
303*34293Skarels 	/*
304*34293Skarels 	 * Set up the generic MSCP structures.
305*34293Skarels 	 */
306*34293Skarels 	mi->mi_md = &kdbmscpdriver;
307*34293Skarels 	mi->mi_ctlr = kdbnum;	/* also sets ki->ki_ctlr */
308*34293Skarels 	mi->mi_tab = &ki->ki_tab;
309*34293Skarels 	mi->mi_ip = kdbip[kdbnum];
310*34293Skarels 	mi->mi_cmd.mri_size = NCMD;
311*34293Skarels 	mi->mi_cmd.mri_desc = ki->ki_ca.ca_cmddsc;
312*34293Skarels 	mi->mi_cmd.mri_ring = ki->ki_cmd;
313*34293Skarels 	mi->mi_rsp.mri_size = NRSP;
314*34293Skarels 	mi->mi_rsp.mri_desc = ki->ki_ca.ca_rspdsc;
315*34293Skarels 	mi->mi_rsp.mri_ring = ki->ki_rsp;
316*34293Skarels 	mi->mi_wtab.av_forw = mi->mi_wtab.av_back = &mi->mi_wtab;
317*34293Skarels #undef mi
318*34293Skarels }
319*34293Skarels 
320*34293Skarels /*
321*34293Skarels  * Find a slave.
322*34293Skarels  * Note that by the time kdbslave is called, the interrupt vector
323*34293Skarels  * for the KDB50 has been set up (so that kdbunconf() will be called).
324*34293Skarels  */
325*34293Skarels kdbslave(ui)
326*34293Skarels 	register struct uba_device *ui;
327*34293Skarels {
328*34293Skarels 	register struct kdbinfo *ki;
329*34293Skarels 	register struct mscp *mp;
330*34293Skarels 	int next = 0, type, timeout, tries, i;
331*34293Skarels 
332*34293Skarels #ifdef lint
333*34293Skarels 	i = 0; i = i;
334*34293Skarels #endif
335*34293Skarels 	/*
336*34293Skarels 	 * Make sure the controller is fully initialised, by waiting
337*34293Skarels 	 * for it if necessary.
338*34293Skarels 	 */
339*34293Skarels 	ki = &kdbinfo[ui->ui_ctlr];
340*34293Skarels 	if (ki->ki_state == ST_RUN)
341*34293Skarels 		goto findunit;
342*34293Skarels 	tries = 0;
343*34293Skarels again:
344*34293Skarels 	if (kdbinit(ki))
345*34293Skarels 		return (0);
346*34293Skarels 	timeout = todr() + 1000;		/* 10 seconds */
347*34293Skarels 	while (todr() < timeout)
348*34293Skarels 		if (ki->ki_state == ST_RUN)	/* made it */
349*34293Skarels 			goto findunit;
350*34293Skarels 	if (++tries < 2)
351*34293Skarels 		goto again;
352*34293Skarels 	printf("kdb%d: controller hung\n", ki->ki_ctlr);
353*34293Skarels 	return (0);
354*34293Skarels 
355*34293Skarels 	/*
356*34293Skarels 	 * The controller is all set; go find the unit.  Grab an
357*34293Skarels 	 * MSCP packet and send out a Get Unit Status command, with
358*34293Skarels 	 * the `next unit' modifier if we are looking for a generic
359*34293Skarels 	 * unit.  We set the `in slave' flag so that kdbunconf()
360*34293Skarels 	 * knows to copy the response to `kdbslavereply'.
361*34293Skarels 	 */
362*34293Skarels findunit:
363*34293Skarels 	kdbslavereply.mscp_opcode = 0;
364*34293Skarels 	ki->ki_flags |= KDB_INSLAVE;
365*34293Skarels 	if ((mp = mscp_getcp(&ki->ki_mi, MSCP_DONTWAIT)) == NULL)
366*34293Skarels 		panic("kdbslave");		/* `cannot happen' */
367*34293Skarels 	mp->mscp_opcode = M_OP_GETUNITST;
368*34293Skarels 	if (ui->ui_slave == '?') {
369*34293Skarels 		mp->mscp_unit = next;
370*34293Skarels 		mp->mscp_modifier = M_GUM_NEXTUNIT;
371*34293Skarels 	} else {
372*34293Skarels 		mp->mscp_unit = ui->ui_slave;
373*34293Skarels 		mp->mscp_modifier = 0;
374*34293Skarels 	}
375*34293Skarels 	*mp->mscp_addr |= MSCP_OWN | MSCP_INT;
376*34293Skarels 	i = ki->ki_kdb->kdb_ip;	/* initiate polling */
377*34293Skarels 	mp = &kdbslavereply;
378*34293Skarels 	timeout = todr() + 1000;
379*34293Skarels 	while (todr() < timeout)
380*34293Skarels 		if (mp->mscp_opcode)
381*34293Skarels 			goto gotit;
382*34293Skarels 	printf("kdb%d: no response to Get Unit Status request\n",
383*34293Skarels 		ki->ki_ctlr);
384*34293Skarels 	ki->ki_flags &= ~KDB_INSLAVE;
385*34293Skarels 	return (0);
386*34293Skarels 
387*34293Skarels gotit:
388*34293Skarels 	ki->ki_flags &= ~KDB_INSLAVE;
389*34293Skarels 
390*34293Skarels 	/*
391*34293Skarels 	 * Got a slave response.  If the unit is there, use it.
392*34293Skarels 	 */
393*34293Skarels 	switch (mp->mscp_status & M_ST_MASK) {
394*34293Skarels 
395*34293Skarels 	case M_ST_SUCCESS:	/* worked */
396*34293Skarels 	case M_ST_AVAILABLE:	/* found another drive */
397*34293Skarels 		break;		/* use it */
398*34293Skarels 
399*34293Skarels 	case M_ST_OFFLINE:
400*34293Skarels 		/*
401*34293Skarels 		 * Figure out why it is off line.  It may be because
402*34293Skarels 		 * it is nonexistent, or because it is spun down, or
403*34293Skarels 		 * for some other reason.
404*34293Skarels 		 */
405*34293Skarels 		switch (mp->mscp_status & ~M_ST_MASK) {
406*34293Skarels 
407*34293Skarels 		case M_OFFLINE_UNKNOWN:
408*34293Skarels 			/*
409*34293Skarels 			 * No such drive, and there are none with
410*34293Skarels 			 * higher unit numbers either, if we are
411*34293Skarels 			 * using M_GUM_NEXTUNIT.
412*34293Skarels 			 */
413*34293Skarels 			return (0);
414*34293Skarels 
415*34293Skarels 		case M_OFFLINE_UNMOUNTED:
416*34293Skarels 			/*
417*34293Skarels 			 * The drive is not spun up.  Use it anyway.
418*34293Skarels 			 *
419*34293Skarels 			 * N.B.: this seems to be a common occurrance
420*34293Skarels 			 * after a power failure.  The first attempt
421*34293Skarels 			 * to bring it on line seems to spin it up
422*34293Skarels 			 * (and thus takes several minutes).  Perhaps
423*34293Skarels 			 * we should note here that the on-line may
424*34293Skarels 			 * take longer than usual.
425*34293Skarels 			 */
426*34293Skarels 			break;
427*34293Skarels 
428*34293Skarels 		default:
429*34293Skarels 			/*
430*34293Skarels 			 * In service, or something else equally unusable.
431*34293Skarels 			 */
432*34293Skarels 			printf("kdb%d: unit %d off line: ", ki->ki_ctlr,
433*34293Skarels 				mp->mscp_unit);
434*34293Skarels 			mscp_printevent(mp);
435*34293Skarels 			goto try_another;
436*34293Skarels 		}
437*34293Skarels 		break;
438*34293Skarels 
439*34293Skarels 	default:
440*34293Skarels 		printf("kdb%d: unable to get unit status: ", ki->ki_ctlr);
441*34293Skarels 		mscp_printevent(mp);
442*34293Skarels 		return (0);
443*34293Skarels 	}
444*34293Skarels 
445*34293Skarels 	/*
446*34293Skarels 	 * Does this ever happen?  What (if anything) does it mean?
447*34293Skarels 	 */
448*34293Skarels 	if (mp->mscp_unit < next) {
449*34293Skarels 		printf("kdb%d: unit %d, next %d\n",
450*34293Skarels 			ki->ki_ctlr, mp->mscp_unit, next);
451*34293Skarels 		return (0);
452*34293Skarels 	}
453*34293Skarels 
454*34293Skarels 	if (mp->mscp_unit >= MAXUNIT) {
455*34293Skarels 		printf("kdb%d: cannot handle unit number %d (max is %d)\n",
456*34293Skarels 			ki->ki_ctlr, mp->mscp_unit, MAXUNIT - 1);
457*34293Skarels 		return (0);
458*34293Skarels 	}
459*34293Skarels 
460*34293Skarels 	/*
461*34293Skarels 	 * See if we already handle this drive.
462*34293Skarels 	 * (Only likely if ui->ui_slave=='?'.)
463*34293Skarels 	 */
464*34293Skarels 	if (kdbip[ki->ki_ctlr][mp->mscp_unit] != NULL)
465*34293Skarels 		goto try_another;
466*34293Skarels 
467*34293Skarels 	/*
468*34293Skarels 	 * Make sure we know about this kind of drive.
469*34293Skarels 	 * Others say we should treat unknowns as RA81s; I am
470*34293Skarels 	 * not sure this is safe.
471*34293Skarels 	 */
472*34293Skarels 	type = mp->mscp_guse.guse_drivetype;
473*34293Skarels 	if (type >= NTYPES || kdbtypes[type].ut_name == 0) {
474*34293Skarels 		register long id = mp->mscp_guse.guse_mediaid;
475*34293Skarels 
476*34293Skarels 		printf("kdb%d: unit %d: media ID `", ki->ki_ctlr,
477*34293Skarels 			mp->mscp_unit);
478*34293Skarels 		printf("%c%c %c%c%c%d",
479*34293Skarels 			MSCP_MID_CHAR(4, id), MSCP_MID_CHAR(3, id),
480*34293Skarels 			MSCP_MID_CHAR(2, id), MSCP_MID_CHAR(1, id),
481*34293Skarels 			MSCP_MID_CHAR(0, id), MSCP_MID_NUM(id));
482*34293Skarels 		printf("' is of unknown type %d; ignored\n", type);
483*34293Skarels try_another:
484*34293Skarels 		if (ui->ui_slave != '?')
485*34293Skarels 			return (0);
486*34293Skarels 		next = mp->mscp_unit + 1;
487*34293Skarels 		goto findunit;
488*34293Skarels 	}
489*34293Skarels 
490*34293Skarels 	/*
491*34293Skarels 	 * Voila!
492*34293Skarels 	 */
493*34293Skarels 	ui->ui_type = type;
494*34293Skarels 	ui->ui_flags = 0;	/* not on line, nor anything else */
495*34293Skarels 	ui->ui_slave = mp->mscp_unit;
496*34293Skarels 	return (1);
497*34293Skarels }
498*34293Skarels 
499*34293Skarels /*
500*34293Skarels  * Attach a found slave.  Make sure the watchdog timer is running.
501*34293Skarels  * If this disk is being profiled, fill in the `mspw' value (used by
502*34293Skarels  * what?).  Set up the inverting pointer, and attempt to bring the
503*34293Skarels  * drive on line.
504*34293Skarels  */
505*34293Skarels kdbattach(ui)
506*34293Skarels 	register struct uba_device *ui;
507*34293Skarels {
508*34293Skarels 
509*34293Skarels 	if (kdbwstart == 0) {
510*34293Skarels 		timeout(kdbwatch, (caddr_t) 0, hz);
511*34293Skarels 		kdbwstart++;
512*34293Skarels 	}
513*34293Skarels 	if (ui->ui_dk >= 0)
514*34293Skarels 		dk_mspw[ui->ui_dk] = 1.0 / (60 * 31 * 256);	/* approx */
515*34293Skarels 	kdbip[ui->ui_ctlr][ui->ui_slave] = ui;
516*34293Skarels 	(void) kdb_bringonline(ui, 1);
517*34293Skarels 	/* should we get its status too? */
518*34293Skarels }
519*34293Skarels 
520*34293Skarels /*
521*34293Skarels  * Initialise a KDB50.  Return true iff something goes wrong.
522*34293Skarels  */
523*34293Skarels kdbinit(ki)
524*34293Skarels 	register struct kdbinfo *ki;
525*34293Skarels {
526*34293Skarels 	register struct kdb_regs *ka = ki->ki_kdb;
527*34293Skarels 	int timo;
528*34293Skarels 
529*34293Skarels 	/*
530*34293Skarels 	 * While we are thinking about it, reset the next command
531*34293Skarels 	 * and response indicies.
532*34293Skarels 	 */
533*34293Skarels 	ki->ki_mi.mi_cmd.mri_next = 0;
534*34293Skarels 	ki->ki_mi.mi_rsp.mri_next = 0;
535*34293Skarels 
536*34293Skarels 	/*
537*34293Skarels 	 * Start up the hardware initialisation sequence.
538*34293Skarels 	 */
539*34293Skarels #define	STEP0MASK (KDB_ERR | KDB_STEP4 | KDB_STEP3 | KDB_STEP2 | KDB_STEP1)
540*34293Skarels 
541*34293Skarels 	ki->ki_state = ST_IDLE;	/* in case init fails */
542*34293Skarels 
543*34293Skarels 	bi_reset(&ka->kdb_bi);	/* reset bi node (but not the BI itself) */
544*34293Skarels 
545*34293Skarels 	timo = todr() + 1000;
546*34293Skarels 	while ((ka->kdb_sa & STEP0MASK) == 0) {
547*34293Skarels 		if (todr() > timo) {
548*34293Skarels 			printf("kdb%d: timeout during init\n", ki->ki_ctlr);
549*34293Skarels 			return (-1);
550*34293Skarels 		}
551*34293Skarels 	}
552*34293Skarels 	if ((ka->kdb_sa & STEP0MASK) != KDB_STEP1) {
553*34293Skarels 		printf("kdb%d: init failed, sa=%b\n", ki->ki_ctlr,
554*34293Skarels 			ka->kdb_sa, kdbsr_bits);
555*34293Skarels 		return (-1);
556*34293Skarels 	}
557*34293Skarels 
558*34293Skarels 	/*
559*34293Skarels 	 * Success!  Record new state, and start step 1 initialisation.
560*34293Skarels 	 * The rest is done in the interrupt handler.
561*34293Skarels 	 */
562*34293Skarels 	ki->ki_state = ST_STEP1;
563*34293Skarels 	ka->kdb_bi.bi_intrdes = 1 << mastercpu;
564*34293Skarels #ifdef unneeded /* is it? */
565*34293Skarels 	ka->kdb_bi.bi_csr = (ka->kdb_bi.bi_csr&~BICSR_ARB_MASK)|BICSR_ARB_???;
566*34293Skarels #endif
567*34293Skarels 	ka->kdb_bi.bi_bcicsr |= BCI_STOPEN | BCI_IDENTEN | BCI_UINTEN |
568*34293Skarels 		BCI_INTEN;
569*34293Skarels 
570*34293Skarels /* I THINK THIS IS WRONG */
571*34293Skarels /* Mach uses 0x601d0, which includes IPL16, but 1d0 is IPL17, nexzvec...? */
572*34293Skarels 	ka->kdb_bi.bi_eintrcsr = BIEIC_IPL15 | ki->ki_vec;	/* ??? */
573*34293Skarels /* END I THINK WRONG */
574*34293Skarels 
575*34293Skarels 	ka->kdb_bi.bi_uintrcsr = ki->ki_vec;
576*34293Skarels 	ka->kdb_sw = KDB_ERR | (NCMDL2 << 11) | (NRSPL2 << 8) | KDB_IE |
577*34293Skarels 		(ki->ki_vec >> 2);
578*34293Skarels 	return (0);
579*34293Skarels }
580*34293Skarels 
581*34293Skarels /*
582*34293Skarels  * Open a drive.
583*34293Skarels  */
584*34293Skarels /*ARGSUSED*/
585*34293Skarels kdbopen(dev, flag)
586*34293Skarels 	dev_t dev;
587*34293Skarels 	int flag;
588*34293Skarels {
589*34293Skarels 	register int unit;
590*34293Skarels 	register struct uba_device *ui;
591*34293Skarels 	register struct kdbinfo *ki;
592*34293Skarels 	int s;
593*34293Skarels 
594*34293Skarels 	/*
595*34293Skarels 	 * Make sure this is a reasonable open request.
596*34293Skarels 	 */
597*34293Skarels 	unit = kdbunit(dev);
598*34293Skarels 	if (unit >= NKRA || (ui = kdbdinfo[unit]) == 0 || ui->ui_alive == 0)
599*34293Skarels 		return (ENXIO);
600*34293Skarels 
601*34293Skarels 	/*
602*34293Skarels 	 * Make sure the controller is running, by (re)initialising it if
603*34293Skarels 	 * necessary.
604*34293Skarels 	 */
605*34293Skarels 	ki = &kdbinfo[ui->ui_ctlr];
606*34293Skarels 	s = spl5();
607*34293Skarels 	if (ki->ki_state != ST_RUN) {
608*34293Skarels 		if (ki->ki_state == ST_IDLE && kdbinit(ki)) {
609*34293Skarels 			splx(s);
610*34293Skarels 			return (EIO);
611*34293Skarels 		}
612*34293Skarels 		/*
613*34293Skarels 		 * In case it does not come up, make sure we will be
614*34293Skarels 		 * restarted in 10 seconds.  This corresponds to the
615*34293Skarels 		 * 10 second timeouts in kdbprobe() and kdbslave().
616*34293Skarels 		 */
617*34293Skarels 		ki->ki_flags |= KDB_DOWAKE;
618*34293Skarels 		timeout(wakeup, (caddr_t) &ki->ki_flags, 10 * hz);
619*34293Skarels 		sleep((caddr_t) &ki->ki_flags, PRIBIO);
620*34293Skarels 		if (ki->ki_state != ST_RUN) {
621*34293Skarels 			splx(s);
622*34293Skarels 			printf("kdb%d: controller hung\n", ui->ui_ctlr);
623*34293Skarels 			return (EIO);
624*34293Skarels 		}
625*34293Skarels 		untimeout(wakeup, (caddr_t) &ki->ki_flags);
626*34293Skarels 	}
627*34293Skarels 	if ((ui->ui_flags & UNIT_ONLINE) == 0) {
628*34293Skarels 		/*
629*34293Skarels 		 * Bring the drive on line so we can find out how
630*34293Skarels 		 * big it is.  If it is not spun up, it will not
631*34293Skarels 		 * come on line; this cannot really be considered
632*34293Skarels 		 * an `error condition'.
633*34293Skarels 		 */
634*34293Skarels 		if (kdb_bringonline(ui, 0)) {
635*34293Skarels 			splx(s);
636*34293Skarels 			printf("%s%d: drive will not come on line\n",
637*34293Skarels 				kdbdriver.ud_dname, unit);
638*34293Skarels 			return (EIO);
639*34293Skarels 		}
640*34293Skarels 	}
641*34293Skarels 	splx(s);
642*34293Skarels 	return (0);
643*34293Skarels }
644*34293Skarels 
645*34293Skarels /*
646*34293Skarels  * Bring a drive on line.  In case it fails to respond, we set
647*34293Skarels  * a timeout on it.  The `nosleep' parameter should be set if
648*34293Skarels  * we are to spin-wait; otherwise this must be called at spl5().
649*34293Skarels  */
650*34293Skarels kdb_bringonline(ui, nosleep)
651*34293Skarels 	register struct uba_device *ui;
652*34293Skarels 	int nosleep;
653*34293Skarels {
654*34293Skarels 	register struct kdbinfo *ki = &kdbinfo[ui->ui_ctlr];
655*34293Skarels 	register struct mscp *mp;
656*34293Skarels 	int i;
657*34293Skarels 
658*34293Skarels 	if (nosleep) {
659*34293Skarels 		mp = mscp_getcp(&ki->ki_mi, MSCP_DONTWAIT);
660*34293Skarels 		if (mp == NULL)
661*34293Skarels 			return (-1);
662*34293Skarels 	} else
663*34293Skarels 		mp = mscp_getcp(&ki->ki_mi, MSCP_WAIT);
664*34293Skarels 	mp->mscp_opcode = M_OP_ONLINE;
665*34293Skarels 	mp->mscp_unit = ui->ui_slave;
666*34293Skarels 	mp->mscp_cmdref = (long) &ui->ui_flags;
667*34293Skarels 	*mp->mscp_addr |= MSCP_OWN | MSCP_INT;
668*34293Skarels 	i = ki->ki_kdb->kdb_ip;
669*34293Skarels 
670*34293Skarels 	if (nosleep) {
671*34293Skarels 		i = todr() + 1000;
672*34293Skarels 		while ((ui->ui_flags & UNIT_ONLINE) == 0)
673*34293Skarels 			if (todr() > i)
674*34293Skarels 				return (-1);
675*34293Skarels 	} else {
676*34293Skarels 		timeout(wakeup, (caddr_t) &ui->ui_flags, 10 * hz);
677*34293Skarels 		sleep((caddr_t) &ui->ui_flags, PRIBIO);
678*34293Skarels 		if ((ui->ui_flags & UNIT_ONLINE) == 0)
679*34293Skarels 			return (-1);
680*34293Skarels 		untimeout(wakeup, (caddr_t) &ui->ui_flags);
681*34293Skarels 	}
682*34293Skarels 	return (0);	/* made it */
683*34293Skarels }
684*34293Skarels 
685*34293Skarels /*
686*34293Skarels  * Queue a transfer request, and if possible, hand it to the controller.
687*34293Skarels  *
688*34293Skarels  * This routine is broken into two so that the internal version
689*34293Skarels  * kdbstrat1() can be called by the (nonexistent, as yet) bad block
690*34293Skarels  * revectoring routine.
691*34293Skarels  */
692*34293Skarels kdbstrategy(bp)
693*34293Skarels 	register struct buf *bp;
694*34293Skarels {
695*34293Skarels 	register int unit;
696*34293Skarels 	register struct uba_device *ui;
697*34293Skarels 	register struct size *st;
698*34293Skarels 	daddr_t sz, maxsz;
699*34293Skarels 
700*34293Skarels 	/*
701*34293Skarels 	 * Make sure this is a reasonable drive to use.
702*34293Skarels 	 */
703*34293Skarels 	if ((unit = kdbunit(bp->b_dev)) >= NKRA ||
704*34293Skarels 	    (ui = kdbdinfo[unit]) == NULL || ui->ui_alive == 0) {
705*34293Skarels 		bp->b_error = ENXIO;
706*34293Skarels 		bp->b_flags |= B_ERROR;
707*34293Skarels 		biodone(bp);
708*34293Skarels 		return;
709*34293Skarels 	}
710*34293Skarels 
711*34293Skarels 	/*
712*34293Skarels 	 * Determine the size of the transfer, and make sure it is
713*34293Skarels 	 * within the boundaries of the drive.
714*34293Skarels 	 */
715*34293Skarels 	sz = (bp->b_bcount + 511) >> 9;
716*34293Skarels 	st = &kdbtypes[ui->ui_type].ut_sizes[kdbpart(bp->b_dev)];
717*34293Skarels 	if ((maxsz = st->nblocks) < 0)
718*34293Skarels 		maxsz = ra_dsize[unit] - st->blkoff;
719*34293Skarels 	if (bp->b_blkno < 0 || bp->b_blkno + sz > maxsz ||
720*34293Skarels 	    st->blkoff >= ra_dsize[unit]) {
721*34293Skarels 		/* if exactly at end of disk, return an EOF */
722*34293Skarels 		if (bp->b_blkno == maxsz)
723*34293Skarels 			bp->b_resid = bp->b_bcount;
724*34293Skarels 		else {
725*34293Skarels 			bp->b_error = EINVAL;
726*34293Skarels 			bp->b_flags |= B_ERROR;
727*34293Skarels 		}
728*34293Skarels 		biodone(bp);
729*34293Skarels 		return;
730*34293Skarels 	}
731*34293Skarels 	kdbstrat1(bp);
732*34293Skarels }
733*34293Skarels 
734*34293Skarels /*
735*34293Skarels  * Work routine for kdbstrategy.
736*34293Skarels  */
737*34293Skarels kdbstrat1(bp)
738*34293Skarels 	register struct buf *bp;
739*34293Skarels {
740*34293Skarels 	register int unit = kdbunit(bp->b_dev);
741*34293Skarels 	register struct buf *dp;
742*34293Skarels 	register struct kdbinfo *ki;
743*34293Skarels 	struct uba_device *ui;
744*34293Skarels 	int s;
745*34293Skarels 
746*34293Skarels 	/*
747*34293Skarels 	 * Append the buffer to the drive queue, and if it is not
748*34293Skarels 	 * already there, the drive to the controller queue.  (However,
749*34293Skarels 	 * if the drive queue is marked to be requeued, we must be
750*34293Skarels 	 * awaiting an on line or get unit status command; in this
751*34293Skarels 	 * case, leave it off the controller queue.)
752*34293Skarels 	 */
753*34293Skarels 	ui = kdbdinfo[unit];
754*34293Skarels 	ki = &kdbinfo[ui->ui_ctlr];
755*34293Skarels 	dp = &kdbutab[unit];
756*34293Skarels 	s = spl5();
757*34293Skarels 	APPEND(bp, dp, av_forw);
758*34293Skarels 	if (dp->b_active == 0 && (ui->ui_flags & UNIT_REQUEUE) == 0) {
759*34293Skarels 		APPEND(dp, &ki->ki_tab, b_forw);
760*34293Skarels 		dp->b_active++;
761*34293Skarels 	}
762*34293Skarels 
763*34293Skarels 	/*
764*34293Skarels 	 * Start activity on the controller.
765*34293Skarels 	 */
766*34293Skarels 	kdbstart(ki);
767*34293Skarels 	splx(s);
768*34293Skarels }
769*34293Skarels 
770*34293Skarels /*
771*34293Skarels  * Find the physical address of some contiguous PTEs that map the
772*34293Skarels  * transfer described in `bp', creating them (by copying) if
773*34293Skarels  * necessary.  Store the physical base address of the map through
774*34293Skarels  * mapbase, and the page offset through offset, and any resource
775*34293Skarels  * information in *info (or 0 if none).
776*34293Skarels  *
777*34293Skarels  * If we cannot allocate space, return a nonzero status.
778*34293Skarels  */
779*34293Skarels int
780*34293Skarels kdbmap(ki, bp, mapbase, offset, info)
781*34293Skarels 	struct kdbinfo *ki;
782*34293Skarels 	register struct buf *bp;
783*34293Skarels 	long *mapbase, *offset;
784*34293Skarels 	int *info;
785*34293Skarels {
786*34293Skarels 	register struct pte *spte, *dpte;
787*34293Skarels 	register struct proc *rp;
788*34293Skarels 	register int i, a, o;
789*34293Skarels 	u_int v;
790*34293Skarels 	int npf;
791*34293Skarels 
792*34293Skarels 	o = (int)bp->b_un.b_addr & PGOFSET;
793*34293Skarels 
794*34293Skarels 	/* handle contiguous cases */
795*34293Skarels 	if ((bp->b_flags & B_PHYS) == 0) {
796*34293Skarels 		spte = kvtopte(bp->b_un.b_addr);
797*34293Skarels 		kdbstats.ks_sys++;
798*34293Skarels 		*mapbase = PHYS(long, spte);
799*34293Skarels 		*offset = o;
800*34293Skarels 		*info = 0;
801*34293Skarels 		return (0);
802*34293Skarels 	}
803*34293Skarels 	if (bp->b_flags & B_PAGET) {
804*34293Skarels 		spte = &Usrptmap[btokmx((struct pte *)bp->b_un.b_addr)];
805*34293Skarels if (spte->pg_v == 0) panic("kdbmap");
806*34293Skarels 		kdbstats.ks_paget++;
807*34293Skarels 		*mapbase = PHYS(long, spte);
808*34293Skarels 		*offset = o;
809*34293Skarels 		*info = 0;
810*34293Skarels 		return (0);
811*34293Skarels 	}
812*34293Skarels 
813*34293Skarels 	/* potentially discontiguous or invalid ptes */
814*34293Skarels 	v = btop(bp->b_un.b_addr);
815*34293Skarels 	rp = bp->b_flags & B_DIRTY ? &proc[2] : bp->b_proc;
816*34293Skarels 	if (bp->b_flags & B_UAREA)
817*34293Skarels 		spte = &rp->p_addr[v];
818*34293Skarels 	else
819*34293Skarels 		spte = vtopte(rp, v);
820*34293Skarels 	npf = btoc(bp->b_bcount + o);
821*34293Skarels 
822*34293Skarels #ifdef notdef
823*34293Skarels 	/*
824*34293Skarels 	 * The current implementation of the VM system requires
825*34293Skarels 	 * that all of these be done with a copy.  Even if the
826*34293Skarels 	 * PTEs could be used now, they may be snatched out from
827*34293Skarels 	 * under us later.  It would be nice if we could stop that....
828*34293Skarels 	 */
829*34293Skarels 
830*34293Skarels 	/* check for invalid */
831*34293Skarels 	/* CONSIDER CHANGING VM TO VALIDATE PAGES EARLIER */
832*34293Skarels 	for (dpte = spte, i = npf; --i >= 0; dpte++)
833*34293Skarels 		if (dpte->pg_v == 0)
834*34293Skarels 			goto copy1;
835*34293Skarels 	/*
836*34293Skarels 	 * Check for discontiguous physical pte addresses.  It is
837*34293Skarels 	 * not necessary to check each pte, since they come in clumps
838*34293Skarels 	 * of pages.
839*34293Skarels 	 */
840*34293Skarels 	i = howmany(npf + (((int)spte & PGOFSET) / sizeof (*spte)), NPTEPG);
841*34293Skarels 	/* often i==1, and we can avoid work */
842*34293Skarels 	if (--i > 0) {
843*34293Skarels 		dpte = kvtopte(spte);
844*34293Skarels 		a = dpte->pg_pfnum;
845*34293Skarels 		while (--i >= 0)
846*34293Skarels 			if ((++dpte)->pg_pfnum != ++a)
847*34293Skarels 				goto copy2;
848*34293Skarels 	}
849*34293Skarels 
850*34293Skarels 	/* made it */
851*34293Skarels 	kdbstats.ks_contig++;
852*34293Skarels 	*mapbase = kvtophys(spte);
853*34293Skarels 	*offset = o;
854*34293Skarels 	*info = 0;
855*34293Skarels 	return (0);
856*34293Skarels 
857*34293Skarels copy1:
858*34293Skarels 	kdbstats.ks_inval++;		/* temp */
859*34293Skarels copy2:
860*34293Skarels #endif /* notdef */
861*34293Skarels 	kdbstats.ks_copies++;
862*34293Skarels 	i = npf + 1;
863*34293Skarels 	if ((a = rmalloc(ki->ki_map, (long) i)) == 0) {
864*34293Skarels 		kdbstats.ks_mapwait++;
865*34293Skarels 		return (-1);
866*34293Skarels 	}
867*34293Skarels 	*info = (i << 16) | a;
868*34293Skarels 	a--;
869*34293Skarels 	/* if offset > PGOFSET, btop(offset) indexes mapbase */
870*34293Skarels 	*mapbase = ki->ki_ptephys;
871*34293Skarels 	*offset = (a << PGSHIFT) | o;
872*34293Skarels 	dpte = &ki->ki_pte[a];
873*34293Skarels 	while (--i > 0)
874*34293Skarels 		*(int *)dpte++ = PG_V | *(int *)spte++;
875*34293Skarels 	*(int *)dpte = 0;
876*34293Skarels 	return (0);
877*34293Skarels }
878*34293Skarels 
879*34293Skarels #define	KDBFREE(ki, info) if (info) \
880*34293Skarels 	rmfree((ki)->ki_map, (long)((info) >> 16), (long)((info) & 0xffff))
881*34293Skarels 
882*34293Skarels /*
883*34293Skarels  * Start up whatever transfers we can find.
884*34293Skarels  * Note that kdbstart() must be called at spl5().
885*34293Skarels  */
886*34293Skarels kdbstart(ki)
887*34293Skarels 	register struct kdbinfo *ki;
888*34293Skarels {
889*34293Skarels 	register struct buf *bp, *dp;
890*34293Skarels 	register struct mscp *mp;
891*34293Skarels 	register struct uba_device *ui;
892*34293Skarels 	long mapbase, offset;
893*34293Skarels 	int info, ncmd = 0;
894*34293Skarels 
895*34293Skarels 	/*
896*34293Skarels 	 * If it is not running, try (again and again...) to initialise
897*34293Skarels 	 * it.  If it is currently initialising just ignore it for now.
898*34293Skarels 	 */
899*34293Skarels 	if (ki->ki_state != ST_RUN) {
900*34293Skarels 		if (ki->ki_state == ST_IDLE && kdbinit(ki))
901*34293Skarels 			printf("kdb%d: still hung\n", ki->ki_ctlr);
902*34293Skarels 		return;
903*34293Skarels 	}
904*34293Skarels 
905*34293Skarels loop:
906*34293Skarels 	/* if insufficient credit, avoid overhead */
907*34293Skarels 	if (ki->ki_mi.mi_credits <= MSCP_MINCREDITS)
908*34293Skarels 		goto out;
909*34293Skarels 
910*34293Skarels 	/*
911*34293Skarels 	 * Service the drive at the head of the queue.  We take exactly
912*34293Skarels 	 * one transfer from this drive, then move it to the end of the
913*34293Skarels 	 * controller queue, so as to get more drive overlap.
914*34293Skarels 	 */
915*34293Skarels 	if ((dp = ki->ki_tab.b_actf) == NULL)
916*34293Skarels 		goto out;
917*34293Skarels 
918*34293Skarels 	/*
919*34293Skarels 	 * Get the first request from the drive queue.  There must be
920*34293Skarels 	 * one, or something is rotten.
921*34293Skarels 	 */
922*34293Skarels 	if ((bp = dp->b_actf) == NULL)
923*34293Skarels 		panic("kdbstart: bp==NULL\n");
924*34293Skarels 
925*34293Skarels 	if (ki->ki_kdb->kdb_sa & KDB_ERR) {	/* ctlr fatal error */
926*34293Skarels 		kdbsaerror(ki);
927*34293Skarels 		goto out;
928*34293Skarels 	}
929*34293Skarels 
930*34293Skarels 	 /* find or create maps for this transfer */
931*34293Skarels 	 if (kdbmap(ki, bp, &mapbase, &offset, &info))
932*34293Skarels 		goto out;	/* effectively, resource wait */
933*34293Skarels 
934*34293Skarels 	/*
935*34293Skarels 	 * Get an MSCP packet, then figure out what to do.  If
936*34293Skarels 	 * we cannot get a command packet, the command ring may
937*34293Skarels 	 * be too small:  We should have at least as many command
938*34293Skarels 	 * packets as credits, for best performance.
939*34293Skarels 	 */
940*34293Skarels 	if ((mp = mscp_getcp(&ki->ki_mi, MSCP_DONTWAIT)) == NULL) {
941*34293Skarels 		if (ki->ki_mi.mi_credits > MSCP_MINCREDITS &&
942*34293Skarels 		    (ki->ki_flags & KDB_GRIPED) == 0) {
943*34293Skarels 			log(LOG_NOTICE, "kdb%d: command ring too small\n",
944*34293Skarels 				ki->ki_ctlr);
945*34293Skarels 			ki->ki_flags |= KDB_GRIPED;/* complain only once */
946*34293Skarels 		}
947*34293Skarels 		KDBFREE(ki, info);
948*34293Skarels 		goto out;
949*34293Skarels 	}
950*34293Skarels 
951*34293Skarels 	/*
952*34293Skarels 	 * Bring the drive on line if it is not already.  Get its status
953*34293Skarels 	 * if we do not already have it.  Otherwise just start the transfer.
954*34293Skarels 	 */
955*34293Skarels 	ui = kdbdinfo[kdbunit(bp->b_dev)];
956*34293Skarels 	if ((ui->ui_flags & UNIT_ONLINE) == 0) {
957*34293Skarels 		mp->mscp_opcode = M_OP_ONLINE;
958*34293Skarels 		goto common;
959*34293Skarels 	}
960*34293Skarels 	if ((ui->ui_flags & UNIT_HAVESTATUS) == 0) {
961*34293Skarels 		mp->mscp_opcode = M_OP_GETUNITST;
962*34293Skarels common:
963*34293Skarels if (ui->ui_flags & UNIT_REQUEUE) panic("kdbstart");
964*34293Skarels 		/*
965*34293Skarels 		 * Take the drive off the controller queue.  When the
966*34293Skarels 		 * command finishes, make sure the drive is requeued.
967*34293Skarels 		 * Give up any mapping (not needed now).  This last is
968*34293Skarels 		 * not efficient, but is rare.
969*34293Skarels 		 */
970*34293Skarels 		KDBFREE(ki, info);
971*34293Skarels 		ki->ki_tab.b_actf = dp->b_forw;
972*34293Skarels 		dp->b_active = 0;
973*34293Skarels 		ui->ui_flags |= UNIT_REQUEUE;
974*34293Skarels 		mp->mscp_unit = ui->ui_slave;
975*34293Skarels 		*mp->mscp_addr |= MSCP_OWN | MSCP_INT;
976*34293Skarels 		ncmd++;
977*34293Skarels 		goto loop;
978*34293Skarels 	}
979*34293Skarels 
980*34293Skarels 	mp->mscp_opcode = (bp->b_flags & B_READ) ? M_OP_READ : M_OP_WRITE;
981*34293Skarels 	mp->mscp_unit = ui->ui_slave;
982*34293Skarels 	mp->mscp_seq.seq_lbn = bp->b_blkno +
983*34293Skarels 		kdbtypes[ui->ui_type].ut_sizes[kdbpart(bp->b_dev)].blkoff;
984*34293Skarels 	mp->mscp_seq.seq_bytecount = bp->b_bcount;
985*34293Skarels 
986*34293Skarels 	mp->mscp_seq.seq_buffer = offset | KDB_MAP;
987*34293Skarels 	mp->mscp_seq.seq_mapbase = mapbase;
988*34293Skarels 
989*34293Skarels 	/* profile the drive */
990*34293Skarels 	if (ui->ui_dk >= 0) {
991*34293Skarels 		dk_busy |= 1 << ui->ui_dk;
992*34293Skarels 		dk_xfer[ui->ui_dk]++;
993*34293Skarels 		dk_wds[ui->ui_dk] += bp->b_bcount >> 6;
994*34293Skarels 	}
995*34293Skarels 
996*34293Skarels 	/*
997*34293Skarels 	 * Fill in the rest of the MSCP packet and move the buffer to the
998*34293Skarels 	 * I/O wait queue.
999*34293Skarels 	 */
1000*34293Skarels 	mscp_go(&ki->ki_mi, mp, info);
1001*34293Skarels 	ncmd++;			/* note the transfer */
1002*34293Skarels 	ki->ki_tab.b_active++;	/* another one going */
1003*34293Skarels 	goto loop;
1004*34293Skarels 
1005*34293Skarels out:
1006*34293Skarels 	if (ncmd >= KS_MAXC)
1007*34293Skarels 		ncmd = KS_MAXC - 1;
1008*34293Skarels 	kdbstats.ks_cmd[ncmd]++;
1009*34293Skarels 	if (ncmd)		/* start some transfers */
1010*34293Skarels 		ncmd = ki->ki_kdb->kdb_ip;
1011*34293Skarels }
1012*34293Skarels 
1013*34293Skarels /* ARGSUSED */
1014*34293Skarels kdbiodone(mi, bp, info)
1015*34293Skarels 	struct mscp_info *mi;
1016*34293Skarels 	struct buf *bp;
1017*34293Skarels 	int info;
1018*34293Skarels {
1019*34293Skarels 	register struct kdbinfo *ki = &kdbinfo[mi->mi_ctlr];
1020*34293Skarels 
1021*34293Skarels 	KDBFREE(ki, info);
1022*34293Skarels 	biodone(bp);
1023*34293Skarels 	ki->ki_tab.b_active--;	/* another one done */
1024*34293Skarels }
1025*34293Skarels 
1026*34293Skarels /*
1027*34293Skarels  * The error bit was set in the controller status register.  Gripe,
1028*34293Skarels  * reset the controller, requeue pending transfers.
1029*34293Skarels  */
1030*34293Skarels kdbsaerror(ki)
1031*34293Skarels 	register struct kdbinfo *ki;
1032*34293Skarels {
1033*34293Skarels 
1034*34293Skarels 	printf("kdb%d: controller error, sa=%b\n", ki->ki_ctlr,
1035*34293Skarels 		ki->ki_kdb->kdb_sa, kdbsr_bits);
1036*34293Skarels 	mscp_requeue(&ki->ki_mi);
1037*34293Skarels 	(void) kdbinit(ki);
1038*34293Skarels }
1039*34293Skarels 
1040*34293Skarels /*
1041*34293Skarels  * Interrupt routine.  Depending on the state of the controller,
1042*34293Skarels  * continue initialisation, or acknowledge command and response
1043*34293Skarels  * interrupts, and process responses.
1044*34293Skarels  */
1045*34293Skarels kdbintr(ctlr)
1046*34293Skarels 	int ctlr;
1047*34293Skarels {
1048*34293Skarels 	register struct kdbinfo *ki = &kdbinfo[ctlr];
1049*34293Skarels 	register struct kdb_regs *kdbaddr = ki->ki_kdb;
1050*34293Skarels 	register struct mscp *mp;
1051*34293Skarels 	register int i;
1052*34293Skarels 
1053*34293Skarels 	ki->ki_wticks = 0;	/* reset interrupt watchdog */
1054*34293Skarels 
1055*34293Skarels 	/*
1056*34293Skarels 	 * Combinations during steps 1, 2, and 3: STEPnMASK
1057*34293Skarels 	 * corresponds to which bits should be tested;
1058*34293Skarels 	 * STEPnGOOD corresponds to the pattern that should
1059*34293Skarels 	 * appear after the interrupt from STEPn initialisation.
1060*34293Skarels 	 * All steps test the bits in ALLSTEPS.
1061*34293Skarels 	 */
1062*34293Skarels #define	ALLSTEPS	(KDB_ERR|KDB_STEP4|KDB_STEP3|KDB_STEP2|KDB_STEP1)
1063*34293Skarels 
1064*34293Skarels #define	STEP1MASK	(ALLSTEPS | KDB_IE | KDB_NCNRMASK)
1065*34293Skarels #define	STEP1GOOD	(KDB_STEP2 | KDB_IE | (NCMDL2 << 3) | NRSPL2)
1066*34293Skarels 
1067*34293Skarels #define	STEP2MASK	(ALLSTEPS | KDB_IE | KDB_IVECMASK)
1068*34293Skarels #define	STEP2GOOD	(KDB_STEP3 | KDB_IE | (ki->ki_vec >> 2))
1069*34293Skarels 
1070*34293Skarels #define	STEP3MASK	ALLSTEPS
1071*34293Skarels #define	STEP3GOOD	KDB_STEP4
1072*34293Skarels 
1073*34293Skarels 	switch (ki->ki_state) {
1074*34293Skarels 
1075*34293Skarels 	case ST_IDLE:
1076*34293Skarels 		/*
1077*34293Skarels 		 * Ignore unsolicited interrupts.
1078*34293Skarels 		 */
1079*34293Skarels 		log(LOG_WARNING, "kdb%d: stray intr\n", ctlr);
1080*34293Skarels 		return;
1081*34293Skarels 
1082*34293Skarels 	case ST_STEP1:
1083*34293Skarels 		/*
1084*34293Skarels 		 * Begin step two initialisation.
1085*34293Skarels 		 */
1086*34293Skarels 		if ((kdbaddr->kdb_sa & STEP1MASK) != STEP1GOOD) {
1087*34293Skarels 			i = 1;
1088*34293Skarels initfailed:
1089*34293Skarels 			printf("kdb%d: init step %d failed, sa=%b\n",
1090*34293Skarels 				ctlr, i, kdbaddr->kdb_sa, kdbsr_bits);
1091*34293Skarels 			ki->ki_state = ST_IDLE;
1092*34293Skarels 			if (ki->ki_flags & KDB_DOWAKE) {
1093*34293Skarels 				ki->ki_flags &= ~KDB_DOWAKE;
1094*34293Skarels 				wakeup((caddr_t) &ki->ki_flags);
1095*34293Skarels 			}
1096*34293Skarels 			return;
1097*34293Skarels 		}
1098*34293Skarels 		kdbaddr->kdb_sw = PHYS(int, &ki->ki_ca.ca_rspdsc[0]);
1099*34293Skarels 		ki->ki_state = ST_STEP2;
1100*34293Skarels 		return;
1101*34293Skarels 
1102*34293Skarels 	case ST_STEP2:
1103*34293Skarels 		/*
1104*34293Skarels 		 * Begin step 3 initialisation.
1105*34293Skarels 		 */
1106*34293Skarels 		if ((kdbaddr->kdb_sa & STEP2MASK) != STEP2GOOD) {
1107*34293Skarels 			i = 2;
1108*34293Skarels 			goto initfailed;
1109*34293Skarels 		}
1110*34293Skarels 		kdbaddr->kdb_sw = PHYS(int, &ki->ki_ca.ca_rspdsc[0]) >> 16;
1111*34293Skarels 		ki->ki_state = ST_STEP3;
1112*34293Skarels 		return;
1113*34293Skarels 
1114*34293Skarels 	case ST_STEP3:
1115*34293Skarels 		/*
1116*34293Skarels 		 * Set controller characteristics (finish initialisation).
1117*34293Skarels 		 */
1118*34293Skarels 		if ((kdbaddr->kdb_sa & STEP3MASK) != STEP3GOOD) {
1119*34293Skarels 			i = 3;
1120*34293Skarels 			goto initfailed;
1121*34293Skarels 		}
1122*34293Skarels 		i = kdbaddr->kdb_sa & 0xff;
1123*34293Skarels 		if (i != ki->ki_micro) {
1124*34293Skarels 			ki->ki_micro = i;
1125*34293Skarels 			printf("kdb%d: version %d model %d\n",
1126*34293Skarels 				ctlr, i & 0xf, i >> 4);
1127*34293Skarels 		}
1128*34293Skarels 
1129*34293Skarels 		kdbaddr->kdb_sw = KDB_GO;
1130*34293Skarels 
1131*34293Skarels 		/* initialise hardware data structures */
1132*34293Skarels 		for (i = 0, mp = ki->ki_rsp; i < NRSP; i++, mp++) {
1133*34293Skarels 			ki->ki_ca.ca_rspdsc[i] = MSCP_OWN | MSCP_INT |
1134*34293Skarels 				PHYS(long, &ki->ki_rsp[i].mscp_cmdref);
1135*34293Skarels 			mp->mscp_addr = &ki->ki_ca.ca_rspdsc[i];
1136*34293Skarels 			mp->mscp_msglen = MSCP_MSGLEN;
1137*34293Skarels 		}
1138*34293Skarels 		for (i = 0, mp = ki->ki_cmd; i < NCMD; i++, mp++) {
1139*34293Skarels 			ki->ki_ca.ca_cmddsc[i] = MSCP_INT |
1140*34293Skarels 				PHYS(long, &ki->ki_cmd[i].mscp_cmdref);
1141*34293Skarels 			mp->mscp_addr = &ki->ki_ca.ca_cmddsc[i];
1142*34293Skarels 			mp->mscp_msglen = MSCP_MSGLEN;
1143*34293Skarels 		}
1144*34293Skarels 
1145*34293Skarels 		/*
1146*34293Skarels 		 * Before we can get a command packet, we need some
1147*34293Skarels 		 * credits.  Fake some up to keep mscp_getcp() happy,
1148*34293Skarels 		 * get a packet, and cancel all credits (the right
1149*34293Skarels 		 * number should come back in the response to the
1150*34293Skarels 		 * SCC packet).
1151*34293Skarels 		 */
1152*34293Skarels 		ki->ki_mi.mi_credits = MSCP_MINCREDITS + 1;
1153*34293Skarels 		mp = mscp_getcp(&ki->ki_mi, MSCP_DONTWAIT);
1154*34293Skarels 		if (mp == NULL)	/* `cannot happen' */
1155*34293Skarels 			panic("kdbintr");
1156*34293Skarels 		ki->ki_mi.mi_credits = 0;
1157*34293Skarels 		mp->mscp_opcode = M_OP_SETCTLRC;
1158*34293Skarels 		mp->mscp_unit = 0;
1159*34293Skarels 		mp->mscp_sccc.sccc_ctlrflags = M_CF_ATTN | M_CF_MISC |
1160*34293Skarels 			M_CF_THIS;
1161*34293Skarels 		*mp->mscp_addr |= MSCP_OWN | MSCP_INT;
1162*34293Skarels 		i = kdbaddr->kdb_ip;
1163*34293Skarels 		ki->ki_state = ST_SETCHAR;
1164*34293Skarels 		return;
1165*34293Skarels 
1166*34293Skarels 	case ST_SETCHAR:
1167*34293Skarels 	case ST_RUN:
1168*34293Skarels 		/*
1169*34293Skarels 		 * Handle Set Ctlr Characteristics responses and operational
1170*34293Skarels 		 * responses (via mscp_dorsp).
1171*34293Skarels 		 */
1172*34293Skarels 		break;
1173*34293Skarels 
1174*34293Skarels 	default:
1175*34293Skarels 		log(LOG_ERR, "kdb%d: driver bug, state %d\n", ctlr,
1176*34293Skarels 			ki->ki_state);
1177*34293Skarels 		return;
1178*34293Skarels 	}
1179*34293Skarels 
1180*34293Skarels 	if (kdbaddr->kdb_sa & KDB_ERR) {/* ctlr fatal error */
1181*34293Skarels 		kdbsaerror(ki);
1182*34293Skarels 		return;
1183*34293Skarels 	}
1184*34293Skarels 
1185*34293Skarels 	/*
1186*34293Skarels 	 * Handle buffer purge requests.
1187*34293Skarels 	 * KDB DOES NOT HAVE BDPs
1188*34293Skarels 	 */
1189*34293Skarels 	if (ki->ki_ca.ca_bdp) {
1190*34293Skarels 		printf("kdb%d: purge bdp %d\n", ctlr, ki->ki_ca.ca_bdp);
1191*34293Skarels 		panic("kdb purge");
1192*34293Skarels 	}
1193*34293Skarels 
1194*34293Skarels 	/*
1195*34293Skarels 	 * Check for response and command ring transitions.
1196*34293Skarels 	 */
1197*34293Skarels 	if (ki->ki_ca.ca_rspint) {
1198*34293Skarels 		ki->ki_ca.ca_rspint = 0;
1199*34293Skarels 		mscp_dorsp(&ki->ki_mi);
1200*34293Skarels 	}
1201*34293Skarels 	if (ki->ki_ca.ca_cmdint) {
1202*34293Skarels 		ki->ki_ca.ca_cmdint = 0;
1203*34293Skarels 		MSCP_DOCMD(&ki->ki_mi);
1204*34293Skarels 	}
1205*34293Skarels 	if (ki->ki_tab.b_actf != NULL)
1206*34293Skarels 		kdbstart(ki);
1207*34293Skarels }
1208*34293Skarels 
1209*34293Skarels /*
1210*34293Skarels  * Handle an error datagram.  All we do now is decode it.
1211*34293Skarels  */
1212*34293Skarels kdbdgram(mi, mp)
1213*34293Skarels 	struct mscp_info *mi;
1214*34293Skarels 	struct mscp *mp;
1215*34293Skarels {
1216*34293Skarels 
1217*34293Skarels 	mscp_decodeerror(mi->mi_md->md_mname, mi->mi_ctlr, mp);
1218*34293Skarels }
1219*34293Skarels 
1220*34293Skarels /*
1221*34293Skarels  * The Set Controller Characteristics command finished.
1222*34293Skarels  * Record the new state of the controller.
1223*34293Skarels  */
1224*34293Skarels kdbctlrdone(mi, mp)
1225*34293Skarels 	struct mscp_info *mi;
1226*34293Skarels 	struct mscp *mp;
1227*34293Skarels {
1228*34293Skarels 	register struct kdbinfo *ki = &kdbinfo[mi->mi_ctlr];
1229*34293Skarels 
1230*34293Skarels 	if ((mp->mscp_status & M_ST_MASK) == M_ST_SUCCESS)
1231*34293Skarels 		ki->ki_state = ST_RUN;
1232*34293Skarels 	else {
1233*34293Skarels 		printf("kdb%d: SETCTLRC failed, status 0x%x\n",
1234*34293Skarels 			ki->ki_ctlr, mp->mscp_status);
1235*34293Skarels 		ki->ki_state = ST_IDLE;
1236*34293Skarels 	}
1237*34293Skarels 	if (ki->ki_flags & KDB_DOWAKE) {
1238*34293Skarels 		ki->ki_flags &= ~KDB_DOWAKE;
1239*34293Skarels 		wakeup((caddr_t) &ki->ki_flags);
1240*34293Skarels 	}
1241*34293Skarels }
1242*34293Skarels 
1243*34293Skarels /*
1244*34293Skarels  * Received a response from an as-yet unconfigured drive.  Configure it
1245*34293Skarels  * in, if possible.
1246*34293Skarels  */
1247*34293Skarels kdbunconf(mi, mp)
1248*34293Skarels 	struct mscp_info *mi;
1249*34293Skarels 	register struct mscp *mp;
1250*34293Skarels {
1251*34293Skarels 
1252*34293Skarels 	/*
1253*34293Skarels 	 * If it is a slave response, copy it to kdbslavereply for
1254*34293Skarels 	 * kdbslave() to look at.
1255*34293Skarels 	 */
1256*34293Skarels 	if (mp->mscp_opcode == (M_OP_GETUNITST | M_OP_END) &&
1257*34293Skarels 	    (kdbinfo[mi->mi_ctlr].ki_flags & KDB_INSLAVE) != 0) {
1258*34293Skarels 		kdbslavereply = *mp;
1259*34293Skarels 		return (MSCP_DONE);
1260*34293Skarels 	}
1261*34293Skarels 
1262*34293Skarels 	/*
1263*34293Skarels 	 * Otherwise, it had better be an available attention response.
1264*34293Skarels 	 */
1265*34293Skarels 	if (mp->mscp_opcode != M_OP_AVAILATTN)
1266*34293Skarels 		return (MSCP_FAILED);
1267*34293Skarels 
1268*34293Skarels 	/* do what autoconf does */
1269*34293Skarels 	return (MSCP_FAILED);	/* not yet */
1270*34293Skarels }
1271*34293Skarels 
1272*34293Skarels /*
1273*34293Skarels  * A drive came on line.  Check its type and size.  Return DONE if
1274*34293Skarels  * we think the drive is truly on line.  In any case, awaken anyone
1275*34293Skarels  * sleeping on the drive on-line-ness.
1276*34293Skarels  */
1277*34293Skarels kdbonline(ui, mp)
1278*34293Skarels 	register struct uba_device *ui;
1279*34293Skarels 	struct mscp *mp;
1280*34293Skarels {
1281*34293Skarels 	register int type;
1282*34293Skarels 
1283*34293Skarels 	wakeup((caddr_t) &ui->ui_flags);
1284*34293Skarels 	if ((mp->mscp_status & M_ST_MASK) != M_ST_SUCCESS) {
1285*34293Skarels 		printf("kdb%d: attempt to bring %s%d on line failed: ",
1286*34293Skarels 			ui->ui_ctlr, kdbdriver.ud_dname, ui->ui_unit);
1287*34293Skarels 		mscp_printevent(mp);
1288*34293Skarels 		return (MSCP_FAILED);
1289*34293Skarels 	}
1290*34293Skarels 
1291*34293Skarels 	type = mp->mscp_onle.onle_drivetype;
1292*34293Skarels 	if (type >= NTYPES || kdbtypes[type].ut_name == 0) {
1293*34293Skarels 		printf("kdb%d: %s%d: unknown type %d\n",
1294*34293Skarels 			ui->ui_ctlr, kdbdriver.ud_dname, ui->ui_unit, type);
1295*34293Skarels 		return (MSCP_FAILED);
1296*34293Skarels 	}
1297*34293Skarels 	/*
1298*34293Skarels 	 * Note any change of types.  Not sure if we should do
1299*34293Skarels 	 * something special about them, or if so, what....
1300*34293Skarels 	 */
1301*34293Skarels 	if (type != ui->ui_type) {
1302*34293Skarels 		printf("%s%d: changed types! was %s\n",
1303*34293Skarels 			kdbdriver.ud_dname, ui->ui_unit,
1304*34293Skarels 			kdbtypes[ui->ui_type].ut_name);
1305*34293Skarels 		ui->ui_type = type;
1306*34293Skarels 	}
1307*34293Skarels 	ra_dsize[ui->ui_unit] = (daddr_t) mp->mscp_onle.onle_unitsize;
1308*34293Skarels 	printf("%s%d: %s, size = %d sectors\n",
1309*34293Skarels 		kdbdriver.ud_dname, ui->ui_unit,
1310*34293Skarels 		kdbtypes[type].ut_name, ra_dsize[ui->ui_unit]);
1311*34293Skarels 	return (MSCP_DONE);
1312*34293Skarels }
1313*34293Skarels 
1314*34293Skarels /*
1315*34293Skarels  * We got some (configured) unit's status.  Return DONE if it succeeded.
1316*34293Skarels  */
1317*34293Skarels kdbgotstatus(ui, mp)
1318*34293Skarels 	register struct uba_device *ui;
1319*34293Skarels 	register struct mscp *mp;
1320*34293Skarels {
1321*34293Skarels 
1322*34293Skarels 	if ((mp->mscp_status & M_ST_MASK) != M_ST_SUCCESS) {
1323*34293Skarels 		printf("kdb%d: attempt to get status for %s%d failed: ",
1324*34293Skarels 			ui->ui_ctlr, kdbdriver.ud_dname, ui->ui_unit);
1325*34293Skarels 		mscp_printevent(mp);
1326*34293Skarels 		return (MSCP_FAILED);
1327*34293Skarels 	}
1328*34293Skarels 	/* need to record later for bad block forwarding - for now, print */
1329*34293Skarels 	printf("\
1330*34293Skarels %s%d: unit %d, nspt %d, group %d, ngpc %d, rctsize %d, nrpt %d, nrct %d\n",
1331*34293Skarels 		kdbdriver.ud_dname, ui->ui_unit, mp->mscp_unit,
1332*34293Skarels 		mp->mscp_guse.guse_nspt, mp->mscp_guse.guse_group,
1333*34293Skarels 		mp->mscp_guse.guse_ngpc, mp->mscp_guse.guse_rctsize,
1334*34293Skarels 		mp->mscp_guse.guse_nrpt, mp->mscp_guse.guse_nrct);
1335*34293Skarels 	return (MSCP_DONE);
1336*34293Skarels }
1337*34293Skarels 
1338*34293Skarels /*
1339*34293Skarels  * A transfer failed.  We get a chance to fix or restart it.
1340*34293Skarels  * Need to write the bad block forwaring code first....
1341*34293Skarels  */
1342*34293Skarels /*ARGSUSED*/
1343*34293Skarels kdbioerror(ui, mp, bp)
1344*34293Skarels 	register struct uba_device *ui;
1345*34293Skarels 	register struct mscp *mp;
1346*34293Skarels 	struct buf *bp;
1347*34293Skarels {
1348*34293Skarels 
1349*34293Skarels 	if (mp->mscp_flags & M_EF_BBLKR) {
1350*34293Skarels 		/*
1351*34293Skarels 		 * A bad block report.  Eventually we will
1352*34293Skarels 		 * restart this transfer, but for now, just
1353*34293Skarels 		 * log it and give up.
1354*34293Skarels 		 */
1355*34293Skarels 		log(LOG_ERR, "%s%d: bad block report: %d%s\n",
1356*34293Skarels 			kdbdriver.ud_dname, ui->ui_unit, mp->mscp_seq.seq_lbn,
1357*34293Skarels 			mp->mscp_flags & M_EF_BBLKU ? " + others" : "");
1358*34293Skarels 	} else {
1359*34293Skarels 		/*
1360*34293Skarels 		 * What the heck IS a `serious exception' anyway?
1361*34293Skarels 		 */
1362*34293Skarels 		if (mp->mscp_flags & M_EF_SEREX)
1363*34293Skarels 			log(LOG_ERR, "%s%d: serious exception reported\n",
1364*34293Skarels 				kdbdriver.ud_dname, ui->ui_unit);
1365*34293Skarels 	}
1366*34293Skarels 	return (MSCP_FAILED);
1367*34293Skarels }
1368*34293Skarels 
1369*34293Skarels 
1370*34293Skarels #ifdef notyet
1371*34293Skarels /*
1372*34293Skarels  * I/O controls.  Not yet!
1373*34293Skarels  */
1374*34293Skarels kdbioctl(dev, cmd, flag, data)
1375*34293Skarels 	dev_t dev;
1376*34293Skarels 	int cmd, flag;
1377*34293Skarels 	caddr_t data;
1378*34293Skarels {
1379*34293Skarels 	int error = 0;
1380*34293Skarels 	register int unit = kdbunit(dev);
1381*34293Skarels 
1382*34293Skarels 	if (unit >= NKRA || uddinfo[unit] == NULL)
1383*34293Skarels 		return (ENXIO);
1384*34293Skarels 
1385*34293Skarels 	switch (cmd) {
1386*34293Skarels 
1387*34293Skarels 	case KDBIOCREPLACE:
1388*34293Skarels 		/*
1389*34293Skarels 		 * Initiate bad block replacement for the given LBN.
1390*34293Skarels 		 * (Should we allow modifiers?)
1391*34293Skarels 		 */
1392*34293Skarels 		error = EOPNOTSUPP;
1393*34293Skarels 		break;
1394*34293Skarels 
1395*34293Skarels 	case KDBIOCGMICRO:
1396*34293Skarels 		/*
1397*34293Skarels 		 * Return the microcode revision for the KDB50 running
1398*34293Skarels 		 * this drive.
1399*34293Skarels 		 */
1400*34293Skarels 		*(int *) data = kdbinfo[kdbdinfo[unit]->ui_ctlr].ki_micro;
1401*34293Skarels 		break;
1402*34293Skarels 
1403*34293Skarels 	case KDBIOCGSIZE:
1404*34293Skarels 		/*
1405*34293Skarels 		 * Return the size (in 512 byte blocks) of this
1406*34293Skarels 		 * disk drive.
1407*34293Skarels 		 */
1408*34293Skarels 		*(daddr_t *) data = ra_dsize[unit];
1409*34293Skarels 		break;
1410*34293Skarels 
1411*34293Skarels 	default:
1412*34293Skarels 		error = EINVAL;
1413*34293Skarels 		break;
1414*34293Skarels 	}
1415*34293Skarels 	return (error);
1416*34293Skarels }
1417*34293Skarels #endif
1418*34293Skarels 
1419*34293Skarels #ifdef notyet
1420*34293Skarels /*
1421*34293Skarels  * Reset a KDB50 (self test and all).
1422*34293Skarels  * What if it fails?
1423*34293Skarels  */
1424*34293Skarels kdbreset(ki)
1425*34293Skarels 	register struct kdbinfo *ki;
1426*34293Skarels {
1427*34293Skarels 
1428*34293Skarels 	printf("reset kdb%d", ki->ki_ctlr);
1429*34293Skarels 	bi_selftest(&ki->ki_kdb.kdb_bi);
1430*34293Skarels 	ki->ki_state = ST_IDLE;
1431*34293Skarels 	rminit(ki->ki_map, (long)KI_PTES, (long)1, "kdb", KI_MAPSIZ);
1432*34293Skarels 	mscp_requeue(&ki->ki_mi);
1433*34293Skarels 	if (kdbinit(ctlr))
1434*34293Skarels 		printf(" (hung)");
1435*34293Skarels 	printf("\n");
1436*34293Skarels }
1437*34293Skarels #endif
1438*34293Skarels 
1439*34293Skarels /*
1440*34293Skarels  * Watchdog timer:  If the controller is active, and no interrupts
1441*34293Skarels  * have occurred for 30 seconds, assume it has gone away.
1442*34293Skarels  */
1443*34293Skarels kdbwatch()
1444*34293Skarels {
1445*34293Skarels 	register struct kdbinfo *ki;
1446*34293Skarels 	register int i;
1447*34293Skarels 
1448*34293Skarels 	timeout(kdbwatch, (caddr_t) 0, hz);	/* every second */
1449*34293Skarels 	for (i = 0, ki = kdbinfo; i < NKDB; i++, ki++) {
1450*34293Skarels 		if ((ki->ki_flags & KDB_ALIVE) == 0)
1451*34293Skarels 			continue;
1452*34293Skarels 		if (ki->ki_state == ST_IDLE)
1453*34293Skarels 			continue;
1454*34293Skarels 		if (ki->ki_state == ST_RUN && !ki->ki_tab.b_active)
1455*34293Skarels 			ki->ki_wticks = 0;
1456*34293Skarels 		else if (++ki->ki_wticks >= 30) {
1457*34293Skarels 			ki->ki_wticks = 0;
1458*34293Skarels 			printf("kdb%d: lost interrupt\n", i);
1459*34293Skarels 			/* kdbreset(ki); */
1460*34293Skarels 			panic("kdb lost interrupt");
1461*34293Skarels 		}
1462*34293Skarels 	}
1463*34293Skarels }
1464*34293Skarels 
1465*34293Skarels /*
1466*34293Skarels  * Do a panic dump.
1467*34293Skarels  */
1468*34293Skarels #define	DBSIZE	32		/* dump 16K at a time */
1469*34293Skarels 
1470*34293Skarels struct kdbdumpspace {
1471*34293Skarels 	struct	kdb1ca kd_ca;
1472*34293Skarels 	struct	mscp kd_rsp;
1473*34293Skarels 	struct	mscp kd_cmd;
1474*34293Skarels } kdbdumpspace;
1475*34293Skarels 
1476*34293Skarels kdbdump(dev)
1477*34293Skarels 	dev_t dev;
1478*34293Skarels {
1479*34293Skarels 	register struct kdbdumpspace *kd;
1480*34293Skarels 	register struct kdb_regs *k;
1481*34293Skarels 	register int i;
1482*34293Skarels 	struct uba_device *ui;
1483*34293Skarels 	char *start;
1484*34293Skarels 	int num, blk, unit, maxsz, blkoff;
1485*34293Skarels 
1486*34293Skarels 	/*
1487*34293Skarels 	 * Make sure the device is a reasonable place on which to dump.
1488*34293Skarels 	 */
1489*34293Skarels 	unit = kdbunit(dev);
1490*34293Skarels 	if (unit >= NKRA)
1491*34293Skarels 		return (ENXIO);
1492*34293Skarels 	ui = PHYS(struct uba_device *, kdbdinfo[unit]);
1493*34293Skarels 	if (ui == NULL || ui->ui_alive == 0)
1494*34293Skarels 		return (ENXIO);
1495*34293Skarels 
1496*34293Skarels 	/*
1497*34293Skarels 	 * Find and initialise the KDB; get the physical address of the
1498*34293Skarels 	 * device registers, and of communications area and command and
1499*34293Skarels 	 * response packet.
1500*34293Skarels 	 */
1501*34293Skarels 	k = PHYS(struct kdbinfo *, &kdbinfo[ui->ui_ctlr])->ki_physkdb;
1502*34293Skarels 	kd = PHYS(struct kdbdumpspace *, &kdbdumpspace);
1503*34293Skarels 
1504*34293Skarels 	/*
1505*34293Skarels 	 * Initialise the controller, with one command and one response
1506*34293Skarels 	 * packet.
1507*34293Skarels 	 */
1508*34293Skarels 	bi_reset(&k->kdb_bi);
1509*34293Skarels 	if (kdbdumpwait(k, KDB_STEP1))
1510*34293Skarels 		return (EFAULT);
1511*34293Skarels 	k->kdb_sw = KDB_ERR;
1512*34293Skarels 	if (kdbdumpwait(k, KDB_STEP2))
1513*34293Skarels 		return (EFAULT);
1514*34293Skarels 	k->kdb_sw = (int) &kd->kd_ca.ca_rspdsc;
1515*34293Skarels 	if (kdbdumpwait(k, KDB_STEP3))
1516*34293Skarels 		return (EFAULT);
1517*34293Skarels 	k->kdb_sw = ((int) &kd->kd_ca.ca_rspdsc) >> 16;
1518*34293Skarels 	if (kdbdumpwait(k, KDB_STEP4))
1519*34293Skarels 		return (EFAULT);
1520*34293Skarels 	k->kdb_sw = KDB_GO;
1521*34293Skarels 
1522*34293Skarels 	/*
1523*34293Skarels 	 * Set up the command and response descriptor, then set the
1524*34293Skarels 	 * controller characteristics and bring the drive on line.
1525*34293Skarels 	 * Note that all uninitialised locations in kd_cmd are zero.
1526*34293Skarels 	 */
1527*34293Skarels 	kd->kd_ca.ca_rspdsc = (long) &kd->kd_rsp.mscp_cmdref;
1528*34293Skarels 	kd->kd_ca.ca_cmddsc = (long) &kd->kd_cmd.mscp_cmdref;
1529*34293Skarels 	/* kd->kd_cmd.mscp_sccc.sccc_ctlrflags = 0; */
1530*34293Skarels 	/* kd->kd_cmd.mscp_sccc.sccc_version = 0; */
1531*34293Skarels 	if (kdbdumpcmd(M_OP_SETCTLRC, k, kd, ui->ui_ctlr))
1532*34293Skarels 		return (EFAULT);
1533*34293Skarels 	kd->kd_cmd.mscp_unit = ui->ui_slave;
1534*34293Skarels 	if (kdbdumpcmd(M_OP_ONLINE, k, kd, ui->ui_ctlr))
1535*34293Skarels 		return (EFAULT);
1536*34293Skarels 
1537*34293Skarels 	/*
1538*34293Skarels 	 * Pick up the drive type from the on line end packet;
1539*34293Skarels 	 * convert that to a dump area size and a disk offset.
1540*34293Skarels 	 * Note that the assembler uses pc-relative addressing
1541*34293Skarels 	 * to get at kdbtypes[], no need for PHYS().
1542*34293Skarels 	 */
1543*34293Skarels 	i = kd->kd_rsp.mscp_onle.onle_drivetype;
1544*34293Skarels 	if (i >= NTYPES || kdbtypes[i].ut_name == 0) {
1545*34293Skarels 		printf("disk type %d unknown\ndump ");
1546*34293Skarels 		return (EINVAL);
1547*34293Skarels 	}
1548*34293Skarels 	printf("on %s ", kdbtypes[i].ut_name);
1549*34293Skarels 
1550*34293Skarels 	maxsz = kdbtypes[i].ut_sizes[kdbpart(dev)].nblocks;
1551*34293Skarels 	blkoff = kdbtypes[i].ut_sizes[kdbpart(dev)].blkoff;
1552*34293Skarels 
1553*34293Skarels 	/*
1554*34293Skarels 	 * Dump all of physical memory, or as much as will fit in the
1555*34293Skarels 	 * space provided.
1556*34293Skarels 	 */
1557*34293Skarels 	start = 0;
1558*34293Skarels 	num = maxfree;
1559*34293Skarels 	if (dumplo < 0)
1560*34293Skarels 		return (EINVAL);
1561*34293Skarels 	if (dumplo + num >= maxsz)
1562*34293Skarels 		num = maxsz - dumplo;
1563*34293Skarels 	blkoff += dumplo;
1564*34293Skarels 
1565*34293Skarels 	/*
1566*34293Skarels 	 * Write out memory, DBSIZE pages at a time.
1567*34293Skarels 	 * N.B.: this code depends on the fact that the sector
1568*34293Skarels 	 * size == the page size.
1569*34293Skarels 	 */
1570*34293Skarels 	while (num > 0) {
1571*34293Skarels 		blk = num > DBSIZE ? DBSIZE : num;
1572*34293Skarels 		kd->kd_cmd.mscp_unit = ui->ui_slave;
1573*34293Skarels 		kd->kd_cmd.mscp_seq.seq_lbn = btop(start) + blkoff;
1574*34293Skarels 		kd->kd_cmd.mscp_seq.seq_bytecount = blk << PGSHIFT;
1575*34293Skarels 		kd->kd_cmd.mscp_seq.seq_buffer = (long)start | KDB_PHYS;
1576*34293Skarels 		if (kdbdumpcmd(M_OP_WRITE, k, kd, ui->ui_ctlr))
1577*34293Skarels 			return (EIO);
1578*34293Skarels 		start += blk << PGSHIFT;
1579*34293Skarels 		num -= blk;
1580*34293Skarels 	}
1581*34293Skarels 	return (0);		/* made it! */
1582*34293Skarels }
1583*34293Skarels 
1584*34293Skarels /*
1585*34293Skarels  * Wait for some of the bits in `bits' to come on.  If the error bit
1586*34293Skarels  * comes on, or ten seconds pass without response, return true (error).
1587*34293Skarels  */
1588*34293Skarels kdbdumpwait(k, bits)
1589*34293Skarels 	register struct kdb_regs *k;
1590*34293Skarels 	register int bits;
1591*34293Skarels {
1592*34293Skarels 	register int timo = todr() + 1000;
1593*34293Skarels 
1594*34293Skarels 	while ((k->kdb_sa & bits) == 0) {
1595*34293Skarels 		if (k->kdb_sa & KDB_ERR) {
1596*34293Skarels 			printf("kdb_sa=%b\ndump ", k->kdb_sa, kdbsr_bits);
1597*34293Skarels 			return (1);
1598*34293Skarels 		}
1599*34293Skarels 		if (todr() >= timo) {
1600*34293Skarels 			printf("timeout\ndump ");
1601*34293Skarels 			return (1);
1602*34293Skarels 		}
1603*34293Skarels 	}
1604*34293Skarels 	return (0);
1605*34293Skarels }
1606*34293Skarels 
1607*34293Skarels /*
1608*34293Skarels  * Feed a command to the KDB50, wait for its response, and return
1609*34293Skarels  * true iff something went wrong.
1610*34293Skarels  */
1611*34293Skarels kdbdumpcmd(op, k, kd, ctlr)
1612*34293Skarels 	int op;
1613*34293Skarels 	register struct kdb_regs *k;
1614*34293Skarels 	register struct kdbdumpspace *kd;
1615*34293Skarels 	int ctlr;
1616*34293Skarels {
1617*34293Skarels 	register int n;
1618*34293Skarels #define mp (&kd->kd_rsp)
1619*34293Skarels 
1620*34293Skarels 	kd->kd_cmd.mscp_opcode = op;
1621*34293Skarels 	kd->kd_cmd.mscp_msglen = MSCP_MSGLEN;
1622*34293Skarels 	kd->kd_rsp.mscp_msglen = MSCP_MSGLEN;
1623*34293Skarels 	kd->kd_ca.ca_rspdsc |= MSCP_OWN | MSCP_INT;
1624*34293Skarels 	kd->kd_ca.ca_cmddsc |= MSCP_OWN | MSCP_INT;
1625*34293Skarels 	if (k->kdb_sa & KDB_ERR) {
1626*34293Skarels 		printf("kdb_sa=%b\ndump ", k->kdb_sa, kdbsr_bits);
1627*34293Skarels 		return (1);
1628*34293Skarels 	}
1629*34293Skarels 	n = k->kdb_ip;
1630*34293Skarels 	n = todr() + 1000;
1631*34293Skarels 	for (;;) {
1632*34293Skarels 		if (todr() > n) {
1633*34293Skarels 			printf("timeout\ndump ");
1634*34293Skarels 			return (1);
1635*34293Skarels 		}
1636*34293Skarels 		if (kd->kd_ca.ca_cmdint)
1637*34293Skarels 			kd->kd_ca.ca_cmdint = 0;
1638*34293Skarels 		if (kd->kd_ca.ca_rspint == 0)
1639*34293Skarels 			continue;
1640*34293Skarels 		kd->kd_ca.ca_rspint = 0;
1641*34293Skarels 		if (mp->mscp_opcode == (op | M_OP_END))
1642*34293Skarels 			break;
1643*34293Skarels 		printf("\n");
1644*34293Skarels 		switch (MSCP_MSGTYPE(mp->mscp_msgtc)) {
1645*34293Skarels 
1646*34293Skarels 		case MSCPT_SEQ:
1647*34293Skarels 			printf("sequential");
1648*34293Skarels 			break;
1649*34293Skarels 
1650*34293Skarels 		case MSCPT_DATAGRAM:
1651*34293Skarels 			mscp_decodeerror("kdb", ctlr, mp);
1652*34293Skarels 			printf("datagram");
1653*34293Skarels 			break;
1654*34293Skarels 
1655*34293Skarels 		case MSCPT_CREDITS:
1656*34293Skarels 			printf("credits");
1657*34293Skarels 			break;
1658*34293Skarels 
1659*34293Skarels 		case MSCPT_MAINTENANCE:
1660*34293Skarels 			printf("maintenance");
1661*34293Skarels 			break;
1662*34293Skarels 
1663*34293Skarels 		default:
1664*34293Skarels 			printf("unknown (type 0x%x)",
1665*34293Skarels 				MSCP_MSGTYPE(mp->mscp_msgtc));
1666*34293Skarels 			break;
1667*34293Skarels 		}
1668*34293Skarels 		printf(" ignored\ndump ");
1669*34293Skarels 		kd->kd_ca.ca_rspdsc |= MSCP_OWN | MSCP_INT;
1670*34293Skarels 	}
1671*34293Skarels 	if ((mp->mscp_status & M_ST_MASK) != M_ST_SUCCESS) {
1672*34293Skarels 		printf("error: op 0x%x => 0x%x status 0x%x\ndump ", op,
1673*34293Skarels 			mp->mscp_opcode, mp->mscp_status);
1674*34293Skarels 		return (1);
1675*34293Skarels 	}
1676*34293Skarels 	return (0);
1677*34293Skarels #undef mp
1678*34293Skarels }
1679*34293Skarels 
1680*34293Skarels /*
1681*34293Skarels  * Return the size of a partition, if known, or -1 if not.
1682*34293Skarels  */
1683*34293Skarels kdbsize(dev)
1684*34293Skarels 	dev_t dev;
1685*34293Skarels {
1686*34293Skarels 	register int unit = kdbunit(dev);
1687*34293Skarels 	register struct uba_device *ui;
1688*34293Skarels 	register struct size *st;
1689*34293Skarels 
1690*34293Skarels 	if (unit >= NKRA || (ui = kdbdinfo[unit]) == NULL || ui->ui_alive == 0)
1691*34293Skarels 		return (-1);
1692*34293Skarels 	st = &kdbtypes[ui->ui_type].ut_sizes[kdbpart(dev)];
1693*34293Skarels 	if (st->nblocks == -1) {
1694*34293Skarels 		int s = spl5();
1695*34293Skarels 
1696*34293Skarels 		/*
1697*34293Skarels 		 * We need to have the drive on line to find the size
1698*34293Skarels 		 * of this particular partition.
1699*34293Skarels 		 * IS IT OKAY TO GO TO SLEEP IN THIS ROUTINE?
1700*34293Skarels 		 * (If not, better not page on one of these...)
1701*34293Skarels 		 */
1702*34293Skarels 		if ((ui->ui_flags & UNIT_ONLINE) == 0) {
1703*34293Skarels 			if (kdb_bringonline(ui, 0)) {
1704*34293Skarels 				splx(s);
1705*34293Skarels 				return (-1);
1706*34293Skarels 			}
1707*34293Skarels 		}
1708*34293Skarels 		splx(s);
1709*34293Skarels 		if (st->blkoff > ra_dsize[unit])
1710*34293Skarels 			return (-1);
1711*34293Skarels 		return (ra_dsize[unit] - st->blkoff);
1712*34293Skarels 	}
1713*34293Skarels 	return (st->nblocks);
1714*34293Skarels }
1715*34293Skarels 
1716*34293Skarels #endif NKDB > 0
1717