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