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