xref: /csrg-svn/sys/vax/bi/kdb.c (revision 38171)
134293Skarels /*
235041Sbostic  * Copyright (c) 1988 Regents of the University of California.
335041Sbostic  * All rights reserved.
434293Skarels  *
535041Sbostic  * This code is derived from software contributed to Berkeley by
635041Sbostic  * Chris Torek.
735041Sbostic  *
835041Sbostic  * Redistribution and use in source and binary forms are permitted
935041Sbostic  * provided that the above copyright notice and this paragraph are
1035041Sbostic  * duplicated in all such forms and that any documentation,
1135041Sbostic  * advertising materials, and other materials related to such
1235041Sbostic  * distribution and use acknowledge that the software was developed
1335041Sbostic  * by the University of California, Berkeley.  The name of the
1435041Sbostic  * University may not be used to endorse or promote products derived
1535041Sbostic  * from this software without specific prior written permission.
1635041Sbostic  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
1735041Sbostic  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
1835041Sbostic  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
1935041Sbostic  *
20*38171Smckusick  *	@(#)kdb.c	7.7 (Berkeley) 05/29/89
2135041Sbostic  */
2235041Sbostic 
2335041Sbostic /*
2434293Skarels  * KDB50/MSCP device driver
2534293Skarels  */
2634293Skarels 
2734293Skarels /*
2834293Skarels  * TODO
2934293Skarels  *	rethink BI software interface
3034293Skarels  *	write bad block forwarding code
3134293Skarels  */
3234293Skarels 
3334293Skarels #include "kra.h"		/* XXX */
3434293Skarels 
3534293Skarels #define	DRIVENAMES	"kra"	/* XXX */
3634293Skarels 
3734293Skarels #if NKDB > 0
3834293Skarels 
3934293Skarels /*
4034293Skarels  * CONFIGURATION OPTIONS.  The next three defines are tunable -- tune away!
4134293Skarels  *
4234293Skarels  * NRSPL2 and NCMDL2 control the number of response and command
4334293Skarels  * packets respectively.  They may be any value from 0 to 7, though
4434293Skarels  * setting them higher than 5 is unlikely to be of any value.
4534293Skarels  * If you get warnings about your command ring being too small,
4634293Skarels  * try increasing the values by one.
4734293Skarels  *
4834293Skarels  * MAXUNIT controls the maximum slave number (and hence number of drives
4934293Skarels  * per controller) we are prepared to handle.
5034293Skarels  */
5134293Skarels #define	NRSPL2	5		/* log2 number of response packets */
5234293Skarels #define NCMDL2	5		/* log2 number of command packets */
5334293Skarels #define	MAXUNIT	8		/* maximum allowed unit number */
5434293Skarels 
5534293Skarels #include "param.h"
5634293Skarels #include "systm.h"
5734293Skarels #include "malloc.h"
5834293Skarels #include "map.h"
5934293Skarels #include "buf.h"
6034293Skarels #include "conf.h"
6134293Skarels #include "dir.h"
6234293Skarels #include "user.h"
6334293Skarels #include "proc.h"
6434293Skarels #include "vm.h"
6534293Skarels #include "dkstat.h"
6634293Skarels #include "cmap.h"
6734293Skarels #include "syslog.h"
6834293Skarels #include "kernel.h"
6934293Skarels 
7034293Skarels #define	NRSP	(1 << NRSPL2)
7134293Skarels #define	NCMD	(1 << NCMDL2)
7234293Skarels 
7334510Skarels #include "../vax/pte.h"
7434293Skarels #include "../vax/cpu.h"
7534293Skarels #include "../vax/mscp.h"
7634293Skarels #include "../vax/mscpvar.h"
7734293Skarels #include "../vax/mtpr.h"
7834293Skarels 
7934293Skarels #include "bireg.h"
8034293Skarels #include "kdbreg.h"
8134510Skarels 
8234293Skarels #include "../vaxuba/ubavar.h"
8334293Skarels 
8434293Skarels /*
8534293Skarels  * Conversions from kernel virtual to physical and page table addresses.
8634293Skarels  * PHYS works only for kernel text and primary (compile time) data addresses.
8734293Skarels  */
8834293Skarels #define	PHYS(cast, addr) \
8934293Skarels 	((cast) ((int)(addr) & 0x7fffffff))
9034293Skarels 
9134293Skarels /*
9234293Skarels  * KDB variables, per controller.
9334293Skarels  */
9434293Skarels struct kdbinfo {
9534293Skarels 	/* software info, per KDB */
9634293Skarels 	struct	kdb_regs *ki_kdb;	/* KDB registers */
9734293Skarels 	struct	kdb_regs *ki_physkdb;	/* phys address of KDB registers */
9834293Skarels 	short	ki_state;		/* KDB50 state; see below */
9934293Skarels 	short	ki_flags;		/* flags; see below */
10034293Skarels 	int	ki_micro;		/* microcode revision */
10134293Skarels 	short	ki_vec;			/* scb vector offset */
10234293Skarels 	short	ki_wticks;		/* watchdog timer ticks */
10334293Skarels 
10434293Skarels 	/*
10534293Skarels 	 * KDB PTEs must be contiguous.  Some I/O is done on addresses
10634293Skarels 	 * for which this is true (PTEs in Sysmap and Usrptmap), but
10734293Skarels 	 * other transfers may have PTEs that are scattered in physical
10834293Skarels 	 * space.  Ki_map maps a physically contiguous PTE space used
10934757Sbostic 	 * for these transfers.
11034293Skarels 	 */
11134293Skarels #define KI_MAPSIZ	(NCMD + 2)
11234293Skarels 	struct	map *ki_map;		/* resource map */
11334293Skarels #define KI_PTES		256
11434757Sbostic 	struct	pte ki_pte[KI_PTES];	/* contiguous PTE space */
11534293Skarels 	long	ki_ptephys;		/* phys address of &ki_pte[0] */
11634293Skarels 
11734293Skarels 	struct	mscp_info ki_mi;	/* MSCP info (per mscpvar.h) */
11834293Skarels 	struct	buf ki_tab;		/* controller queue */
11934293Skarels 
12034293Skarels 	/* stuff read and written by hardware */
12134293Skarels 	struct	kdbca ki_ca;		/* communications area */
12234293Skarels 	struct	mscp ki_rsp[NRSP];	/* response packets */
12334293Skarels 	struct	mscp ki_cmd[NCMD];	/* command packets */
12434293Skarels } kdbinfo[NKDB];
12534293Skarels 
12634293Skarels #define	ki_ctlr	ki_mi.mi_ctlr
12734293Skarels 
12834293Skarels /*
12934293Skarels  * Controller states
13034293Skarels  */
13134293Skarels #define	ST_IDLE		0	/* uninitialised */
13234293Skarels #define	ST_STEP1	1	/* in `STEP 1' */
13334293Skarels #define	ST_STEP2	2	/* in `STEP 2' */
13434293Skarels #define	ST_STEP3	3	/* in `STEP 3' */
13534293Skarels #define	ST_SETCHAR	4	/* in `Set Controller Characteristics' */
13634293Skarels #define	ST_RUN		5	/* up and running */
13734293Skarels 
13834293Skarels /*
13934293Skarels  * Flags
14034293Skarels  */
14134293Skarels #define	KDB_ALIVE	0x01	/* this KDB50 exists */
14234293Skarels #define	KDB_GRIPED	0x04	/* griped about cmd ring too small */
14334293Skarels #define	KDB_INSLAVE	0x08	/* inside kdbslave() */
14434293Skarels #define	KDB_DOWAKE	0x10	/* wakeup when ctlr init done */
14534293Skarels 
14634293Skarels struct kdbstats kdbstats;	/* statistics */
14734293Skarels 
14834293Skarels /*
14934293Skarels  * Device to unit number and partition:
15034293Skarels  */
15134293Skarels #define	UNITSHIFT	3
15234293Skarels #define	UNITMASK	7
15334293Skarels #define	kdbunit(dev)	(minor(dev) >> UNITSHIFT)
15434293Skarels #define	kdbpart(dev)	(minor(dev) & UNITMASK)
15534293Skarels 
15634293Skarels /* THIS SHOULD BE READ OFF THE PACK, PER DRIVE */
15734293Skarels /* THESE SHOULD BE SHARED WITH uda.c (but not yet) */
15834293Skarels struct size {
15934293Skarels 	daddr_t nblocks;
16034293Skarels 	daddr_t blkoff;
16134293Skarels } kra81_sizes[8] = {
16234293Skarels #ifdef MARYLAND
16334293Skarels 	67832,	0,		/* A=cyl    0 thru   94 + 2 sectors */
16434293Skarels 	67828,	67832,		/* B=cyl   95 thru  189 - 2 sectors */
16534293Skarels 	-1,	0,		/* C=cyl    0 thru 1247 */
16634293Skarels 	-1,	135660,		/* D=cyl  190 thru 1247 */
16734293Skarels 	449466,	49324,		/* E xxx */
16834293Skarels 	64260,	498790,		/* F xxx */
16934293Skarels 	328022,	563050,		/* G xxx */
17034293Skarels 	0,	0,
17134293Skarels #else
17234293Skarels 	15884,	0,		/* a */
17334293Skarels 	33440,	15884,		/* b */
17434293Skarels 	-1,	0,		/* c */
17534293Skarels 	-1,	49324,		/* d */
17634293Skarels 	449466,	49324,		/* e */
17734293Skarels 	64260,	498790,		/* f */
17834293Skarels 	328022,	563050,		/* g */
17934293Skarels 	0,	0,
18034293Skarels #endif
18134293Skarels }, kra80_sizes[8] = {
18234293Skarels 	15884,	0,		/* A=blk 0 thru 15883 */
18334293Skarels 	33440,	15884,		/* B=blk 15884 thru 49323 */
18434293Skarels 	-1,	0,		/* C=blk 0 thru end */
18534293Skarels 	0,	0,
18634293Skarels 	0,	0,
18734293Skarels 	0,	0,
18834293Skarels 	82080,	49324,		/* G=blk 49324 thru 131403 */
18934293Skarels 	-1,	131404,		/* H=blk 131404 thru end */
19034293Skarels }, kra60_sizes[8] = {
19134293Skarels 	15884,	0,		/* A=blk 0 thru 15883 */
19234293Skarels 	33440,	15884,		/* B=blk 15884 thru 49323 */
19334293Skarels 	-1,	0,		/* C=blk 0 thru end */
19434293Skarels 	-1,	49324,		/* D=blk 49324 thru end */
19534293Skarels 	0,	0,
19634293Skarels 	0,	0,
19734293Skarels 	82080,	49324,		/* G=blk 49324 thru 131403 */
19834293Skarels 	-1,	131404,		/* H=blk 131404 thru end */
19934293Skarels };
20034293Skarels /* END OF STUFF WHICH SHOULD BE READ IN PER DISK */
20134293Skarels 
20234293Skarels /*
20334293Skarels  * Drive type index decoding table.  `ut_name' is null iff the
20434293Skarels  * type is not known.
20534293Skarels  */
20634293Skarels struct	kdbtypes {
20734293Skarels 	char	*ut_name;	/* drive type name */
20834293Skarels 	struct	size *ut_sizes;	/* partition tables */
20934293Skarels } kdbtypes[] = {
21034293Skarels 	NULL,		NULL,
21134293Skarels 	"ra80",		kra80_sizes,	/* 1 = ra80 */
21234293Skarels 	NULL,		NULL,
21334293Skarels 	NULL,		NULL,
21434293Skarels 	"ra60",		kra60_sizes,	/* 4 = ra60 */
21534293Skarels 	"ra81",		kra81_sizes,	/* 5 = ra81 */
21634293Skarels };
21734293Skarels 
21834293Skarels #define NTYPES 6
21934293Skarels 
22034293Skarels /*
22134293Skarels  * Definition of the driver for autoconf and generic MSCP code.
22234293Skarels  * SOME OF THIS IS BOGUS (must fix config)
22334293Skarels  */
22434293Skarels 
22534293Skarels #ifdef notdef		/* not when driver is for kra disks */
22634293Skarels /*
22734293Skarels  * Some of these variables (per-drive stuff) are shared
22834293Skarels  * with the UDA50 code (why not, they are the same drives).
22934293Skarels  * N.B.: kdbdinfo must not be shared.
23034293Skarels  */
23134293Skarels #define	kdbutab		udautab		/* shared */
23234293Skarels #define	kdbslavereply	udaslavereply	/* shared */
23334293Skarels #endif
23434293Skarels 
23534293Skarels int	kdbprobe();		/* XXX */
23634293Skarels int	kdbslave(), kdbattach();
23734293Skarels 
23834293Skarels int	kdbdgram(), kdbctlrdone(), kdbunconf(), kdbiodone();
23934293Skarels int	kdbonline(), kdbgotstatus(), kdbioerror();
24034293Skarels 
24134293Skarels struct	uba_device *kdbdinfo[NKRA];	/* uba_device indeed! */
24234293Skarels struct	buf kdbutab[NKRA];	/* per drive transfer queue */
24334293Skarels 
24434293Skarels u_short kdbstd[] = { 0 };	/* XXX */
24534293Skarels struct uba_driver kdbdriver =	/* XXX */
24634293Skarels  { kdbprobe, kdbslave, kdbattach, 0, kdbstd, DRIVENAMES, kdbdinfo, "kdb" };
24734293Skarels 
24834293Skarels struct	mscp_driver kdbmscpdriver =
24934552Skarels  { MAXUNIT, NKRA, UNITSHIFT, kdbutab, (struct disklabel *)0, kdbdinfo,
25034293Skarels    kdbdgram, kdbctlrdone, kdbunconf, kdbiodone,
25134293Skarels    kdbonline, kdbgotstatus, NULL, kdbioerror, NULL,
25234293Skarels    "kdb", DRIVENAMES };
25334293Skarels 
25434293Skarels /*
25534293Skarels  * Miscellaneous private variables.
25634293Skarels  */
25734293Skarels char	kdbsr_bits[] = KDBSR_BITS;
25834293Skarels 
25934293Skarels struct	uba_device *kdbip[NKDB][MAXUNIT];
26034293Skarels 				/* inverting pointers: ctlr & unit => `Unibus'
26134293Skarels 				   device pointer */
26234293Skarels 
26334293Skarels daddr_t	ra_dsize[NKRA];		/* drive sizes, from on line end packets */
26434293Skarels 
26534293Skarels struct	mscp kdbslavereply;	/* get unit status response packet, set
26634293Skarels 				   for kdbslave by kdbunconf, via kdbintr */
26734293Skarels 
26834293Skarels int	kdbwstart, kdbwatch();	/* watchdog timer */
26934293Skarels int	wakeup();
27034293Skarels 
27134293Skarels /*
27234293Skarels  * If kdbprobe is called, return 0 to keep Unibus code from attempting
27334293Skarels  * to use this device.	XXX rethink
27434293Skarels  */
27534293Skarels /* ARGSUSED */
27634293Skarels kdbprobe(reg, ctlr)
27734293Skarels 	caddr_t reg;
27834293Skarels 	int ctlr;
27934293Skarels {
28034293Skarels 
28134293Skarels 	return (0);
28234293Skarels }
28334293Skarels 
28434293Skarels /*
28534293Skarels  * Configure in a KDB50 controller.
28634293Skarels  */
28734293Skarels kdbconfig(kdbnum, va, pa, vec)
28834293Skarels 	int kdbnum;
28934293Skarels 	struct biiregs *va, *pa;
29034293Skarels 	int vec;
29134293Skarels {
29234293Skarels 	register struct kdbinfo *ki;
29334293Skarels #define mi (&ki->ki_mi)
29434293Skarels 
29534293Skarels #ifdef lint
29634293Skarels 	extern int (*kdbint0[])();
29734293Skarels 
29834293Skarels 	(*kdbint0[0])(0);	/* this is a config botch */
29934293Skarels 	kdbintr(0);
30034293Skarels #endif
30134293Skarels 
30234293Skarels 	/*
30334293Skarels 	 * Set up local KDB status.
30434293Skarels 	 */
30534293Skarels 	ki = &kdbinfo[kdbnum];
30634757Sbostic 	ki->ki_kdb = (struct kdb_regs *)va;
30734757Sbostic 	ki->ki_physkdb = (struct kdb_regs *)pa;
30834293Skarels 	ki->ki_vec = vec;
30934510Skarels 	ki->ki_map =
31034757Sbostic 	    (struct map *)malloc((u_long)(KI_MAPSIZ * sizeof(struct map)),
31134293Skarels 	    M_DEVBUF, M_NOWAIT);
31234757Sbostic 	if (ki->ki_map == NULL) {
31334757Sbostic 		printf("kdb%d: cannot get memory for ptes\n", kdbnum);
31434293Skarels 		return;
31534757Sbostic 	}
31634757Sbostic 	ki->ki_ptephys = PHYS(long, ki->ki_pte); /* kvtophys(ki->ki_pte) */
31734293Skarels 	ki->ki_flags = KDB_ALIVE;
31834293Skarels 
31934757Sbostic 	/* THE FOLLOWING IS ONLY NEEDED TO CIRCUMVENT A BUG IN rminit */
32034757Sbostic 	bzero((caddr_t)ki->ki_map, KI_MAPSIZ * sizeof(struct map));
32134757Sbostic 
32234293Skarels 	rminit(ki->ki_map, (long)KI_PTES, (long)1, "kdb", KI_MAPSIZ);
32334293Skarels 
32434293Skarels 	/*
32534293Skarels 	 * Set up the generic MSCP structures.
32634293Skarels 	 */
32734293Skarels 	mi->mi_md = &kdbmscpdriver;
32834293Skarels 	mi->mi_ctlr = kdbnum;	/* also sets ki->ki_ctlr */
32934293Skarels 	mi->mi_tab = &ki->ki_tab;
33034293Skarels 	mi->mi_ip = kdbip[kdbnum];
33134293Skarels 	mi->mi_cmd.mri_size = NCMD;
33234293Skarels 	mi->mi_cmd.mri_desc = ki->ki_ca.ca_cmddsc;
33334293Skarels 	mi->mi_cmd.mri_ring = ki->ki_cmd;
33434293Skarels 	mi->mi_rsp.mri_size = NRSP;
33534293Skarels 	mi->mi_rsp.mri_desc = ki->ki_ca.ca_rspdsc;
33634293Skarels 	mi->mi_rsp.mri_ring = ki->ki_rsp;
33734293Skarels 	mi->mi_wtab.av_forw = mi->mi_wtab.av_back = &mi->mi_wtab;
33834293Skarels #undef mi
33934293Skarels }
34034293Skarels 
34134293Skarels /*
34234293Skarels  * Find a slave.
34334293Skarels  * Note that by the time kdbslave is called, the interrupt vector
34434293Skarels  * for the KDB50 has been set up (so that kdbunconf() will be called).
34534293Skarels  */
34634293Skarels kdbslave(ui)
34734293Skarels 	register struct uba_device *ui;
34834293Skarels {
34934293Skarels 	register struct kdbinfo *ki;
35034293Skarels 	register struct mscp *mp;
35134293Skarels 	int next = 0, type, timeout, tries, i;
35234293Skarels 
35334293Skarels #ifdef lint
35434293Skarels 	i = 0; i = i;
35534293Skarels #endif
35634293Skarels 	/*
35734293Skarels 	 * Make sure the controller is fully initialised, by waiting
35834293Skarels 	 * for it if necessary.
35934293Skarels 	 */
36034293Skarels 	ki = &kdbinfo[ui->ui_ctlr];
36134293Skarels 	if (ki->ki_state == ST_RUN)
36234293Skarels 		goto findunit;
36334293Skarels 	tries = 0;
36434293Skarels again:
36534293Skarels 	if (kdbinit(ki))
36634293Skarels 		return (0);
36734293Skarels 	timeout = todr() + 1000;		/* 10 seconds */
36834293Skarels 	while (todr() < timeout)
36934293Skarels 		if (ki->ki_state == ST_RUN)	/* made it */
37034293Skarels 			goto findunit;
37134293Skarels 	if (++tries < 2)
37234293Skarels 		goto again;
37334293Skarels 	printf("kdb%d: controller hung\n", ki->ki_ctlr);
37434293Skarels 	return (0);
37534293Skarels 
37634293Skarels 	/*
37734293Skarels 	 * The controller is all set; go find the unit.  Grab an
37834293Skarels 	 * MSCP packet and send out a Get Unit Status command, with
37934293Skarels 	 * the `next unit' modifier if we are looking for a generic
38034293Skarels 	 * unit.  We set the `in slave' flag so that kdbunconf()
38134293Skarels 	 * knows to copy the response to `kdbslavereply'.
38234293Skarels 	 */
38334293Skarels findunit:
38434293Skarels 	kdbslavereply.mscp_opcode = 0;
38534293Skarels 	ki->ki_flags |= KDB_INSLAVE;
38634293Skarels 	if ((mp = mscp_getcp(&ki->ki_mi, MSCP_DONTWAIT)) == NULL)
38734293Skarels 		panic("kdbslave");		/* `cannot happen' */
38834293Skarels 	mp->mscp_opcode = M_OP_GETUNITST;
38934293Skarels 	if (ui->ui_slave == '?') {
39034293Skarels 		mp->mscp_unit = next;
39134293Skarels 		mp->mscp_modifier = M_GUM_NEXTUNIT;
39234293Skarels 	} else {
39334293Skarels 		mp->mscp_unit = ui->ui_slave;
39434293Skarels 		mp->mscp_modifier = 0;
39534293Skarels 	}
39634293Skarels 	*mp->mscp_addr |= MSCP_OWN | MSCP_INT;
39734293Skarels 	i = ki->ki_kdb->kdb_ip;	/* initiate polling */
39834293Skarels 	mp = &kdbslavereply;
39934293Skarels 	timeout = todr() + 1000;
40034293Skarels 	while (todr() < timeout)
40134293Skarels 		if (mp->mscp_opcode)
40234293Skarels 			goto gotit;
40334293Skarels 	printf("kdb%d: no response to Get Unit Status request\n",
40434293Skarels 		ki->ki_ctlr);
40534293Skarels 	ki->ki_flags &= ~KDB_INSLAVE;
40634293Skarels 	return (0);
40734293Skarels 
40834293Skarels gotit:
40934293Skarels 	ki->ki_flags &= ~KDB_INSLAVE;
41034293Skarels 
41134293Skarels 	/*
41234293Skarels 	 * Got a slave response.  If the unit is there, use it.
41334293Skarels 	 */
41434293Skarels 	switch (mp->mscp_status & M_ST_MASK) {
41534293Skarels 
41634293Skarels 	case M_ST_SUCCESS:	/* worked */
41734293Skarels 	case M_ST_AVAILABLE:	/* found another drive */
41834293Skarels 		break;		/* use it */
41934293Skarels 
42034293Skarels 	case M_ST_OFFLINE:
42134293Skarels 		/*
42234293Skarels 		 * Figure out why it is off line.  It may be because
42334293Skarels 		 * it is nonexistent, or because it is spun down, or
42434293Skarels 		 * for some other reason.
42534293Skarels 		 */
42634293Skarels 		switch (mp->mscp_status & ~M_ST_MASK) {
42734293Skarels 
42834293Skarels 		case M_OFFLINE_UNKNOWN:
42934293Skarels 			/*
43034293Skarels 			 * No such drive, and there are none with
43134293Skarels 			 * higher unit numbers either, if we are
43234293Skarels 			 * using M_GUM_NEXTUNIT.
43334293Skarels 			 */
43434293Skarels 			return (0);
43534293Skarels 
43634293Skarels 		case M_OFFLINE_UNMOUNTED:
43734293Skarels 			/*
43834293Skarels 			 * The drive is not spun up.  Use it anyway.
43934293Skarels 			 *
44034293Skarels 			 * N.B.: this seems to be a common occurrance
44134293Skarels 			 * after a power failure.  The first attempt
44234293Skarels 			 * to bring it on line seems to spin it up
44334293Skarels 			 * (and thus takes several minutes).  Perhaps
44434293Skarels 			 * we should note here that the on-line may
44534293Skarels 			 * take longer than usual.
44634293Skarels 			 */
44734293Skarels 			break;
44834293Skarels 
44934293Skarels 		default:
45034293Skarels 			/*
45134293Skarels 			 * In service, or something else equally unusable.
45234293Skarels 			 */
45334757Sbostic 			printf("kdb%d: unit %d off line:", ki->ki_ctlr,
45434293Skarels 				mp->mscp_unit);
45534293Skarels 			mscp_printevent(mp);
45634293Skarels 			goto try_another;
45734293Skarels 		}
45834293Skarels 		break;
45934293Skarels 
46034293Skarels 	default:
46134757Sbostic 		printf("kdb%d: unable to get unit status:", ki->ki_ctlr);
46234293Skarels 		mscp_printevent(mp);
46334293Skarels 		return (0);
46434293Skarels 	}
46534293Skarels 
46634293Skarels 	/*
46734293Skarels 	 * Does this ever happen?  What (if anything) does it mean?
46834293Skarels 	 */
46934293Skarels 	if (mp->mscp_unit < next) {
47034293Skarels 		printf("kdb%d: unit %d, next %d\n",
47134293Skarels 			ki->ki_ctlr, mp->mscp_unit, next);
47234293Skarels 		return (0);
47334293Skarels 	}
47434293Skarels 
47534293Skarels 	if (mp->mscp_unit >= MAXUNIT) {
47634293Skarels 		printf("kdb%d: cannot handle unit number %d (max is %d)\n",
47734293Skarels 			ki->ki_ctlr, mp->mscp_unit, MAXUNIT - 1);
47834293Skarels 		return (0);
47934293Skarels 	}
48034293Skarels 
48134293Skarels 	/*
48234293Skarels 	 * See if we already handle this drive.
48334293Skarels 	 * (Only likely if ui->ui_slave=='?'.)
48434293Skarels 	 */
48534293Skarels 	if (kdbip[ki->ki_ctlr][mp->mscp_unit] != NULL)
48634293Skarels 		goto try_another;
48734293Skarels 
48834293Skarels 	/*
48934293Skarels 	 * Make sure we know about this kind of drive.
49034293Skarels 	 * Others say we should treat unknowns as RA81s; I am
49134293Skarels 	 * not sure this is safe.
49234293Skarels 	 */
49334293Skarels 	type = mp->mscp_guse.guse_drivetype;
49434293Skarels 	if (type >= NTYPES || kdbtypes[type].ut_name == 0) {
49534293Skarels 		register long id = mp->mscp_guse.guse_mediaid;
49634293Skarels 
49734293Skarels 		printf("kdb%d: unit %d: media ID `", ki->ki_ctlr,
49834293Skarels 			mp->mscp_unit);
49934293Skarels 		printf("%c%c %c%c%c%d",
50034293Skarels 			MSCP_MID_CHAR(4, id), MSCP_MID_CHAR(3, id),
50134293Skarels 			MSCP_MID_CHAR(2, id), MSCP_MID_CHAR(1, id),
50234293Skarels 			MSCP_MID_CHAR(0, id), MSCP_MID_NUM(id));
50334293Skarels 		printf("' is of unknown type %d; ignored\n", type);
50434293Skarels try_another:
50534293Skarels 		if (ui->ui_slave != '?')
50634293Skarels 			return (0);
50734293Skarels 		next = mp->mscp_unit + 1;
50834293Skarels 		goto findunit;
50934293Skarels 	}
51034293Skarels 
51134293Skarels 	/*
51234293Skarels 	 * Voila!
51334293Skarels 	 */
51434293Skarels 	ui->ui_type = type;
51534293Skarels 	ui->ui_flags = 0;	/* not on line, nor anything else */
51634293Skarels 	ui->ui_slave = mp->mscp_unit;
51734293Skarels 	return (1);
51834293Skarels }
51934293Skarels 
52034293Skarels /*
52134293Skarels  * Attach a found slave.  Make sure the watchdog timer is running.
522*38171Smckusick  * If this disk is being profiled, fill in the `wpms' value (used by
52334293Skarels  * what?).  Set up the inverting pointer, and attempt to bring the
52434293Skarels  * drive on line.
52534293Skarels  */
52634293Skarels kdbattach(ui)
52734293Skarels 	register struct uba_device *ui;
52834293Skarels {
52934293Skarels 
53034293Skarels 	if (kdbwstart == 0) {
53134757Sbostic 		timeout(kdbwatch, (caddr_t)0, hz);
53234293Skarels 		kdbwstart++;
53334293Skarels 	}
53434293Skarels 	if (ui->ui_dk >= 0)
535*38171Smckusick 		dk_wpms[ui->ui_dk] = (60 * 31 * 256);	/* approx */
53634293Skarels 	kdbip[ui->ui_ctlr][ui->ui_slave] = ui;
53734293Skarels 	(void) kdb_bringonline(ui, 1);
53834293Skarels 	/* should we get its status too? */
53934293Skarels }
54034293Skarels 
54134293Skarels /*
54234293Skarels  * Initialise a KDB50.  Return true iff something goes wrong.
54334293Skarels  */
54434293Skarels kdbinit(ki)
54534293Skarels 	register struct kdbinfo *ki;
54634293Skarels {
54734293Skarels 	register struct kdb_regs *ka = ki->ki_kdb;
54834293Skarels 	int timo;
54934293Skarels 
55034293Skarels 	/*
55134293Skarels 	 * While we are thinking about it, reset the next command
55234293Skarels 	 * and response indicies.
55334293Skarels 	 */
55434293Skarels 	ki->ki_mi.mi_cmd.mri_next = 0;
55534293Skarels 	ki->ki_mi.mi_rsp.mri_next = 0;
55634293Skarels 
55734293Skarels 	/*
55834293Skarels 	 * Start up the hardware initialisation sequence.
55934293Skarels 	 */
56034293Skarels #define	STEP0MASK (KDB_ERR | KDB_STEP4 | KDB_STEP3 | KDB_STEP2 | KDB_STEP1)
56134293Skarels 
56234293Skarels 	ki->ki_state = ST_IDLE;	/* in case init fails */
56334293Skarels 
56434293Skarels 	bi_reset(&ka->kdb_bi);	/* reset bi node (but not the BI itself) */
56534293Skarels 
56634293Skarels 	timo = todr() + 1000;
56734293Skarels 	while ((ka->kdb_sa & STEP0MASK) == 0) {
56834293Skarels 		if (todr() > timo) {
56934293Skarels 			printf("kdb%d: timeout during init\n", ki->ki_ctlr);
57034293Skarels 			return (-1);
57134293Skarels 		}
57234293Skarels 	}
57334293Skarels 	if ((ka->kdb_sa & STEP0MASK) != KDB_STEP1) {
57434293Skarels 		printf("kdb%d: init failed, sa=%b\n", ki->ki_ctlr,
57534293Skarels 			ka->kdb_sa, kdbsr_bits);
57634293Skarels 		return (-1);
57734293Skarels 	}
57834293Skarels 
57934293Skarels 	/*
58034293Skarels 	 * Success!  Record new state, and start step 1 initialisation.
58134293Skarels 	 * The rest is done in the interrupt handler.
58234293Skarels 	 */
58334293Skarels 	ki->ki_state = ST_STEP1;
58434293Skarels 	ka->kdb_bi.bi_intrdes = 1 << mastercpu;
58534293Skarels #ifdef unneeded /* is it? */
58634293Skarels 	ka->kdb_bi.bi_csr = (ka->kdb_bi.bi_csr&~BICSR_ARB_MASK)|BICSR_ARB_???;
58734293Skarels #endif
58834293Skarels 	ka->kdb_bi.bi_bcicsr |= BCI_STOPEN | BCI_IDENTEN | BCI_UINTEN |
58934293Skarels 		BCI_INTEN;
59034293Skarels 
59134293Skarels /* I THINK THIS IS WRONG */
59234293Skarels /* Mach uses 0x601d0, which includes IPL16, but 1d0 is IPL17, nexzvec...? */
59334293Skarels 	ka->kdb_bi.bi_eintrcsr = BIEIC_IPL15 | ki->ki_vec;	/* ??? */
59434293Skarels /* END I THINK WRONG */
59534293Skarels 
59634293Skarels 	ka->kdb_bi.bi_uintrcsr = ki->ki_vec;
59734293Skarels 	ka->kdb_sw = KDB_ERR | (NCMDL2 << 11) | (NRSPL2 << 8) | KDB_IE |
59834293Skarels 		(ki->ki_vec >> 2);
59934293Skarels 	return (0);
60034293Skarels }
60134293Skarels 
60234293Skarels /*
60334293Skarels  * Open a drive.
60434293Skarels  */
60534293Skarels /*ARGSUSED*/
60634293Skarels kdbopen(dev, flag)
60734293Skarels 	dev_t dev;
60834293Skarels 	int flag;
60934293Skarels {
61034293Skarels 	register int unit;
61134293Skarels 	register struct uba_device *ui;
61234293Skarels 	register struct kdbinfo *ki;
61334293Skarels 	int s;
61434293Skarels 
61534293Skarels 	/*
61634293Skarels 	 * Make sure this is a reasonable open request.
61734293Skarels 	 */
61834293Skarels 	unit = kdbunit(dev);
61934293Skarels 	if (unit >= NKRA || (ui = kdbdinfo[unit]) == 0 || ui->ui_alive == 0)
62034293Skarels 		return (ENXIO);
62134293Skarels 
62234293Skarels 	/*
62334293Skarels 	 * Make sure the controller is running, by (re)initialising it if
62434293Skarels 	 * necessary.
62534293Skarels 	 */
62634293Skarels 	ki = &kdbinfo[ui->ui_ctlr];
62734293Skarels 	s = spl5();
62834293Skarels 	if (ki->ki_state != ST_RUN) {
62934293Skarels 		if (ki->ki_state == ST_IDLE && kdbinit(ki)) {
63034293Skarels 			splx(s);
63134293Skarels 			return (EIO);
63234293Skarels 		}
63334293Skarels 		/*
63434293Skarels 		 * In case it does not come up, make sure we will be
63534293Skarels 		 * restarted in 10 seconds.  This corresponds to the
63634293Skarels 		 * 10 second timeouts in kdbprobe() and kdbslave().
63734293Skarels 		 */
63834293Skarels 		ki->ki_flags |= KDB_DOWAKE;
63934757Sbostic 		timeout(wakeup, (caddr_t)&ki->ki_flags, 10 * hz);
64034757Sbostic 		sleep((caddr_t)&ki->ki_flags, PRIBIO);
64134293Skarels 		if (ki->ki_state != ST_RUN) {
64234293Skarels 			splx(s);
64334293Skarels 			printf("kdb%d: controller hung\n", ui->ui_ctlr);
64434293Skarels 			return (EIO);
64534293Skarels 		}
64634757Sbostic 		untimeout(wakeup, (caddr_t)&ki->ki_flags);
64734293Skarels 	}
64834293Skarels 	if ((ui->ui_flags & UNIT_ONLINE) == 0) {
64934293Skarels 		/*
65034293Skarels 		 * Bring the drive on line so we can find out how
65134293Skarels 		 * big it is.  If it is not spun up, it will not
65234293Skarels 		 * come on line; this cannot really be considered
65334293Skarels 		 * an `error condition'.
65434293Skarels 		 */
65534293Skarels 		if (kdb_bringonline(ui, 0)) {
65634293Skarels 			splx(s);
65734293Skarels 			printf("%s%d: drive will not come on line\n",
65834293Skarels 				kdbdriver.ud_dname, unit);
65934293Skarels 			return (EIO);
66034293Skarels 		}
66134293Skarels 	}
66234293Skarels 	splx(s);
66334293Skarels 	return (0);
66434293Skarels }
66534293Skarels 
66634293Skarels /*
66734293Skarels  * Bring a drive on line.  In case it fails to respond, we set
66834293Skarels  * a timeout on it.  The `nosleep' parameter should be set if
66934293Skarels  * we are to spin-wait; otherwise this must be called at spl5().
67034293Skarels  */
67134293Skarels kdb_bringonline(ui, nosleep)
67234293Skarels 	register struct uba_device *ui;
67334293Skarels 	int nosleep;
67434293Skarels {
67534293Skarels 	register struct kdbinfo *ki = &kdbinfo[ui->ui_ctlr];
67634293Skarels 	register struct mscp *mp;
67734293Skarels 	int i;
67834293Skarels 
67934293Skarels 	if (nosleep) {
68034293Skarels 		mp = mscp_getcp(&ki->ki_mi, MSCP_DONTWAIT);
68134293Skarels 		if (mp == NULL)
68234293Skarels 			return (-1);
68334293Skarels 	} else
68434293Skarels 		mp = mscp_getcp(&ki->ki_mi, MSCP_WAIT);
68534293Skarels 	mp->mscp_opcode = M_OP_ONLINE;
68634293Skarels 	mp->mscp_unit = ui->ui_slave;
68734757Sbostic 	mp->mscp_cmdref = (long)&ui->ui_flags;
68834293Skarels 	*mp->mscp_addr |= MSCP_OWN | MSCP_INT;
68934293Skarels 	i = ki->ki_kdb->kdb_ip;
69034293Skarels 
69134293Skarels 	if (nosleep) {
69234293Skarels 		i = todr() + 1000;
69334293Skarels 		while ((ui->ui_flags & UNIT_ONLINE) == 0)
69434293Skarels 			if (todr() > i)
69534293Skarels 				return (-1);
69634293Skarels 	} else {
69734757Sbostic 		timeout(wakeup, (caddr_t)&ui->ui_flags, 10 * hz);
69834757Sbostic 		sleep((caddr_t)&ui->ui_flags, PRIBIO);
69934293Skarels 		if ((ui->ui_flags & UNIT_ONLINE) == 0)
70034293Skarels 			return (-1);
70134757Sbostic 		untimeout(wakeup, (caddr_t)&ui->ui_flags);
70234293Skarels 	}
70334293Skarels 	return (0);	/* made it */
70434293Skarels }
70534293Skarels 
70634293Skarels /*
70734293Skarels  * Queue a transfer request, and if possible, hand it to the controller.
70834293Skarels  *
70934293Skarels  * This routine is broken into two so that the internal version
71034293Skarels  * kdbstrat1() can be called by the (nonexistent, as yet) bad block
71134293Skarels  * revectoring routine.
71234293Skarels  */
71334293Skarels kdbstrategy(bp)
71434293Skarels 	register struct buf *bp;
71534293Skarels {
71634293Skarels 	register int unit;
71734293Skarels 	register struct uba_device *ui;
71834293Skarels 	register struct size *st;
71934293Skarels 	daddr_t sz, maxsz;
72034293Skarels 
72134293Skarels 	/*
72234293Skarels 	 * Make sure this is a reasonable drive to use.
72334293Skarels 	 */
72434293Skarels 	if ((unit = kdbunit(bp->b_dev)) >= NKRA ||
72534293Skarels 	    (ui = kdbdinfo[unit]) == NULL || ui->ui_alive == 0) {
72634293Skarels 		bp->b_error = ENXIO;
72734293Skarels 		bp->b_flags |= B_ERROR;
72834293Skarels 		biodone(bp);
72934293Skarels 		return;
73034293Skarels 	}
73134293Skarels 
73234293Skarels 	/*
73334293Skarels 	 * Determine the size of the transfer, and make sure it is
73434293Skarels 	 * within the boundaries of the drive.
73534293Skarels 	 */
73634293Skarels 	sz = (bp->b_bcount + 511) >> 9;
73734293Skarels 	st = &kdbtypes[ui->ui_type].ut_sizes[kdbpart(bp->b_dev)];
73834293Skarels 	if ((maxsz = st->nblocks) < 0)
73934293Skarels 		maxsz = ra_dsize[unit] - st->blkoff;
74034293Skarels 	if (bp->b_blkno < 0 || bp->b_blkno + sz > maxsz ||
74134293Skarels 	    st->blkoff >= ra_dsize[unit]) {
74234293Skarels 		/* if exactly at end of disk, return an EOF */
74334293Skarels 		if (bp->b_blkno == maxsz)
74434293Skarels 			bp->b_resid = bp->b_bcount;
74534293Skarels 		else {
74634293Skarels 			bp->b_error = EINVAL;
74734293Skarels 			bp->b_flags |= B_ERROR;
74834293Skarels 		}
74934293Skarels 		biodone(bp);
75034293Skarels 		return;
75134293Skarels 	}
75234293Skarels 	kdbstrat1(bp);
75334293Skarels }
75434293Skarels 
75534293Skarels /*
75634293Skarels  * Work routine for kdbstrategy.
75734293Skarels  */
75834293Skarels kdbstrat1(bp)
75934293Skarels 	register struct buf *bp;
76034293Skarels {
76134293Skarels 	register int unit = kdbunit(bp->b_dev);
76234293Skarels 	register struct buf *dp;
76334293Skarels 	register struct kdbinfo *ki;
76434293Skarels 	struct uba_device *ui;
76534293Skarels 	int s;
76634293Skarels 
76734293Skarels 	/*
76834293Skarels 	 * Append the buffer to the drive queue, and if it is not
76934293Skarels 	 * already there, the drive to the controller queue.  (However,
77034293Skarels 	 * if the drive queue is marked to be requeued, we must be
77134293Skarels 	 * awaiting an on line or get unit status command; in this
77234293Skarels 	 * case, leave it off the controller queue.)
77334293Skarels 	 */
77434293Skarels 	ui = kdbdinfo[unit];
77534293Skarels 	ki = &kdbinfo[ui->ui_ctlr];
77634293Skarels 	dp = &kdbutab[unit];
77734293Skarels 	s = spl5();
77834293Skarels 	APPEND(bp, dp, av_forw);
77934293Skarels 	if (dp->b_active == 0 && (ui->ui_flags & UNIT_REQUEUE) == 0) {
78034293Skarels 		APPEND(dp, &ki->ki_tab, b_forw);
78134293Skarels 		dp->b_active++;
78234293Skarels 	}
78334293Skarels 
78434293Skarels 	/*
78534293Skarels 	 * Start activity on the controller.
78634293Skarels 	 */
78734293Skarels 	kdbstart(ki);
78834293Skarels 	splx(s);
78934293Skarels }
79034293Skarels 
79134293Skarels /*
79234293Skarels  * Find the physical address of some contiguous PTEs that map the
79334293Skarels  * transfer described in `bp', creating them (by copying) if
79434293Skarels  * necessary.  Store the physical base address of the map through
79534293Skarels  * mapbase, and the page offset through offset, and any resource
79634293Skarels  * information in *info (or 0 if none).
79734293Skarels  *
79834293Skarels  * If we cannot allocate space, return a nonzero status.
79934293Skarels  */
80034293Skarels int
80134293Skarels kdbmap(ki, bp, mapbase, offset, info)
80234293Skarels 	struct kdbinfo *ki;
80334293Skarels 	register struct buf *bp;
80434293Skarels 	long *mapbase, *offset;
80534293Skarels 	int *info;
80634293Skarels {
80734293Skarels 	register struct pte *spte, *dpte;
80834293Skarels 	register struct proc *rp;
80934293Skarels 	register int i, a, o;
81034293Skarels 	u_int v;
81134293Skarels 	int npf;
81234293Skarels 
81334293Skarels 	o = (int)bp->b_un.b_addr & PGOFSET;
81434293Skarels 
81534293Skarels 	/* handle contiguous cases */
81634293Skarels 	if ((bp->b_flags & B_PHYS) == 0) {
81734293Skarels 		spte = kvtopte(bp->b_un.b_addr);
81834293Skarels 		kdbstats.ks_sys++;
81934293Skarels 		*mapbase = PHYS(long, spte);
82034293Skarels 		*offset = o;
82134293Skarels 		*info = 0;
82234293Skarels 		return (0);
82334293Skarels 	}
82434293Skarels 	if (bp->b_flags & B_PAGET) {
82534293Skarels 		spte = &Usrptmap[btokmx((struct pte *)bp->b_un.b_addr)];
82634293Skarels if (spte->pg_v == 0) panic("kdbmap");
82734293Skarels 		kdbstats.ks_paget++;
82834293Skarels 		*mapbase = PHYS(long, spte);
82934293Skarels 		*offset = o;
83034293Skarels 		*info = 0;
83134293Skarels 		return (0);
83234293Skarels 	}
83334293Skarels 
83434293Skarels 	/* potentially discontiguous or invalid ptes */
83534293Skarels 	v = btop(bp->b_un.b_addr);
83634293Skarels 	rp = bp->b_flags & B_DIRTY ? &proc[2] : bp->b_proc;
83734293Skarels 	if (bp->b_flags & B_UAREA)
83834293Skarels 		spte = &rp->p_addr[v];
83934293Skarels 	else
84034293Skarels 		spte = vtopte(rp, v);
84134293Skarels 	npf = btoc(bp->b_bcount + o);
84234293Skarels 
84334293Skarels #ifdef notdef
84434293Skarels 	/*
84534293Skarels 	 * The current implementation of the VM system requires
84634293Skarels 	 * that all of these be done with a copy.  Even if the
84734293Skarels 	 * PTEs could be used now, they may be snatched out from
84834293Skarels 	 * under us later.  It would be nice if we could stop that....
84934293Skarels 	 */
85034293Skarels 
85134293Skarels 	/* check for invalid */
85234293Skarels 	/* CONSIDER CHANGING VM TO VALIDATE PAGES EARLIER */
85334293Skarels 	for (dpte = spte, i = npf; --i >= 0; dpte++)
85434293Skarels 		if (dpte->pg_v == 0)
85534293Skarels 			goto copy1;
85634293Skarels 	/*
85734293Skarels 	 * Check for discontiguous physical pte addresses.  It is
85834293Skarels 	 * not necessary to check each pte, since they come in clumps
85934293Skarels 	 * of pages.
86034293Skarels 	 */
86134293Skarels 	i = howmany(npf + (((int)spte & PGOFSET) / sizeof (*spte)), NPTEPG);
86234293Skarels 	/* often i==1, and we can avoid work */
86334293Skarels 	if (--i > 0) {
86434293Skarels 		dpte = kvtopte(spte);
86534293Skarels 		a = dpte->pg_pfnum;
86634293Skarels 		while (--i >= 0)
86734293Skarels 			if ((++dpte)->pg_pfnum != ++a)
86834293Skarels 				goto copy2;
86934293Skarels 	}
87034293Skarels 
87134293Skarels 	/* made it */
87234293Skarels 	kdbstats.ks_contig++;
87334293Skarels 	*mapbase = kvtophys(spte);
87434293Skarels 	*offset = o;
87534293Skarels 	*info = 0;
87634293Skarels 	return (0);
87734293Skarels 
87834293Skarels copy1:
87934293Skarels 	kdbstats.ks_inval++;		/* temp */
88034293Skarels copy2:
88134293Skarels #endif /* notdef */
88234293Skarels 	kdbstats.ks_copies++;
88334293Skarels 	i = npf + 1;
88434757Sbostic 	if ((a = rmalloc(ki->ki_map, (long)i)) == 0) {
88534293Skarels 		kdbstats.ks_mapwait++;
88634293Skarels 		return (-1);
88734293Skarels 	}
88834293Skarels 	*info = (i << 16) | a;
88934293Skarels 	a--;
89034293Skarels 	/* if offset > PGOFSET, btop(offset) indexes mapbase */
89134293Skarels 	*mapbase = ki->ki_ptephys;
89234293Skarels 	*offset = (a << PGSHIFT) | o;
89334293Skarels 	dpte = &ki->ki_pte[a];
89434293Skarels 	while (--i > 0)
89534293Skarels 		*(int *)dpte++ = PG_V | *(int *)spte++;
89634293Skarels 	*(int *)dpte = 0;
89734293Skarels 	return (0);
89834293Skarels }
89934293Skarels 
90034293Skarels #define	KDBFREE(ki, info) if (info) \
90134293Skarels 	rmfree((ki)->ki_map, (long)((info) >> 16), (long)((info) & 0xffff))
90234293Skarels 
90334293Skarels /*
90434293Skarels  * Start up whatever transfers we can find.
90534293Skarels  * Note that kdbstart() must be called at spl5().
90634293Skarels  */
90734293Skarels kdbstart(ki)
90834293Skarels 	register struct kdbinfo *ki;
90934293Skarels {
91034293Skarels 	register struct buf *bp, *dp;
91134293Skarels 	register struct mscp *mp;
91234293Skarels 	register struct uba_device *ui;
91334293Skarels 	long mapbase, offset;
91434293Skarels 	int info, ncmd = 0;
91534293Skarels 
91634293Skarels 	/*
91734293Skarels 	 * If it is not running, try (again and again...) to initialise
91834293Skarels 	 * it.  If it is currently initialising just ignore it for now.
91934293Skarels 	 */
92034293Skarels 	if (ki->ki_state != ST_RUN) {
92134293Skarels 		if (ki->ki_state == ST_IDLE && kdbinit(ki))
92234293Skarels 			printf("kdb%d: still hung\n", ki->ki_ctlr);
92334293Skarels 		return;
92434293Skarels 	}
92534293Skarels 
92634293Skarels loop:
92734293Skarels 	/* if insufficient credit, avoid overhead */
92834293Skarels 	if (ki->ki_mi.mi_credits <= MSCP_MINCREDITS)
92934293Skarels 		goto out;
93034293Skarels 
93134293Skarels 	/*
93234757Sbostic 	 * Service the drive at the head of the queue.  It may not
93334757Sbostic 	 * need anything; eventually this will finish up the close
93434757Sbostic 	 * protocol, but that is yet to be implemented here.
93534293Skarels 	 */
93634293Skarels 	if ((dp = ki->ki_tab.b_actf) == NULL)
93734293Skarels 		goto out;
93834757Sbostic 	if ((bp = dp->b_actf) == NULL) {
93934757Sbostic 		dp->b_active = 0;
94034757Sbostic 		ki->ki_tab.b_actf = dp->b_forw;
94134757Sbostic 		goto loop;
94234757Sbostic 	}
94334293Skarels 
94434293Skarels 	if (ki->ki_kdb->kdb_sa & KDB_ERR) {	/* ctlr fatal error */
94534293Skarels 		kdbsaerror(ki);
94634293Skarels 		goto out;
94734293Skarels 	}
94834293Skarels 
94934293Skarels 	 /* find or create maps for this transfer */
95034293Skarels 	 if (kdbmap(ki, bp, &mapbase, &offset, &info))
95134293Skarels 		goto out;	/* effectively, resource wait */
95234293Skarels 
95334293Skarels 	/*
95434293Skarels 	 * Get an MSCP packet, then figure out what to do.  If
95534293Skarels 	 * we cannot get a command packet, the command ring may
95634293Skarels 	 * be too small:  We should have at least as many command
95734293Skarels 	 * packets as credits, for best performance.
95834293Skarels 	 */
95934293Skarels 	if ((mp = mscp_getcp(&ki->ki_mi, MSCP_DONTWAIT)) == NULL) {
96034293Skarels 		if (ki->ki_mi.mi_credits > MSCP_MINCREDITS &&
96134293Skarels 		    (ki->ki_flags & KDB_GRIPED) == 0) {
96234293Skarels 			log(LOG_NOTICE, "kdb%d: command ring too small\n",
96334293Skarels 				ki->ki_ctlr);
96434293Skarels 			ki->ki_flags |= KDB_GRIPED;/* complain only once */
96534293Skarels 		}
96634293Skarels 		KDBFREE(ki, info);
96734293Skarels 		goto out;
96834293Skarels 	}
96934293Skarels 
97034293Skarels 	/*
97134293Skarels 	 * Bring the drive on line if it is not already.  Get its status
97234293Skarels 	 * if we do not already have it.  Otherwise just start the transfer.
97334293Skarels 	 */
97434293Skarels 	ui = kdbdinfo[kdbunit(bp->b_dev)];
97534293Skarels 	if ((ui->ui_flags & UNIT_ONLINE) == 0) {
97634293Skarels 		mp->mscp_opcode = M_OP_ONLINE;
97734293Skarels 		goto common;
97834293Skarels 	}
97934293Skarels 	if ((ui->ui_flags & UNIT_HAVESTATUS) == 0) {
98034293Skarels 		mp->mscp_opcode = M_OP_GETUNITST;
98134293Skarels common:
98234293Skarels if (ui->ui_flags & UNIT_REQUEUE) panic("kdbstart");
98334293Skarels 		/*
98434293Skarels 		 * Take the drive off the controller queue.  When the
98534293Skarels 		 * command finishes, make sure the drive is requeued.
98634293Skarels 		 * Give up any mapping (not needed now).  This last is
98734293Skarels 		 * not efficient, but is rare.
98834293Skarels 		 */
98934293Skarels 		KDBFREE(ki, info);
99034293Skarels 		ki->ki_tab.b_actf = dp->b_forw;
99134293Skarels 		dp->b_active = 0;
99234293Skarels 		ui->ui_flags |= UNIT_REQUEUE;
99334293Skarels 		mp->mscp_unit = ui->ui_slave;
99434293Skarels 		*mp->mscp_addr |= MSCP_OWN | MSCP_INT;
99534293Skarels 		ncmd++;
99634293Skarels 		goto loop;
99734293Skarels 	}
99834293Skarels 
99934293Skarels 	mp->mscp_opcode = (bp->b_flags & B_READ) ? M_OP_READ : M_OP_WRITE;
100034293Skarels 	mp->mscp_unit = ui->ui_slave;
100134293Skarels 	mp->mscp_seq.seq_lbn = bp->b_blkno +
100234293Skarels 		kdbtypes[ui->ui_type].ut_sizes[kdbpart(bp->b_dev)].blkoff;
100334293Skarels 	mp->mscp_seq.seq_bytecount = bp->b_bcount;
100434293Skarels 
100534293Skarels 	mp->mscp_seq.seq_buffer = offset | KDB_MAP;
100634293Skarels 	mp->mscp_seq.seq_mapbase = mapbase;
100734293Skarels 
100834293Skarels 	/* profile the drive */
100934293Skarels 	if (ui->ui_dk >= 0) {
101034293Skarels 		dk_busy |= 1 << ui->ui_dk;
101134293Skarels 		dk_xfer[ui->ui_dk]++;
101234293Skarels 		dk_wds[ui->ui_dk] += bp->b_bcount >> 6;
101334293Skarels 	}
101434293Skarels 
101534293Skarels 	/*
101634293Skarels 	 * Fill in the rest of the MSCP packet and move the buffer to the
101734293Skarels 	 * I/O wait queue.
101834293Skarels 	 */
101934293Skarels 	mscp_go(&ki->ki_mi, mp, info);
102034293Skarels 	ncmd++;			/* note the transfer */
102134293Skarels 	ki->ki_tab.b_active++;	/* another one going */
102234293Skarels 	goto loop;
102334293Skarels 
102434293Skarels out:
102534293Skarels 	if (ncmd >= KS_MAXC)
102634293Skarels 		ncmd = KS_MAXC - 1;
102734293Skarels 	kdbstats.ks_cmd[ncmd]++;
102834293Skarels 	if (ncmd)		/* start some transfers */
102934293Skarels 		ncmd = ki->ki_kdb->kdb_ip;
103034293Skarels }
103134293Skarels 
103234293Skarels /* ARGSUSED */
103334293Skarels kdbiodone(mi, bp, info)
103434293Skarels 	struct mscp_info *mi;
103534293Skarels 	struct buf *bp;
103634293Skarels 	int info;
103734293Skarels {
103834293Skarels 	register struct kdbinfo *ki = &kdbinfo[mi->mi_ctlr];
103934293Skarels 
104034293Skarels 	KDBFREE(ki, info);
104134293Skarels 	biodone(bp);
104234293Skarels 	ki->ki_tab.b_active--;	/* another one done */
104334293Skarels }
104434293Skarels 
104534293Skarels /*
104634293Skarels  * The error bit was set in the controller status register.  Gripe,
104734293Skarels  * reset the controller, requeue pending transfers.
104834293Skarels  */
104934293Skarels kdbsaerror(ki)
105034293Skarels 	register struct kdbinfo *ki;
105134293Skarels {
105234293Skarels 
105334293Skarels 	printf("kdb%d: controller error, sa=%b\n", ki->ki_ctlr,
105434293Skarels 		ki->ki_kdb->kdb_sa, kdbsr_bits);
105534293Skarels 	mscp_requeue(&ki->ki_mi);
105634293Skarels 	(void) kdbinit(ki);
105734293Skarels }
105834293Skarels 
105934293Skarels /*
106034293Skarels  * Interrupt routine.  Depending on the state of the controller,
106134293Skarels  * continue initialisation, or acknowledge command and response
106234293Skarels  * interrupts, and process responses.
106334293Skarels  */
106434293Skarels kdbintr(ctlr)
106534293Skarels 	int ctlr;
106634293Skarels {
106734293Skarels 	register struct kdbinfo *ki = &kdbinfo[ctlr];
106834293Skarels 	register struct kdb_regs *kdbaddr = ki->ki_kdb;
106934293Skarels 	register struct mscp *mp;
107034293Skarels 	register int i;
107134293Skarels 
107234293Skarels 	ki->ki_wticks = 0;	/* reset interrupt watchdog */
107334293Skarels 
107434293Skarels 	/*
107534293Skarels 	 * Combinations during steps 1, 2, and 3: STEPnMASK
107634293Skarels 	 * corresponds to which bits should be tested;
107734293Skarels 	 * STEPnGOOD corresponds to the pattern that should
107834293Skarels 	 * appear after the interrupt from STEPn initialisation.
107934293Skarels 	 * All steps test the bits in ALLSTEPS.
108034293Skarels 	 */
108134293Skarels #define	ALLSTEPS	(KDB_ERR|KDB_STEP4|KDB_STEP3|KDB_STEP2|KDB_STEP1)
108234293Skarels 
108334293Skarels #define	STEP1MASK	(ALLSTEPS | KDB_IE | KDB_NCNRMASK)
108434293Skarels #define	STEP1GOOD	(KDB_STEP2 | KDB_IE | (NCMDL2 << 3) | NRSPL2)
108534293Skarels 
108634293Skarels #define	STEP2MASK	(ALLSTEPS | KDB_IE | KDB_IVECMASK)
108734293Skarels #define	STEP2GOOD	(KDB_STEP3 | KDB_IE | (ki->ki_vec >> 2))
108834293Skarels 
108934293Skarels #define	STEP3MASK	ALLSTEPS
109034293Skarels #define	STEP3GOOD	KDB_STEP4
109134293Skarels 
109234293Skarels 	switch (ki->ki_state) {
109334293Skarels 
109434293Skarels 	case ST_IDLE:
109534293Skarels 		/*
109634293Skarels 		 * Ignore unsolicited interrupts.
109734293Skarels 		 */
109834293Skarels 		log(LOG_WARNING, "kdb%d: stray intr\n", ctlr);
109934293Skarels 		return;
110034293Skarels 
110134293Skarels 	case ST_STEP1:
110234293Skarels 		/*
110334293Skarels 		 * Begin step two initialisation.
110434293Skarels 		 */
110534293Skarels 		if ((kdbaddr->kdb_sa & STEP1MASK) != STEP1GOOD) {
110634293Skarels 			i = 1;
110734293Skarels initfailed:
110834293Skarels 			printf("kdb%d: init step %d failed, sa=%b\n",
110934293Skarels 				ctlr, i, kdbaddr->kdb_sa, kdbsr_bits);
111034293Skarels 			ki->ki_state = ST_IDLE;
111134293Skarels 			if (ki->ki_flags & KDB_DOWAKE) {
111234293Skarels 				ki->ki_flags &= ~KDB_DOWAKE;
111334757Sbostic 				wakeup((caddr_t)&ki->ki_flags);
111434293Skarels 			}
111534293Skarels 			return;
111634293Skarels 		}
111734293Skarels 		kdbaddr->kdb_sw = PHYS(int, &ki->ki_ca.ca_rspdsc[0]);
111834293Skarels 		ki->ki_state = ST_STEP2;
111934293Skarels 		return;
112034293Skarels 
112134293Skarels 	case ST_STEP2:
112234293Skarels 		/*
112334293Skarels 		 * Begin step 3 initialisation.
112434293Skarels 		 */
112534293Skarels 		if ((kdbaddr->kdb_sa & STEP2MASK) != STEP2GOOD) {
112634293Skarels 			i = 2;
112734293Skarels 			goto initfailed;
112834293Skarels 		}
112934293Skarels 		kdbaddr->kdb_sw = PHYS(int, &ki->ki_ca.ca_rspdsc[0]) >> 16;
113034293Skarels 		ki->ki_state = ST_STEP3;
113134293Skarels 		return;
113234293Skarels 
113334293Skarels 	case ST_STEP3:
113434293Skarels 		/*
113534293Skarels 		 * Set controller characteristics (finish initialisation).
113634293Skarels 		 */
113734293Skarels 		if ((kdbaddr->kdb_sa & STEP3MASK) != STEP3GOOD) {
113834293Skarels 			i = 3;
113934293Skarels 			goto initfailed;
114034293Skarels 		}
114134293Skarels 		i = kdbaddr->kdb_sa & 0xff;
114234293Skarels 		if (i != ki->ki_micro) {
114334293Skarels 			ki->ki_micro = i;
114434293Skarels 			printf("kdb%d: version %d model %d\n",
114534293Skarels 				ctlr, i & 0xf, i >> 4);
114634293Skarels 		}
114734293Skarels 
114834293Skarels 		kdbaddr->kdb_sw = KDB_GO;
114934293Skarels 
115034293Skarels 		/* initialise hardware data structures */
115134293Skarels 		for (i = 0, mp = ki->ki_rsp; i < NRSP; i++, mp++) {
115234293Skarels 			ki->ki_ca.ca_rspdsc[i] = MSCP_OWN | MSCP_INT |
115334293Skarels 				PHYS(long, &ki->ki_rsp[i].mscp_cmdref);
115434293Skarels 			mp->mscp_addr = &ki->ki_ca.ca_rspdsc[i];
115534293Skarels 			mp->mscp_msglen = MSCP_MSGLEN;
115634293Skarels 		}
115734293Skarels 		for (i = 0, mp = ki->ki_cmd; i < NCMD; i++, mp++) {
115834293Skarels 			ki->ki_ca.ca_cmddsc[i] = MSCP_INT |
115934293Skarels 				PHYS(long, &ki->ki_cmd[i].mscp_cmdref);
116034293Skarels 			mp->mscp_addr = &ki->ki_ca.ca_cmddsc[i];
116134293Skarels 			mp->mscp_msglen = MSCP_MSGLEN;
116234293Skarels 		}
116334293Skarels 
116434293Skarels 		/*
116534293Skarels 		 * Before we can get a command packet, we need some
116634293Skarels 		 * credits.  Fake some up to keep mscp_getcp() happy,
116734293Skarels 		 * get a packet, and cancel all credits (the right
116834293Skarels 		 * number should come back in the response to the
116934293Skarels 		 * SCC packet).
117034293Skarels 		 */
117134293Skarels 		ki->ki_mi.mi_credits = MSCP_MINCREDITS + 1;
117234293Skarels 		mp = mscp_getcp(&ki->ki_mi, MSCP_DONTWAIT);
117334293Skarels 		if (mp == NULL)	/* `cannot happen' */
117434293Skarels 			panic("kdbintr");
117534293Skarels 		ki->ki_mi.mi_credits = 0;
117634293Skarels 		mp->mscp_opcode = M_OP_SETCTLRC;
117734293Skarels 		mp->mscp_unit = 0;
117834293Skarels 		mp->mscp_sccc.sccc_ctlrflags = M_CF_ATTN | M_CF_MISC |
117934293Skarels 			M_CF_THIS;
118034293Skarels 		*mp->mscp_addr |= MSCP_OWN | MSCP_INT;
118134293Skarels 		i = kdbaddr->kdb_ip;
118234293Skarels 		ki->ki_state = ST_SETCHAR;
118334293Skarels 		return;
118434293Skarels 
118534293Skarels 	case ST_SETCHAR:
118634293Skarels 	case ST_RUN:
118734293Skarels 		/*
118834293Skarels 		 * Handle Set Ctlr Characteristics responses and operational
118934293Skarels 		 * responses (via mscp_dorsp).
119034293Skarels 		 */
119134293Skarels 		break;
119234293Skarels 
119334293Skarels 	default:
119434293Skarels 		log(LOG_ERR, "kdb%d: driver bug, state %d\n", ctlr,
119534293Skarels 			ki->ki_state);
119634293Skarels 		return;
119734293Skarels 	}
119834293Skarels 
119934293Skarels 	if (kdbaddr->kdb_sa & KDB_ERR) {/* ctlr fatal error */
120034293Skarels 		kdbsaerror(ki);
120134293Skarels 		return;
120234293Skarels 	}
120334293Skarels 
120434293Skarels 	/*
120534293Skarels 	 * Handle buffer purge requests.
120634293Skarels 	 * KDB DOES NOT HAVE BDPs
120734293Skarels 	 */
120834293Skarels 	if (ki->ki_ca.ca_bdp) {
120934293Skarels 		printf("kdb%d: purge bdp %d\n", ctlr, ki->ki_ca.ca_bdp);
121034293Skarels 		panic("kdb purge");
121134293Skarels 	}
121234293Skarels 
121334293Skarels 	/*
121434293Skarels 	 * Check for response and command ring transitions.
121534293Skarels 	 */
121634293Skarels 	if (ki->ki_ca.ca_rspint) {
121734293Skarels 		ki->ki_ca.ca_rspint = 0;
121834293Skarels 		mscp_dorsp(&ki->ki_mi);
121934293Skarels 	}
122034293Skarels 	if (ki->ki_ca.ca_cmdint) {
122134293Skarels 		ki->ki_ca.ca_cmdint = 0;
122234293Skarels 		MSCP_DOCMD(&ki->ki_mi);
122334293Skarels 	}
122434293Skarels 	if (ki->ki_tab.b_actf != NULL)
122534293Skarels 		kdbstart(ki);
122634293Skarels }
122734293Skarels 
122834293Skarels /*
122934293Skarels  * Handle an error datagram.  All we do now is decode it.
123034293Skarels  */
123134293Skarels kdbdgram(mi, mp)
123234293Skarels 	struct mscp_info *mi;
123334293Skarels 	struct mscp *mp;
123434293Skarels {
123534293Skarels 
123634293Skarels 	mscp_decodeerror(mi->mi_md->md_mname, mi->mi_ctlr, mp);
123734293Skarels }
123834293Skarels 
123934293Skarels /*
124034293Skarels  * The Set Controller Characteristics command finished.
124134293Skarels  * Record the new state of the controller.
124234293Skarels  */
124334293Skarels kdbctlrdone(mi, mp)
124434293Skarels 	struct mscp_info *mi;
124534293Skarels 	struct mscp *mp;
124634293Skarels {
124734293Skarels 	register struct kdbinfo *ki = &kdbinfo[mi->mi_ctlr];
124834293Skarels 
124934293Skarels 	if ((mp->mscp_status & M_ST_MASK) == M_ST_SUCCESS)
125034293Skarels 		ki->ki_state = ST_RUN;
125134293Skarels 	else {
125234293Skarels 		printf("kdb%d: SETCTLRC failed, status 0x%x\n",
125334293Skarels 			ki->ki_ctlr, mp->mscp_status);
125434293Skarels 		ki->ki_state = ST_IDLE;
125534293Skarels 	}
125634293Skarels 	if (ki->ki_flags & KDB_DOWAKE) {
125734293Skarels 		ki->ki_flags &= ~KDB_DOWAKE;
125834757Sbostic 		wakeup((caddr_t)&ki->ki_flags);
125934293Skarels 	}
126034293Skarels }
126134293Skarels 
126234293Skarels /*
126334293Skarels  * Received a response from an as-yet unconfigured drive.  Configure it
126434293Skarels  * in, if possible.
126534293Skarels  */
126634293Skarels kdbunconf(mi, mp)
126734293Skarels 	struct mscp_info *mi;
126834293Skarels 	register struct mscp *mp;
126934293Skarels {
127034293Skarels 
127134293Skarels 	/*
127234293Skarels 	 * If it is a slave response, copy it to kdbslavereply for
127334293Skarels 	 * kdbslave() to look at.
127434293Skarels 	 */
127534293Skarels 	if (mp->mscp_opcode == (M_OP_GETUNITST | M_OP_END) &&
127634293Skarels 	    (kdbinfo[mi->mi_ctlr].ki_flags & KDB_INSLAVE) != 0) {
127734293Skarels 		kdbslavereply = *mp;
127834293Skarels 		return (MSCP_DONE);
127934293Skarels 	}
128034293Skarels 
128134293Skarels 	/*
128234293Skarels 	 * Otherwise, it had better be an available attention response.
128334293Skarels 	 */
128434293Skarels 	if (mp->mscp_opcode != M_OP_AVAILATTN)
128534293Skarels 		return (MSCP_FAILED);
128634293Skarels 
128734293Skarels 	/* do what autoconf does */
128834293Skarels 	return (MSCP_FAILED);	/* not yet */
128934293Skarels }
129034293Skarels 
129134293Skarels /*
129234293Skarels  * A drive came on line.  Check its type and size.  Return DONE if
129334293Skarels  * we think the drive is truly on line.  In any case, awaken anyone
129434293Skarels  * sleeping on the drive on-line-ness.
129534293Skarels  */
129634293Skarels kdbonline(ui, mp)
129734293Skarels 	register struct uba_device *ui;
129834293Skarels 	struct mscp *mp;
129934293Skarels {
130034293Skarels 	register int type;
130134293Skarels 
130234757Sbostic 	wakeup((caddr_t)&ui->ui_flags);
130334293Skarels 	if ((mp->mscp_status & M_ST_MASK) != M_ST_SUCCESS) {
130434757Sbostic 		printf("kdb%d: attempt to bring %s%d on line failed:",
130534293Skarels 			ui->ui_ctlr, kdbdriver.ud_dname, ui->ui_unit);
130634293Skarels 		mscp_printevent(mp);
130734293Skarels 		return (MSCP_FAILED);
130834293Skarels 	}
130934293Skarels 
131034293Skarels 	type = mp->mscp_onle.onle_drivetype;
131134293Skarels 	if (type >= NTYPES || kdbtypes[type].ut_name == 0) {
131234293Skarels 		printf("kdb%d: %s%d: unknown type %d\n",
131334293Skarels 			ui->ui_ctlr, kdbdriver.ud_dname, ui->ui_unit, type);
131434293Skarels 		return (MSCP_FAILED);
131534293Skarels 	}
131634293Skarels 	/*
131734293Skarels 	 * Note any change of types.  Not sure if we should do
131834293Skarels 	 * something special about them, or if so, what....
131934293Skarels 	 */
132034293Skarels 	if (type != ui->ui_type) {
132134293Skarels 		printf("%s%d: changed types! was %s\n",
132234293Skarels 			kdbdriver.ud_dname, ui->ui_unit,
132334293Skarels 			kdbtypes[ui->ui_type].ut_name);
132434293Skarels 		ui->ui_type = type;
132534293Skarels 	}
132634293Skarels 	ra_dsize[ui->ui_unit] = (daddr_t) mp->mscp_onle.onle_unitsize;
132734293Skarels 	printf("%s%d: %s, size = %d sectors\n",
132834293Skarels 		kdbdriver.ud_dname, ui->ui_unit,
132934293Skarels 		kdbtypes[type].ut_name, ra_dsize[ui->ui_unit]);
133034293Skarels 	return (MSCP_DONE);
133134293Skarels }
133234293Skarels 
133334293Skarels /*
133434293Skarels  * We got some (configured) unit's status.  Return DONE if it succeeded.
133534293Skarels  */
133634293Skarels kdbgotstatus(ui, mp)
133734293Skarels 	register struct uba_device *ui;
133834293Skarels 	register struct mscp *mp;
133934293Skarels {
134034293Skarels 
134134293Skarels 	if ((mp->mscp_status & M_ST_MASK) != M_ST_SUCCESS) {
134234757Sbostic 		printf("kdb%d: attempt to get status for %s%d failed:",
134334293Skarels 			ui->ui_ctlr, kdbdriver.ud_dname, ui->ui_unit);
134434293Skarels 		mscp_printevent(mp);
134534293Skarels 		return (MSCP_FAILED);
134634293Skarels 	}
134734293Skarels 	/* need to record later for bad block forwarding - for now, print */
134834293Skarels 	printf("\
134934293Skarels %s%d: unit %d, nspt %d, group %d, ngpc %d, rctsize %d, nrpt %d, nrct %d\n",
135034293Skarels 		kdbdriver.ud_dname, ui->ui_unit, mp->mscp_unit,
135134293Skarels 		mp->mscp_guse.guse_nspt, mp->mscp_guse.guse_group,
135234293Skarels 		mp->mscp_guse.guse_ngpc, mp->mscp_guse.guse_rctsize,
135334293Skarels 		mp->mscp_guse.guse_nrpt, mp->mscp_guse.guse_nrct);
135434293Skarels 	return (MSCP_DONE);
135534293Skarels }
135634293Skarels 
135734293Skarels /*
135834293Skarels  * A transfer failed.  We get a chance to fix or restart it.
135934293Skarels  * Need to write the bad block forwaring code first....
136034293Skarels  */
136134293Skarels /*ARGSUSED*/
136234293Skarels kdbioerror(ui, mp, bp)
136334293Skarels 	register struct uba_device *ui;
136434293Skarels 	register struct mscp *mp;
136534293Skarels 	struct buf *bp;
136634293Skarels {
136734293Skarels 
136834293Skarels 	if (mp->mscp_flags & M_EF_BBLKR) {
136934293Skarels 		/*
137034293Skarels 		 * A bad block report.  Eventually we will
137134293Skarels 		 * restart this transfer, but for now, just
137234293Skarels 		 * log it and give up.
137334293Skarels 		 */
137434293Skarels 		log(LOG_ERR, "%s%d: bad block report: %d%s\n",
137534293Skarels 			kdbdriver.ud_dname, ui->ui_unit, mp->mscp_seq.seq_lbn,
137634293Skarels 			mp->mscp_flags & M_EF_BBLKU ? " + others" : "");
137734293Skarels 	} else {
137834293Skarels 		/*
137934293Skarels 		 * What the heck IS a `serious exception' anyway?
138034293Skarels 		 */
138134293Skarels 		if (mp->mscp_flags & M_EF_SEREX)
138234293Skarels 			log(LOG_ERR, "%s%d: serious exception reported\n",
138334293Skarels 				kdbdriver.ud_dname, ui->ui_unit);
138434293Skarels 	}
138534293Skarels 	return (MSCP_FAILED);
138634293Skarels }
138734293Skarels 
138834293Skarels 
138934293Skarels #ifdef notyet
139034293Skarels /*
139134293Skarels  * I/O controls.  Not yet!
139234293Skarels  */
139334293Skarels kdbioctl(dev, cmd, flag, data)
139434293Skarels 	dev_t dev;
139534293Skarels 	int cmd, flag;
139634293Skarels 	caddr_t data;
139734293Skarels {
139834293Skarels 	int error = 0;
139934293Skarels 	register int unit = kdbunit(dev);
140034293Skarels 
140134293Skarels 	if (unit >= NKRA || uddinfo[unit] == NULL)
140234293Skarels 		return (ENXIO);
140334293Skarels 
140434293Skarels 	switch (cmd) {
140534293Skarels 
140634293Skarels 	case KDBIOCREPLACE:
140734293Skarels 		/*
140834293Skarels 		 * Initiate bad block replacement for the given LBN.
140934293Skarels 		 * (Should we allow modifiers?)
141034293Skarels 		 */
141134293Skarels 		error = EOPNOTSUPP;
141234293Skarels 		break;
141334293Skarels 
141434293Skarels 	case KDBIOCGMICRO:
141534293Skarels 		/*
141634293Skarels 		 * Return the microcode revision for the KDB50 running
141734293Skarels 		 * this drive.
141834293Skarels 		 */
141934757Sbostic 		*(int *)data = kdbinfo[kdbdinfo[unit]->ui_ctlr].ki_micro;
142034293Skarels 		break;
142134293Skarels 
142234293Skarels 	case KDBIOCGSIZE:
142334293Skarels 		/*
142434293Skarels 		 * Return the size (in 512 byte blocks) of this
142534293Skarels 		 * disk drive.
142634293Skarels 		 */
142734757Sbostic 		*(daddr_t *)data = ra_dsize[unit];
142834293Skarels 		break;
142934293Skarels 
143034293Skarels 	default:
143134293Skarels 		error = EINVAL;
143234293Skarels 		break;
143334293Skarels 	}
143434293Skarels 	return (error);
143534293Skarels }
143634293Skarels #endif
143734293Skarels 
143834293Skarels #ifdef notyet
143934293Skarels /*
144034293Skarels  * Reset a KDB50 (self test and all).
144134293Skarels  * What if it fails?
144234293Skarels  */
144334293Skarels kdbreset(ki)
144434293Skarels 	register struct kdbinfo *ki;
144534293Skarels {
144634293Skarels 
144734293Skarels 	printf("reset kdb%d", ki->ki_ctlr);
144834293Skarels 	bi_selftest(&ki->ki_kdb.kdb_bi);
144934293Skarels 	ki->ki_state = ST_IDLE;
145034293Skarels 	rminit(ki->ki_map, (long)KI_PTES, (long)1, "kdb", KI_MAPSIZ);
145134293Skarels 	mscp_requeue(&ki->ki_mi);
145234293Skarels 	if (kdbinit(ctlr))
145334293Skarels 		printf(" (hung)");
145434293Skarels 	printf("\n");
145534293Skarels }
145634293Skarels #endif
145734293Skarels 
145834293Skarels /*
145934293Skarels  * Watchdog timer:  If the controller is active, and no interrupts
146034293Skarels  * have occurred for 30 seconds, assume it has gone away.
146134293Skarels  */
146234293Skarels kdbwatch()
146334293Skarels {
146434293Skarels 	register struct kdbinfo *ki;
146534293Skarels 	register int i;
146634293Skarels 
146734757Sbostic 	timeout(kdbwatch, (caddr_t)0, hz);	/* every second */
146834293Skarels 	for (i = 0, ki = kdbinfo; i < NKDB; i++, ki++) {
146934293Skarels 		if ((ki->ki_flags & KDB_ALIVE) == 0)
147034293Skarels 			continue;
147134293Skarels 		if (ki->ki_state == ST_IDLE)
147234293Skarels 			continue;
147334293Skarels 		if (ki->ki_state == ST_RUN && !ki->ki_tab.b_active)
147434293Skarels 			ki->ki_wticks = 0;
147534293Skarels 		else if (++ki->ki_wticks >= 30) {
147634293Skarels 			ki->ki_wticks = 0;
147734293Skarels 			printf("kdb%d: lost interrupt\n", i);
147834293Skarels 			/* kdbreset(ki); */
147934293Skarels 			panic("kdb lost interrupt");
148034293Skarels 		}
148134293Skarels 	}
148234293Skarels }
148334293Skarels 
148434293Skarels /*
148534293Skarels  * Do a panic dump.
148634293Skarels  */
148734293Skarels #define	DBSIZE	32		/* dump 16K at a time */
148834293Skarels 
148934293Skarels struct kdbdumpspace {
149034293Skarels 	struct	kdb1ca kd_ca;
149134293Skarels 	struct	mscp kd_rsp;
149234293Skarels 	struct	mscp kd_cmd;
149334293Skarels } kdbdumpspace;
149434293Skarels 
149534293Skarels kdbdump(dev)
149634293Skarels 	dev_t dev;
149734293Skarels {
149834293Skarels 	register struct kdbdumpspace *kd;
149934293Skarels 	register struct kdb_regs *k;
150034293Skarels 	register int i;
150134293Skarels 	struct uba_device *ui;
150234293Skarels 	char *start;
150334293Skarels 	int num, blk, unit, maxsz, blkoff;
150434293Skarels 
150534293Skarels 	/*
150634293Skarels 	 * Make sure the device is a reasonable place on which to dump.
150734293Skarels 	 */
150834293Skarels 	unit = kdbunit(dev);
150934293Skarels 	if (unit >= NKRA)
151034293Skarels 		return (ENXIO);
151134293Skarels 	ui = PHYS(struct uba_device *, kdbdinfo[unit]);
151234293Skarels 	if (ui == NULL || ui->ui_alive == 0)
151334293Skarels 		return (ENXIO);
151434293Skarels 
151534293Skarels 	/*
151634293Skarels 	 * Find and initialise the KDB; get the physical address of the
151734293Skarels 	 * device registers, and of communications area and command and
151834293Skarels 	 * response packet.
151934293Skarels 	 */
152034293Skarels 	k = PHYS(struct kdbinfo *, &kdbinfo[ui->ui_ctlr])->ki_physkdb;
152134293Skarels 	kd = PHYS(struct kdbdumpspace *, &kdbdumpspace);
152234293Skarels 
152334293Skarels 	/*
152434293Skarels 	 * Initialise the controller, with one command and one response
152534293Skarels 	 * packet.
152634293Skarels 	 */
152734293Skarels 	bi_reset(&k->kdb_bi);
152834293Skarels 	if (kdbdumpwait(k, KDB_STEP1))
152934293Skarels 		return (EFAULT);
153034293Skarels 	k->kdb_sw = KDB_ERR;
153134293Skarels 	if (kdbdumpwait(k, KDB_STEP2))
153234293Skarels 		return (EFAULT);
153334757Sbostic 	k->kdb_sw = (int)&kd->kd_ca.ca_rspdsc;
153434293Skarels 	if (kdbdumpwait(k, KDB_STEP3))
153534293Skarels 		return (EFAULT);
153634757Sbostic 	k->kdb_sw = ((int)&kd->kd_ca.ca_rspdsc) >> 16;
153734293Skarels 	if (kdbdumpwait(k, KDB_STEP4))
153834293Skarels 		return (EFAULT);
153934293Skarels 	k->kdb_sw = KDB_GO;
154034293Skarels 
154134293Skarels 	/*
154234293Skarels 	 * Set up the command and response descriptor, then set the
154334293Skarels 	 * controller characteristics and bring the drive on line.
154434293Skarels 	 * Note that all uninitialised locations in kd_cmd are zero.
154534293Skarels 	 */
154634757Sbostic 	kd->kd_ca.ca_rspdsc = (long)&kd->kd_rsp.mscp_cmdref;
154734757Sbostic 	kd->kd_ca.ca_cmddsc = (long)&kd->kd_cmd.mscp_cmdref;
154834293Skarels 	/* kd->kd_cmd.mscp_sccc.sccc_ctlrflags = 0; */
154934293Skarels 	/* kd->kd_cmd.mscp_sccc.sccc_version = 0; */
155034293Skarels 	if (kdbdumpcmd(M_OP_SETCTLRC, k, kd, ui->ui_ctlr))
155134293Skarels 		return (EFAULT);
155234293Skarels 	kd->kd_cmd.mscp_unit = ui->ui_slave;
155334293Skarels 	if (kdbdumpcmd(M_OP_ONLINE, k, kd, ui->ui_ctlr))
155434293Skarels 		return (EFAULT);
155534293Skarels 
155634293Skarels 	/*
155734293Skarels 	 * Pick up the drive type from the on line end packet;
155834293Skarels 	 * convert that to a dump area size and a disk offset.
155934293Skarels 	 * Note that the assembler uses pc-relative addressing
156034293Skarels 	 * to get at kdbtypes[], no need for PHYS().
156134293Skarels 	 */
156234293Skarels 	i = kd->kd_rsp.mscp_onle.onle_drivetype;
156334293Skarels 	if (i >= NTYPES || kdbtypes[i].ut_name == 0) {
156434293Skarels 		printf("disk type %d unknown\ndump ");
156534293Skarels 		return (EINVAL);
156634293Skarels 	}
156734293Skarels 	printf("on %s ", kdbtypes[i].ut_name);
156834293Skarels 
156934293Skarels 	maxsz = kdbtypes[i].ut_sizes[kdbpart(dev)].nblocks;
157034293Skarels 	blkoff = kdbtypes[i].ut_sizes[kdbpart(dev)].blkoff;
157134293Skarels 
157234293Skarels 	/*
157334293Skarels 	 * Dump all of physical memory, or as much as will fit in the
157434293Skarels 	 * space provided.
157534293Skarels 	 */
157634293Skarels 	start = 0;
157734293Skarels 	num = maxfree;
157834293Skarels 	if (dumplo < 0)
157934293Skarels 		return (EINVAL);
158034293Skarels 	if (dumplo + num >= maxsz)
158134293Skarels 		num = maxsz - dumplo;
158234293Skarels 	blkoff += dumplo;
158334293Skarels 
158434293Skarels 	/*
158534293Skarels 	 * Write out memory, DBSIZE pages at a time.
158634293Skarels 	 * N.B.: this code depends on the fact that the sector
158734293Skarels 	 * size == the page size.
158834293Skarels 	 */
158934293Skarels 	while (num > 0) {
159034293Skarels 		blk = num > DBSIZE ? DBSIZE : num;
159134293Skarels 		kd->kd_cmd.mscp_unit = ui->ui_slave;
159234293Skarels 		kd->kd_cmd.mscp_seq.seq_lbn = btop(start) + blkoff;
159334293Skarels 		kd->kd_cmd.mscp_seq.seq_bytecount = blk << PGSHIFT;
159434293Skarels 		kd->kd_cmd.mscp_seq.seq_buffer = (long)start | KDB_PHYS;
159534293Skarels 		if (kdbdumpcmd(M_OP_WRITE, k, kd, ui->ui_ctlr))
159634293Skarels 			return (EIO);
159734293Skarels 		start += blk << PGSHIFT;
159834293Skarels 		num -= blk;
159934293Skarels 	}
160034293Skarels 	return (0);		/* made it! */
160134293Skarels }
160234293Skarels 
160334293Skarels /*
160434293Skarels  * Wait for some of the bits in `bits' to come on.  If the error bit
160534293Skarels  * comes on, or ten seconds pass without response, return true (error).
160634293Skarels  */
160734293Skarels kdbdumpwait(k, bits)
160834293Skarels 	register struct kdb_regs *k;
160934293Skarels 	register int bits;
161034293Skarels {
161134293Skarels 	register int timo = todr() + 1000;
161234293Skarels 
161334293Skarels 	while ((k->kdb_sa & bits) == 0) {
161434293Skarels 		if (k->kdb_sa & KDB_ERR) {
161534293Skarels 			printf("kdb_sa=%b\ndump ", k->kdb_sa, kdbsr_bits);
161634293Skarels 			return (1);
161734293Skarels 		}
161834293Skarels 		if (todr() >= timo) {
161934293Skarels 			printf("timeout\ndump ");
162034293Skarels 			return (1);
162134293Skarels 		}
162234293Skarels 	}
162334293Skarels 	return (0);
162434293Skarels }
162534293Skarels 
162634293Skarels /*
162734293Skarels  * Feed a command to the KDB50, wait for its response, and return
162834293Skarels  * true iff something went wrong.
162934293Skarels  */
163034293Skarels kdbdumpcmd(op, k, kd, ctlr)
163134293Skarels 	int op;
163234293Skarels 	register struct kdb_regs *k;
163334293Skarels 	register struct kdbdumpspace *kd;
163434293Skarels 	int ctlr;
163534293Skarels {
163634293Skarels 	register int n;
163734293Skarels #define mp (&kd->kd_rsp)
163834293Skarels 
163934293Skarels 	kd->kd_cmd.mscp_opcode = op;
164034293Skarels 	kd->kd_cmd.mscp_msglen = MSCP_MSGLEN;
164134293Skarels 	kd->kd_rsp.mscp_msglen = MSCP_MSGLEN;
164234293Skarels 	kd->kd_ca.ca_rspdsc |= MSCP_OWN | MSCP_INT;
164334293Skarels 	kd->kd_ca.ca_cmddsc |= MSCP_OWN | MSCP_INT;
164434293Skarels 	if (k->kdb_sa & KDB_ERR) {
164534293Skarels 		printf("kdb_sa=%b\ndump ", k->kdb_sa, kdbsr_bits);
164634293Skarels 		return (1);
164734293Skarels 	}
164834293Skarels 	n = k->kdb_ip;
164934293Skarels 	n = todr() + 1000;
165034293Skarels 	for (;;) {
165134293Skarels 		if (todr() > n) {
165234293Skarels 			printf("timeout\ndump ");
165334293Skarels 			return (1);
165434293Skarels 		}
165534293Skarels 		if (kd->kd_ca.ca_cmdint)
165634293Skarels 			kd->kd_ca.ca_cmdint = 0;
165734293Skarels 		if (kd->kd_ca.ca_rspint == 0)
165834293Skarels 			continue;
165934293Skarels 		kd->kd_ca.ca_rspint = 0;
166034293Skarels 		if (mp->mscp_opcode == (op | M_OP_END))
166134293Skarels 			break;
166234293Skarels 		printf("\n");
166334293Skarels 		switch (MSCP_MSGTYPE(mp->mscp_msgtc)) {
166434293Skarels 
166534293Skarels 		case MSCPT_SEQ:
166634293Skarels 			printf("sequential");
166734293Skarels 			break;
166834293Skarels 
166934293Skarels 		case MSCPT_DATAGRAM:
167034293Skarels 			mscp_decodeerror("kdb", ctlr, mp);
167134293Skarels 			printf("datagram");
167234293Skarels 			break;
167334293Skarels 
167434293Skarels 		case MSCPT_CREDITS:
167534293Skarels 			printf("credits");
167634293Skarels 			break;
167734293Skarels 
167834293Skarels 		case MSCPT_MAINTENANCE:
167934293Skarels 			printf("maintenance");
168034293Skarels 			break;
168134293Skarels 
168234293Skarels 		default:
168334293Skarels 			printf("unknown (type 0x%x)",
168434293Skarels 				MSCP_MSGTYPE(mp->mscp_msgtc));
168534293Skarels 			break;
168634293Skarels 		}
168734293Skarels 		printf(" ignored\ndump ");
168834293Skarels 		kd->kd_ca.ca_rspdsc |= MSCP_OWN | MSCP_INT;
168934293Skarels 	}
169034293Skarels 	if ((mp->mscp_status & M_ST_MASK) != M_ST_SUCCESS) {
169134293Skarels 		printf("error: op 0x%x => 0x%x status 0x%x\ndump ", op,
169234293Skarels 			mp->mscp_opcode, mp->mscp_status);
169334293Skarels 		return (1);
169434293Skarels 	}
169534293Skarels 	return (0);
169634293Skarels #undef mp
169734293Skarels }
169834293Skarels 
169934293Skarels /*
170034293Skarels  * Return the size of a partition, if known, or -1 if not.
170134293Skarels  */
170234293Skarels kdbsize(dev)
170334293Skarels 	dev_t dev;
170434293Skarels {
170534293Skarels 	register int unit = kdbunit(dev);
170634293Skarels 	register struct uba_device *ui;
170734293Skarels 	register struct size *st;
170834293Skarels 
170934293Skarels 	if (unit >= NKRA || (ui = kdbdinfo[unit]) == NULL || ui->ui_alive == 0)
171034293Skarels 		return (-1);
171134293Skarels 	st = &kdbtypes[ui->ui_type].ut_sizes[kdbpart(dev)];
171234293Skarels 	if (st->nblocks == -1) {
171334293Skarels 		int s = spl5();
171434293Skarels 
171534293Skarels 		/*
171634293Skarels 		 * We need to have the drive on line to find the size
171734293Skarels 		 * of this particular partition.
171834293Skarels 		 * IS IT OKAY TO GO TO SLEEP IN THIS ROUTINE?
171934293Skarels 		 * (If not, better not page on one of these...)
172034293Skarels 		 */
172134293Skarels 		if ((ui->ui_flags & UNIT_ONLINE) == 0) {
172234293Skarels 			if (kdb_bringonline(ui, 0)) {
172334293Skarels 				splx(s);
172434293Skarels 				return (-1);
172534293Skarels 			}
172634293Skarels 		}
172734293Skarels 		splx(s);
172834293Skarels 		if (st->blkoff > ra_dsize[unit])
172934293Skarels 			return (-1);
173034293Skarels 		return (ra_dsize[unit] - st->blkoff);
173134293Skarels 	}
173234293Skarels 	return (st->nblocks);
173334293Skarels }
173434293Skarels 
173534293Skarels #endif NKDB > 0
1736