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