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