1*34293Skarels /* 2*34293Skarels * @(#)kdb.c 7.1 (Berkeley) 05/14/88 3*34293Skarels * 4*34293Skarels * KDB50/MSCP device driver 5*34293Skarels */ 6*34293Skarels 7*34293Skarels /* 8*34293Skarels * TODO 9*34293Skarels * rethink BI software interface 10*34293Skarels * performance: would testing contiguity in kdbmap be worthwhile? 11*34293Skarels * write bad block forwarding code 12*34293Skarels */ 13*34293Skarels 14*34293Skarels #include "kra.h" /* XXX */ 15*34293Skarels 16*34293Skarels #define DRIVENAMES "kra" /* XXX */ 17*34293Skarels 18*34293Skarels #if NKDB > 0 19*34293Skarels 20*34293Skarels /* 21*34293Skarels * CONFIGURATION OPTIONS. The next three defines are tunable -- tune away! 22*34293Skarels * 23*34293Skarels * NRSPL2 and NCMDL2 control the number of response and command 24*34293Skarels * packets respectively. They may be any value from 0 to 7, though 25*34293Skarels * setting them higher than 5 is unlikely to be of any value. 26*34293Skarels * If you get warnings about your command ring being too small, 27*34293Skarels * try increasing the values by one. 28*34293Skarels * 29*34293Skarels * MAXUNIT controls the maximum slave number (and hence number of drives 30*34293Skarels * per controller) we are prepared to handle. 31*34293Skarels */ 32*34293Skarels #define NRSPL2 5 /* log2 number of response packets */ 33*34293Skarels #define NCMDL2 5 /* log2 number of command packets */ 34*34293Skarels #define MAXUNIT 8 /* maximum allowed unit number */ 35*34293Skarels 36*34293Skarels #include "../machine/pte.h" 37*34293Skarels 38*34293Skarels #include "param.h" 39*34293Skarels #include "systm.h" 40*34293Skarels #include "malloc.h" 41*34293Skarels #include "map.h" 42*34293Skarels #include "buf.h" 43*34293Skarels #include "conf.h" 44*34293Skarels #include "dir.h" 45*34293Skarels #include "user.h" 46*34293Skarels #include "proc.h" 47*34293Skarels #include "vm.h" 48*34293Skarels #include "dkstat.h" 49*34293Skarels #include "cmap.h" 50*34293Skarels #include "syslog.h" 51*34293Skarels #include "kernel.h" 52*34293Skarels 53*34293Skarels #define NRSP (1 << NRSPL2) 54*34293Skarels #define NCMD (1 << NCMDL2) 55*34293Skarels 56*34293Skarels #include "../vax/cpu.h" 57*34293Skarels #include "../vax/mscp.h" 58*34293Skarels #include "../vax/mscpvar.h" 59*34293Skarels #include "../vax/mtpr.h" 60*34293Skarels 61*34293Skarels #include "bireg.h" 62*34293Skarels #include "kdbreg.h" 63*34293Skarels #include "../vaxuba/ubavar.h" 64*34293Skarels 65*34293Skarels /* 66*34293Skarels * Conversions from kernel virtual to physical and page table addresses. 67*34293Skarels * PHYS works only for kernel text and primary (compile time) data addresses. 68*34293Skarels */ 69*34293Skarels #define PHYS(cast, addr) \ 70*34293Skarels ((cast) ((int)(addr) & 0x7fffffff)) 71*34293Skarels 72*34293Skarels /* 73*34293Skarels * KDB variables, per controller. 74*34293Skarels */ 75*34293Skarels struct kdbinfo { 76*34293Skarels /* software info, per KDB */ 77*34293Skarels struct kdb_regs *ki_kdb; /* KDB registers */ 78*34293Skarels struct kdb_regs *ki_physkdb; /* phys address of KDB registers */ 79*34293Skarels short ki_state; /* KDB50 state; see below */ 80*34293Skarels short ki_flags; /* flags; see below */ 81*34293Skarels int ki_micro; /* microcode revision */ 82*34293Skarels short ki_vec; /* scb vector offset */ 83*34293Skarels short ki_wticks; /* watchdog timer ticks */ 84*34293Skarels 85*34293Skarels /* 86*34293Skarels * KDB PTEs must be contiguous. Some I/O is done on addresses 87*34293Skarels * for which this is true (PTEs in Sysmap and Usrptmap), but 88*34293Skarels * other transfers may have PTEs that are scattered in physical 89*34293Skarels * space. Ki_map maps a physically contiguous PTE space used 90*34293Skarels * for these tranfsers. 91*34293Skarels */ 92*34293Skarels #define KI_MAPSIZ (NCMD + 2) 93*34293Skarels struct map *ki_map; /* resource map */ 94*34293Skarels #define KI_PTES 256 95*34293Skarels struct pte *ki_pte; /* contiguous PTE space */ 96*34293Skarels long ki_ptephys; /* phys address of &ki_pte[0] */ 97*34293Skarels 98*34293Skarels struct mscp_info ki_mi; /* MSCP info (per mscpvar.h) */ 99*34293Skarels struct buf ki_tab; /* controller queue */ 100*34293Skarels 101*34293Skarels /* stuff read and written by hardware */ 102*34293Skarels struct kdbca ki_ca; /* communications area */ 103*34293Skarels struct mscp ki_rsp[NRSP]; /* response packets */ 104*34293Skarels struct mscp ki_cmd[NCMD]; /* command packets */ 105*34293Skarels } kdbinfo[NKDB]; 106*34293Skarels 107*34293Skarels #define ki_ctlr ki_mi.mi_ctlr 108*34293Skarels 109*34293Skarels /* 110*34293Skarels * Controller states 111*34293Skarels */ 112*34293Skarels #define ST_IDLE 0 /* uninitialised */ 113*34293Skarels #define ST_STEP1 1 /* in `STEP 1' */ 114*34293Skarels #define ST_STEP2 2 /* in `STEP 2' */ 115*34293Skarels #define ST_STEP3 3 /* in `STEP 3' */ 116*34293Skarels #define ST_SETCHAR 4 /* in `Set Controller Characteristics' */ 117*34293Skarels #define ST_RUN 5 /* up and running */ 118*34293Skarels 119*34293Skarels /* 120*34293Skarels * Flags 121*34293Skarels */ 122*34293Skarels #define KDB_ALIVE 0x01 /* this KDB50 exists */ 123*34293Skarels #define KDB_GRIPED 0x04 /* griped about cmd ring too small */ 124*34293Skarels #define KDB_INSLAVE 0x08 /* inside kdbslave() */ 125*34293Skarels #define KDB_DOWAKE 0x10 /* wakeup when ctlr init done */ 126*34293Skarels 127*34293Skarels struct kdbstats kdbstats; /* statistics */ 128*34293Skarels 129*34293Skarels /* 130*34293Skarels * Device to unit number and partition: 131*34293Skarels */ 132*34293Skarels #define UNITSHIFT 3 133*34293Skarels #define UNITMASK 7 134*34293Skarels #define kdbunit(dev) (minor(dev) >> UNITSHIFT) 135*34293Skarels #define kdbpart(dev) (minor(dev) & UNITMASK) 136*34293Skarels 137*34293Skarels /* THIS SHOULD BE READ OFF THE PACK, PER DRIVE */ 138*34293Skarels /* THESE SHOULD BE SHARED WITH uda.c (but not yet) */ 139*34293Skarels struct size { 140*34293Skarels daddr_t nblocks; 141*34293Skarels daddr_t blkoff; 142*34293Skarels } kra81_sizes[8] = { 143*34293Skarels #ifdef MARYLAND 144*34293Skarels 67832, 0, /* A=cyl 0 thru 94 + 2 sectors */ 145*34293Skarels 67828, 67832, /* B=cyl 95 thru 189 - 2 sectors */ 146*34293Skarels -1, 0, /* C=cyl 0 thru 1247 */ 147*34293Skarels -1, 135660, /* D=cyl 190 thru 1247 */ 148*34293Skarels 449466, 49324, /* E xxx */ 149*34293Skarels 64260, 498790, /* F xxx */ 150*34293Skarels 328022, 563050, /* G xxx */ 151*34293Skarels 0, 0, 152*34293Skarels #else 153*34293Skarels 15884, 0, /* a */ 154*34293Skarels 33440, 15884, /* b */ 155*34293Skarels -1, 0, /* c */ 156*34293Skarels -1, 49324, /* d */ 157*34293Skarels 449466, 49324, /* e */ 158*34293Skarels 64260, 498790, /* f */ 159*34293Skarels 328022, 563050, /* g */ 160*34293Skarels 0, 0, 161*34293Skarels #endif 162*34293Skarels }, kra80_sizes[8] = { 163*34293Skarels 15884, 0, /* A=blk 0 thru 15883 */ 164*34293Skarels 33440, 15884, /* B=blk 15884 thru 49323 */ 165*34293Skarels -1, 0, /* C=blk 0 thru end */ 166*34293Skarels 0, 0, 167*34293Skarels 0, 0, 168*34293Skarels 0, 0, 169*34293Skarels 82080, 49324, /* G=blk 49324 thru 131403 */ 170*34293Skarels -1, 131404, /* H=blk 131404 thru end */ 171*34293Skarels }, kra60_sizes[8] = { 172*34293Skarels 15884, 0, /* A=blk 0 thru 15883 */ 173*34293Skarels 33440, 15884, /* B=blk 15884 thru 49323 */ 174*34293Skarels -1, 0, /* C=blk 0 thru end */ 175*34293Skarels -1, 49324, /* D=blk 49324 thru end */ 176*34293Skarels 0, 0, 177*34293Skarels 0, 0, 178*34293Skarels 82080, 49324, /* G=blk 49324 thru 131403 */ 179*34293Skarels -1, 131404, /* H=blk 131404 thru end */ 180*34293Skarels }; 181*34293Skarels /* END OF STUFF WHICH SHOULD BE READ IN PER DISK */ 182*34293Skarels 183*34293Skarels /* 184*34293Skarels * Drive type index decoding table. `ut_name' is null iff the 185*34293Skarels * type is not known. 186*34293Skarels */ 187*34293Skarels struct kdbtypes { 188*34293Skarels char *ut_name; /* drive type name */ 189*34293Skarels struct size *ut_sizes; /* partition tables */ 190*34293Skarels } kdbtypes[] = { 191*34293Skarels NULL, NULL, 192*34293Skarels "ra80", kra80_sizes, /* 1 = ra80 */ 193*34293Skarels NULL, NULL, 194*34293Skarels NULL, NULL, 195*34293Skarels "ra60", kra60_sizes, /* 4 = ra60 */ 196*34293Skarels "ra81", kra81_sizes, /* 5 = ra81 */ 197*34293Skarels }; 198*34293Skarels 199*34293Skarels #define NTYPES 6 200*34293Skarels 201*34293Skarels /* 202*34293Skarels * Definition of the driver for autoconf and generic MSCP code. 203*34293Skarels * SOME OF THIS IS BOGUS (must fix config) 204*34293Skarels */ 205*34293Skarels 206*34293Skarels #ifdef notdef /* not when driver is for kra disks */ 207*34293Skarels /* 208*34293Skarels * Some of these variables (per-drive stuff) are shared 209*34293Skarels * with the UDA50 code (why not, they are the same drives). 210*34293Skarels * N.B.: kdbdinfo must not be shared. 211*34293Skarels */ 212*34293Skarels #define kdbutab udautab /* shared */ 213*34293Skarels #define kdbslavereply udaslavereply /* shared */ 214*34293Skarels #endif 215*34293Skarels 216*34293Skarels int kdbprobe(); /* XXX */ 217*34293Skarels int kdbslave(), kdbattach(); 218*34293Skarels 219*34293Skarels int kdbdgram(), kdbctlrdone(), kdbunconf(), kdbiodone(); 220*34293Skarels int kdbonline(), kdbgotstatus(), kdbioerror(); 221*34293Skarels 222*34293Skarels struct uba_device *kdbdinfo[NKRA]; /* uba_device indeed! */ 223*34293Skarels struct buf kdbutab[NKRA]; /* per drive transfer queue */ 224*34293Skarels 225*34293Skarels u_short kdbstd[] = { 0 }; /* XXX */ 226*34293Skarels struct uba_driver kdbdriver = /* XXX */ 227*34293Skarels { kdbprobe, kdbslave, kdbattach, 0, kdbstd, DRIVENAMES, kdbdinfo, "kdb" }; 228*34293Skarels 229*34293Skarels struct mscp_driver kdbmscpdriver = 230*34293Skarels { MAXUNIT, NKRA, UNITSHIFT, kdbutab, kdbdinfo, 231*34293Skarels kdbdgram, kdbctlrdone, kdbunconf, kdbiodone, 232*34293Skarels kdbonline, kdbgotstatus, NULL, kdbioerror, NULL, 233*34293Skarels "kdb", DRIVENAMES }; 234*34293Skarels 235*34293Skarels /* 236*34293Skarels * Miscellaneous private variables. 237*34293Skarels */ 238*34293Skarels char kdbsr_bits[] = KDBSR_BITS; 239*34293Skarels 240*34293Skarels struct uba_device *kdbip[NKDB][MAXUNIT]; 241*34293Skarels /* inverting pointers: ctlr & unit => `Unibus' 242*34293Skarels device pointer */ 243*34293Skarels 244*34293Skarels daddr_t ra_dsize[NKRA]; /* drive sizes, from on line end packets */ 245*34293Skarels 246*34293Skarels struct mscp kdbslavereply; /* get unit status response packet, set 247*34293Skarels for kdbslave by kdbunconf, via kdbintr */ 248*34293Skarels 249*34293Skarels int kdbwstart, kdbwatch(); /* watchdog timer */ 250*34293Skarels int wakeup(); 251*34293Skarels 252*34293Skarels /* 253*34293Skarels * If kdbprobe is called, return 0 to keep Unibus code from attempting 254*34293Skarels * to use this device. XXX rethink 255*34293Skarels */ 256*34293Skarels /* ARGSUSED */ 257*34293Skarels kdbprobe(reg, ctlr) 258*34293Skarels caddr_t reg; 259*34293Skarels int ctlr; 260*34293Skarels { 261*34293Skarels 262*34293Skarels return (0); 263*34293Skarels } 264*34293Skarels 265*34293Skarels /* 266*34293Skarels * Configure in a KDB50 controller. 267*34293Skarels */ 268*34293Skarels kdbconfig(kdbnum, va, pa, vec) 269*34293Skarels int kdbnum; 270*34293Skarels struct biiregs *va, *pa; 271*34293Skarels int vec; 272*34293Skarels { 273*34293Skarels register struct kdbinfo *ki; 274*34293Skarels #define mi (&ki->ki_mi) 275*34293Skarels 276*34293Skarels #ifdef lint 277*34293Skarels extern int (*kdbint0[])(); 278*34293Skarels 279*34293Skarels (*kdbint0[0])(0); /* this is a config botch */ 280*34293Skarels kdbintr(0); 281*34293Skarels #endif 282*34293Skarels 283*34293Skarels /* 284*34293Skarels * Set up local KDB status. 285*34293Skarels */ 286*34293Skarels ki = &kdbinfo[kdbnum]; 287*34293Skarels ki->ki_kdb = (struct kdb_regs *) va; 288*34293Skarels ki->ki_physkdb = (struct kdb_regs *) pa; 289*34293Skarels ki->ki_vec = vec; 290*34293Skarels ki->ki_map = (struct map *) malloc(KI_MAPSIZ * sizeof (struct map), 291*34293Skarels M_DEVBUF, M_NOWAIT); 292*34293Skarels ki->ki_pte = (struct pte *) malloc(KI_PTES * sizeof (struct pte)), 293*34293Skarels M_DEVBUF, M_NOWAIT; 294*34293Skarels if (ki->ki_map == NULL || ki->ki_pte == NULL) 295*34293Skarels return; 296*34293Skarels bzero((caddr_t) ki->ki_map, KI_MAPSIZ * sizeof (struct map)); 297*34293Skarels bzero((caddr_t) ki->ki_pte, KI_PTES * sizeof (struct pte)); 298*34293Skarels ki->ki_flags = KDB_ALIVE; 299*34293Skarels ki->ki_ptephys = kvtophys(ki->ki_pte); 300*34293Skarels 301*34293Skarels rminit(ki->ki_map, (long)KI_PTES, (long)1, "kdb", KI_MAPSIZ); 302*34293Skarels 303*34293Skarels /* 304*34293Skarels * Set up the generic MSCP structures. 305*34293Skarels */ 306*34293Skarels mi->mi_md = &kdbmscpdriver; 307*34293Skarels mi->mi_ctlr = kdbnum; /* also sets ki->ki_ctlr */ 308*34293Skarels mi->mi_tab = &ki->ki_tab; 309*34293Skarels mi->mi_ip = kdbip[kdbnum]; 310*34293Skarels mi->mi_cmd.mri_size = NCMD; 311*34293Skarels mi->mi_cmd.mri_desc = ki->ki_ca.ca_cmddsc; 312*34293Skarels mi->mi_cmd.mri_ring = ki->ki_cmd; 313*34293Skarels mi->mi_rsp.mri_size = NRSP; 314*34293Skarels mi->mi_rsp.mri_desc = ki->ki_ca.ca_rspdsc; 315*34293Skarels mi->mi_rsp.mri_ring = ki->ki_rsp; 316*34293Skarels mi->mi_wtab.av_forw = mi->mi_wtab.av_back = &mi->mi_wtab; 317*34293Skarels #undef mi 318*34293Skarels } 319*34293Skarels 320*34293Skarels /* 321*34293Skarels * Find a slave. 322*34293Skarels * Note that by the time kdbslave is called, the interrupt vector 323*34293Skarels * for the KDB50 has been set up (so that kdbunconf() will be called). 324*34293Skarels */ 325*34293Skarels kdbslave(ui) 326*34293Skarels register struct uba_device *ui; 327*34293Skarels { 328*34293Skarels register struct kdbinfo *ki; 329*34293Skarels register struct mscp *mp; 330*34293Skarels int next = 0, type, timeout, tries, i; 331*34293Skarels 332*34293Skarels #ifdef lint 333*34293Skarels i = 0; i = i; 334*34293Skarels #endif 335*34293Skarels /* 336*34293Skarels * Make sure the controller is fully initialised, by waiting 337*34293Skarels * for it if necessary. 338*34293Skarels */ 339*34293Skarels ki = &kdbinfo[ui->ui_ctlr]; 340*34293Skarels if (ki->ki_state == ST_RUN) 341*34293Skarels goto findunit; 342*34293Skarels tries = 0; 343*34293Skarels again: 344*34293Skarels if (kdbinit(ki)) 345*34293Skarels return (0); 346*34293Skarels timeout = todr() + 1000; /* 10 seconds */ 347*34293Skarels while (todr() < timeout) 348*34293Skarels if (ki->ki_state == ST_RUN) /* made it */ 349*34293Skarels goto findunit; 350*34293Skarels if (++tries < 2) 351*34293Skarels goto again; 352*34293Skarels printf("kdb%d: controller hung\n", ki->ki_ctlr); 353*34293Skarels return (0); 354*34293Skarels 355*34293Skarels /* 356*34293Skarels * The controller is all set; go find the unit. Grab an 357*34293Skarels * MSCP packet and send out a Get Unit Status command, with 358*34293Skarels * the `next unit' modifier if we are looking for a generic 359*34293Skarels * unit. We set the `in slave' flag so that kdbunconf() 360*34293Skarels * knows to copy the response to `kdbslavereply'. 361*34293Skarels */ 362*34293Skarels findunit: 363*34293Skarels kdbslavereply.mscp_opcode = 0; 364*34293Skarels ki->ki_flags |= KDB_INSLAVE; 365*34293Skarels if ((mp = mscp_getcp(&ki->ki_mi, MSCP_DONTWAIT)) == NULL) 366*34293Skarels panic("kdbslave"); /* `cannot happen' */ 367*34293Skarels mp->mscp_opcode = M_OP_GETUNITST; 368*34293Skarels if (ui->ui_slave == '?') { 369*34293Skarels mp->mscp_unit = next; 370*34293Skarels mp->mscp_modifier = M_GUM_NEXTUNIT; 371*34293Skarels } else { 372*34293Skarels mp->mscp_unit = ui->ui_slave; 373*34293Skarels mp->mscp_modifier = 0; 374*34293Skarels } 375*34293Skarels *mp->mscp_addr |= MSCP_OWN | MSCP_INT; 376*34293Skarels i = ki->ki_kdb->kdb_ip; /* initiate polling */ 377*34293Skarels mp = &kdbslavereply; 378*34293Skarels timeout = todr() + 1000; 379*34293Skarels while (todr() < timeout) 380*34293Skarels if (mp->mscp_opcode) 381*34293Skarels goto gotit; 382*34293Skarels printf("kdb%d: no response to Get Unit Status request\n", 383*34293Skarels ki->ki_ctlr); 384*34293Skarels ki->ki_flags &= ~KDB_INSLAVE; 385*34293Skarels return (0); 386*34293Skarels 387*34293Skarels gotit: 388*34293Skarels ki->ki_flags &= ~KDB_INSLAVE; 389*34293Skarels 390*34293Skarels /* 391*34293Skarels * Got a slave response. If the unit is there, use it. 392*34293Skarels */ 393*34293Skarels switch (mp->mscp_status & M_ST_MASK) { 394*34293Skarels 395*34293Skarels case M_ST_SUCCESS: /* worked */ 396*34293Skarels case M_ST_AVAILABLE: /* found another drive */ 397*34293Skarels break; /* use it */ 398*34293Skarels 399*34293Skarels case M_ST_OFFLINE: 400*34293Skarels /* 401*34293Skarels * Figure out why it is off line. It may be because 402*34293Skarels * it is nonexistent, or because it is spun down, or 403*34293Skarels * for some other reason. 404*34293Skarels */ 405*34293Skarels switch (mp->mscp_status & ~M_ST_MASK) { 406*34293Skarels 407*34293Skarels case M_OFFLINE_UNKNOWN: 408*34293Skarels /* 409*34293Skarels * No such drive, and there are none with 410*34293Skarels * higher unit numbers either, if we are 411*34293Skarels * using M_GUM_NEXTUNIT. 412*34293Skarels */ 413*34293Skarels return (0); 414*34293Skarels 415*34293Skarels case M_OFFLINE_UNMOUNTED: 416*34293Skarels /* 417*34293Skarels * The drive is not spun up. Use it anyway. 418*34293Skarels * 419*34293Skarels * N.B.: this seems to be a common occurrance 420*34293Skarels * after a power failure. The first attempt 421*34293Skarels * to bring it on line seems to spin it up 422*34293Skarels * (and thus takes several minutes). Perhaps 423*34293Skarels * we should note here that the on-line may 424*34293Skarels * take longer than usual. 425*34293Skarels */ 426*34293Skarels break; 427*34293Skarels 428*34293Skarels default: 429*34293Skarels /* 430*34293Skarels * In service, or something else equally unusable. 431*34293Skarels */ 432*34293Skarels printf("kdb%d: unit %d off line: ", ki->ki_ctlr, 433*34293Skarels mp->mscp_unit); 434*34293Skarels mscp_printevent(mp); 435*34293Skarels goto try_another; 436*34293Skarels } 437*34293Skarels break; 438*34293Skarels 439*34293Skarels default: 440*34293Skarels printf("kdb%d: unable to get unit status: ", ki->ki_ctlr); 441*34293Skarels mscp_printevent(mp); 442*34293Skarels return (0); 443*34293Skarels } 444*34293Skarels 445*34293Skarels /* 446*34293Skarels * Does this ever happen? What (if anything) does it mean? 447*34293Skarels */ 448*34293Skarels if (mp->mscp_unit < next) { 449*34293Skarels printf("kdb%d: unit %d, next %d\n", 450*34293Skarels ki->ki_ctlr, mp->mscp_unit, next); 451*34293Skarels return (0); 452*34293Skarels } 453*34293Skarels 454*34293Skarels if (mp->mscp_unit >= MAXUNIT) { 455*34293Skarels printf("kdb%d: cannot handle unit number %d (max is %d)\n", 456*34293Skarels ki->ki_ctlr, mp->mscp_unit, MAXUNIT - 1); 457*34293Skarels return (0); 458*34293Skarels } 459*34293Skarels 460*34293Skarels /* 461*34293Skarels * See if we already handle this drive. 462*34293Skarels * (Only likely if ui->ui_slave=='?'.) 463*34293Skarels */ 464*34293Skarels if (kdbip[ki->ki_ctlr][mp->mscp_unit] != NULL) 465*34293Skarels goto try_another; 466*34293Skarels 467*34293Skarels /* 468*34293Skarels * Make sure we know about this kind of drive. 469*34293Skarels * Others say we should treat unknowns as RA81s; I am 470*34293Skarels * not sure this is safe. 471*34293Skarels */ 472*34293Skarels type = mp->mscp_guse.guse_drivetype; 473*34293Skarels if (type >= NTYPES || kdbtypes[type].ut_name == 0) { 474*34293Skarels register long id = mp->mscp_guse.guse_mediaid; 475*34293Skarels 476*34293Skarels printf("kdb%d: unit %d: media ID `", ki->ki_ctlr, 477*34293Skarels mp->mscp_unit); 478*34293Skarels printf("%c%c %c%c%c%d", 479*34293Skarels MSCP_MID_CHAR(4, id), MSCP_MID_CHAR(3, id), 480*34293Skarels MSCP_MID_CHAR(2, id), MSCP_MID_CHAR(1, id), 481*34293Skarels MSCP_MID_CHAR(0, id), MSCP_MID_NUM(id)); 482*34293Skarels printf("' is of unknown type %d; ignored\n", type); 483*34293Skarels try_another: 484*34293Skarels if (ui->ui_slave != '?') 485*34293Skarels return (0); 486*34293Skarels next = mp->mscp_unit + 1; 487*34293Skarels goto findunit; 488*34293Skarels } 489*34293Skarels 490*34293Skarels /* 491*34293Skarels * Voila! 492*34293Skarels */ 493*34293Skarels ui->ui_type = type; 494*34293Skarels ui->ui_flags = 0; /* not on line, nor anything else */ 495*34293Skarels ui->ui_slave = mp->mscp_unit; 496*34293Skarels return (1); 497*34293Skarels } 498*34293Skarels 499*34293Skarels /* 500*34293Skarels * Attach a found slave. Make sure the watchdog timer is running. 501*34293Skarels * If this disk is being profiled, fill in the `mspw' value (used by 502*34293Skarels * what?). Set up the inverting pointer, and attempt to bring the 503*34293Skarels * drive on line. 504*34293Skarels */ 505*34293Skarels kdbattach(ui) 506*34293Skarels register struct uba_device *ui; 507*34293Skarels { 508*34293Skarels 509*34293Skarels if (kdbwstart == 0) { 510*34293Skarels timeout(kdbwatch, (caddr_t) 0, hz); 511*34293Skarels kdbwstart++; 512*34293Skarels } 513*34293Skarels if (ui->ui_dk >= 0) 514*34293Skarels dk_mspw[ui->ui_dk] = 1.0 / (60 * 31 * 256); /* approx */ 515*34293Skarels kdbip[ui->ui_ctlr][ui->ui_slave] = ui; 516*34293Skarels (void) kdb_bringonline(ui, 1); 517*34293Skarels /* should we get its status too? */ 518*34293Skarels } 519*34293Skarels 520*34293Skarels /* 521*34293Skarels * Initialise a KDB50. Return true iff something goes wrong. 522*34293Skarels */ 523*34293Skarels kdbinit(ki) 524*34293Skarels register struct kdbinfo *ki; 525*34293Skarels { 526*34293Skarels register struct kdb_regs *ka = ki->ki_kdb; 527*34293Skarels int timo; 528*34293Skarels 529*34293Skarels /* 530*34293Skarels * While we are thinking about it, reset the next command 531*34293Skarels * and response indicies. 532*34293Skarels */ 533*34293Skarels ki->ki_mi.mi_cmd.mri_next = 0; 534*34293Skarels ki->ki_mi.mi_rsp.mri_next = 0; 535*34293Skarels 536*34293Skarels /* 537*34293Skarels * Start up the hardware initialisation sequence. 538*34293Skarels */ 539*34293Skarels #define STEP0MASK (KDB_ERR | KDB_STEP4 | KDB_STEP3 | KDB_STEP2 | KDB_STEP1) 540*34293Skarels 541*34293Skarels ki->ki_state = ST_IDLE; /* in case init fails */ 542*34293Skarels 543*34293Skarels bi_reset(&ka->kdb_bi); /* reset bi node (but not the BI itself) */ 544*34293Skarels 545*34293Skarels timo = todr() + 1000; 546*34293Skarels while ((ka->kdb_sa & STEP0MASK) == 0) { 547*34293Skarels if (todr() > timo) { 548*34293Skarels printf("kdb%d: timeout during init\n", ki->ki_ctlr); 549*34293Skarels return (-1); 550*34293Skarels } 551*34293Skarels } 552*34293Skarels if ((ka->kdb_sa & STEP0MASK) != KDB_STEP1) { 553*34293Skarels printf("kdb%d: init failed, sa=%b\n", ki->ki_ctlr, 554*34293Skarels ka->kdb_sa, kdbsr_bits); 555*34293Skarels return (-1); 556*34293Skarels } 557*34293Skarels 558*34293Skarels /* 559*34293Skarels * Success! Record new state, and start step 1 initialisation. 560*34293Skarels * The rest is done in the interrupt handler. 561*34293Skarels */ 562*34293Skarels ki->ki_state = ST_STEP1; 563*34293Skarels ka->kdb_bi.bi_intrdes = 1 << mastercpu; 564*34293Skarels #ifdef unneeded /* is it? */ 565*34293Skarels ka->kdb_bi.bi_csr = (ka->kdb_bi.bi_csr&~BICSR_ARB_MASK)|BICSR_ARB_???; 566*34293Skarels #endif 567*34293Skarels ka->kdb_bi.bi_bcicsr |= BCI_STOPEN | BCI_IDENTEN | BCI_UINTEN | 568*34293Skarels BCI_INTEN; 569*34293Skarels 570*34293Skarels /* I THINK THIS IS WRONG */ 571*34293Skarels /* Mach uses 0x601d0, which includes IPL16, but 1d0 is IPL17, nexzvec...? */ 572*34293Skarels ka->kdb_bi.bi_eintrcsr = BIEIC_IPL15 | ki->ki_vec; /* ??? */ 573*34293Skarels /* END I THINK WRONG */ 574*34293Skarels 575*34293Skarels ka->kdb_bi.bi_uintrcsr = ki->ki_vec; 576*34293Skarels ka->kdb_sw = KDB_ERR | (NCMDL2 << 11) | (NRSPL2 << 8) | KDB_IE | 577*34293Skarels (ki->ki_vec >> 2); 578*34293Skarels return (0); 579*34293Skarels } 580*34293Skarels 581*34293Skarels /* 582*34293Skarels * Open a drive. 583*34293Skarels */ 584*34293Skarels /*ARGSUSED*/ 585*34293Skarels kdbopen(dev, flag) 586*34293Skarels dev_t dev; 587*34293Skarels int flag; 588*34293Skarels { 589*34293Skarels register int unit; 590*34293Skarels register struct uba_device *ui; 591*34293Skarels register struct kdbinfo *ki; 592*34293Skarels int s; 593*34293Skarels 594*34293Skarels /* 595*34293Skarels * Make sure this is a reasonable open request. 596*34293Skarels */ 597*34293Skarels unit = kdbunit(dev); 598*34293Skarels if (unit >= NKRA || (ui = kdbdinfo[unit]) == 0 || ui->ui_alive == 0) 599*34293Skarels return (ENXIO); 600*34293Skarels 601*34293Skarels /* 602*34293Skarels * Make sure the controller is running, by (re)initialising it if 603*34293Skarels * necessary. 604*34293Skarels */ 605*34293Skarels ki = &kdbinfo[ui->ui_ctlr]; 606*34293Skarels s = spl5(); 607*34293Skarels if (ki->ki_state != ST_RUN) { 608*34293Skarels if (ki->ki_state == ST_IDLE && kdbinit(ki)) { 609*34293Skarels splx(s); 610*34293Skarels return (EIO); 611*34293Skarels } 612*34293Skarels /* 613*34293Skarels * In case it does not come up, make sure we will be 614*34293Skarels * restarted in 10 seconds. This corresponds to the 615*34293Skarels * 10 second timeouts in kdbprobe() and kdbslave(). 616*34293Skarels */ 617*34293Skarels ki->ki_flags |= KDB_DOWAKE; 618*34293Skarels timeout(wakeup, (caddr_t) &ki->ki_flags, 10 * hz); 619*34293Skarels sleep((caddr_t) &ki->ki_flags, PRIBIO); 620*34293Skarels if (ki->ki_state != ST_RUN) { 621*34293Skarels splx(s); 622*34293Skarels printf("kdb%d: controller hung\n", ui->ui_ctlr); 623*34293Skarels return (EIO); 624*34293Skarels } 625*34293Skarels untimeout(wakeup, (caddr_t) &ki->ki_flags); 626*34293Skarels } 627*34293Skarels if ((ui->ui_flags & UNIT_ONLINE) == 0) { 628*34293Skarels /* 629*34293Skarels * Bring the drive on line so we can find out how 630*34293Skarels * big it is. If it is not spun up, it will not 631*34293Skarels * come on line; this cannot really be considered 632*34293Skarels * an `error condition'. 633*34293Skarels */ 634*34293Skarels if (kdb_bringonline(ui, 0)) { 635*34293Skarels splx(s); 636*34293Skarels printf("%s%d: drive will not come on line\n", 637*34293Skarels kdbdriver.ud_dname, unit); 638*34293Skarels return (EIO); 639*34293Skarels } 640*34293Skarels } 641*34293Skarels splx(s); 642*34293Skarels return (0); 643*34293Skarels } 644*34293Skarels 645*34293Skarels /* 646*34293Skarels * Bring a drive on line. In case it fails to respond, we set 647*34293Skarels * a timeout on it. The `nosleep' parameter should be set if 648*34293Skarels * we are to spin-wait; otherwise this must be called at spl5(). 649*34293Skarels */ 650*34293Skarels kdb_bringonline(ui, nosleep) 651*34293Skarels register struct uba_device *ui; 652*34293Skarels int nosleep; 653*34293Skarels { 654*34293Skarels register struct kdbinfo *ki = &kdbinfo[ui->ui_ctlr]; 655*34293Skarels register struct mscp *mp; 656*34293Skarels int i; 657*34293Skarels 658*34293Skarels if (nosleep) { 659*34293Skarels mp = mscp_getcp(&ki->ki_mi, MSCP_DONTWAIT); 660*34293Skarels if (mp == NULL) 661*34293Skarels return (-1); 662*34293Skarels } else 663*34293Skarels mp = mscp_getcp(&ki->ki_mi, MSCP_WAIT); 664*34293Skarels mp->mscp_opcode = M_OP_ONLINE; 665*34293Skarels mp->mscp_unit = ui->ui_slave; 666*34293Skarels mp->mscp_cmdref = (long) &ui->ui_flags; 667*34293Skarels *mp->mscp_addr |= MSCP_OWN | MSCP_INT; 668*34293Skarels i = ki->ki_kdb->kdb_ip; 669*34293Skarels 670*34293Skarels if (nosleep) { 671*34293Skarels i = todr() + 1000; 672*34293Skarels while ((ui->ui_flags & UNIT_ONLINE) == 0) 673*34293Skarels if (todr() > i) 674*34293Skarels return (-1); 675*34293Skarels } else { 676*34293Skarels timeout(wakeup, (caddr_t) &ui->ui_flags, 10 * hz); 677*34293Skarels sleep((caddr_t) &ui->ui_flags, PRIBIO); 678*34293Skarels if ((ui->ui_flags & UNIT_ONLINE) == 0) 679*34293Skarels return (-1); 680*34293Skarels untimeout(wakeup, (caddr_t) &ui->ui_flags); 681*34293Skarels } 682*34293Skarels return (0); /* made it */ 683*34293Skarels } 684*34293Skarels 685*34293Skarels /* 686*34293Skarels * Queue a transfer request, and if possible, hand it to the controller. 687*34293Skarels * 688*34293Skarels * This routine is broken into two so that the internal version 689*34293Skarels * kdbstrat1() can be called by the (nonexistent, as yet) bad block 690*34293Skarels * revectoring routine. 691*34293Skarels */ 692*34293Skarels kdbstrategy(bp) 693*34293Skarels register struct buf *bp; 694*34293Skarels { 695*34293Skarels register int unit; 696*34293Skarels register struct uba_device *ui; 697*34293Skarels register struct size *st; 698*34293Skarels daddr_t sz, maxsz; 699*34293Skarels 700*34293Skarels /* 701*34293Skarels * Make sure this is a reasonable drive to use. 702*34293Skarels */ 703*34293Skarels if ((unit = kdbunit(bp->b_dev)) >= NKRA || 704*34293Skarels (ui = kdbdinfo[unit]) == NULL || ui->ui_alive == 0) { 705*34293Skarels bp->b_error = ENXIO; 706*34293Skarels bp->b_flags |= B_ERROR; 707*34293Skarels biodone(bp); 708*34293Skarels return; 709*34293Skarels } 710*34293Skarels 711*34293Skarels /* 712*34293Skarels * Determine the size of the transfer, and make sure it is 713*34293Skarels * within the boundaries of the drive. 714*34293Skarels */ 715*34293Skarels sz = (bp->b_bcount + 511) >> 9; 716*34293Skarels st = &kdbtypes[ui->ui_type].ut_sizes[kdbpart(bp->b_dev)]; 717*34293Skarels if ((maxsz = st->nblocks) < 0) 718*34293Skarels maxsz = ra_dsize[unit] - st->blkoff; 719*34293Skarels if (bp->b_blkno < 0 || bp->b_blkno + sz > maxsz || 720*34293Skarels st->blkoff >= ra_dsize[unit]) { 721*34293Skarels /* if exactly at end of disk, return an EOF */ 722*34293Skarels if (bp->b_blkno == maxsz) 723*34293Skarels bp->b_resid = bp->b_bcount; 724*34293Skarels else { 725*34293Skarels bp->b_error = EINVAL; 726*34293Skarels bp->b_flags |= B_ERROR; 727*34293Skarels } 728*34293Skarels biodone(bp); 729*34293Skarels return; 730*34293Skarels } 731*34293Skarels kdbstrat1(bp); 732*34293Skarels } 733*34293Skarels 734*34293Skarels /* 735*34293Skarels * Work routine for kdbstrategy. 736*34293Skarels */ 737*34293Skarels kdbstrat1(bp) 738*34293Skarels register struct buf *bp; 739*34293Skarels { 740*34293Skarels register int unit = kdbunit(bp->b_dev); 741*34293Skarels register struct buf *dp; 742*34293Skarels register struct kdbinfo *ki; 743*34293Skarels struct uba_device *ui; 744*34293Skarels int s; 745*34293Skarels 746*34293Skarels /* 747*34293Skarels * Append the buffer to the drive queue, and if it is not 748*34293Skarels * already there, the drive to the controller queue. (However, 749*34293Skarels * if the drive queue is marked to be requeued, we must be 750*34293Skarels * awaiting an on line or get unit status command; in this 751*34293Skarels * case, leave it off the controller queue.) 752*34293Skarels */ 753*34293Skarels ui = kdbdinfo[unit]; 754*34293Skarels ki = &kdbinfo[ui->ui_ctlr]; 755*34293Skarels dp = &kdbutab[unit]; 756*34293Skarels s = spl5(); 757*34293Skarels APPEND(bp, dp, av_forw); 758*34293Skarels if (dp->b_active == 0 && (ui->ui_flags & UNIT_REQUEUE) == 0) { 759*34293Skarels APPEND(dp, &ki->ki_tab, b_forw); 760*34293Skarels dp->b_active++; 761*34293Skarels } 762*34293Skarels 763*34293Skarels /* 764*34293Skarels * Start activity on the controller. 765*34293Skarels */ 766*34293Skarels kdbstart(ki); 767*34293Skarels splx(s); 768*34293Skarels } 769*34293Skarels 770*34293Skarels /* 771*34293Skarels * Find the physical address of some contiguous PTEs that map the 772*34293Skarels * transfer described in `bp', creating them (by copying) if 773*34293Skarels * necessary. Store the physical base address of the map through 774*34293Skarels * mapbase, and the page offset through offset, and any resource 775*34293Skarels * information in *info (or 0 if none). 776*34293Skarels * 777*34293Skarels * If we cannot allocate space, return a nonzero status. 778*34293Skarels */ 779*34293Skarels int 780*34293Skarels kdbmap(ki, bp, mapbase, offset, info) 781*34293Skarels struct kdbinfo *ki; 782*34293Skarels register struct buf *bp; 783*34293Skarels long *mapbase, *offset; 784*34293Skarels int *info; 785*34293Skarels { 786*34293Skarels register struct pte *spte, *dpte; 787*34293Skarels register struct proc *rp; 788*34293Skarels register int i, a, o; 789*34293Skarels u_int v; 790*34293Skarels int npf; 791*34293Skarels 792*34293Skarels o = (int)bp->b_un.b_addr & PGOFSET; 793*34293Skarels 794*34293Skarels /* handle contiguous cases */ 795*34293Skarels if ((bp->b_flags & B_PHYS) == 0) { 796*34293Skarels spte = kvtopte(bp->b_un.b_addr); 797*34293Skarels kdbstats.ks_sys++; 798*34293Skarels *mapbase = PHYS(long, spte); 799*34293Skarels *offset = o; 800*34293Skarels *info = 0; 801*34293Skarels return (0); 802*34293Skarels } 803*34293Skarels if (bp->b_flags & B_PAGET) { 804*34293Skarels spte = &Usrptmap[btokmx((struct pte *)bp->b_un.b_addr)]; 805*34293Skarels if (spte->pg_v == 0) panic("kdbmap"); 806*34293Skarels kdbstats.ks_paget++; 807*34293Skarels *mapbase = PHYS(long, spte); 808*34293Skarels *offset = o; 809*34293Skarels *info = 0; 810*34293Skarels return (0); 811*34293Skarels } 812*34293Skarels 813*34293Skarels /* potentially discontiguous or invalid ptes */ 814*34293Skarels v = btop(bp->b_un.b_addr); 815*34293Skarels rp = bp->b_flags & B_DIRTY ? &proc[2] : bp->b_proc; 816*34293Skarels if (bp->b_flags & B_UAREA) 817*34293Skarels spte = &rp->p_addr[v]; 818*34293Skarels else 819*34293Skarels spte = vtopte(rp, v); 820*34293Skarels npf = btoc(bp->b_bcount + o); 821*34293Skarels 822*34293Skarels #ifdef notdef 823*34293Skarels /* 824*34293Skarels * The current implementation of the VM system requires 825*34293Skarels * that all of these be done with a copy. Even if the 826*34293Skarels * PTEs could be used now, they may be snatched out from 827*34293Skarels * under us later. It would be nice if we could stop that.... 828*34293Skarels */ 829*34293Skarels 830*34293Skarels /* check for invalid */ 831*34293Skarels /* CONSIDER CHANGING VM TO VALIDATE PAGES EARLIER */ 832*34293Skarels for (dpte = spte, i = npf; --i >= 0; dpte++) 833*34293Skarels if (dpte->pg_v == 0) 834*34293Skarels goto copy1; 835*34293Skarels /* 836*34293Skarels * Check for discontiguous physical pte addresses. It is 837*34293Skarels * not necessary to check each pte, since they come in clumps 838*34293Skarels * of pages. 839*34293Skarels */ 840*34293Skarels i = howmany(npf + (((int)spte & PGOFSET) / sizeof (*spte)), NPTEPG); 841*34293Skarels /* often i==1, and we can avoid work */ 842*34293Skarels if (--i > 0) { 843*34293Skarels dpte = kvtopte(spte); 844*34293Skarels a = dpte->pg_pfnum; 845*34293Skarels while (--i >= 0) 846*34293Skarels if ((++dpte)->pg_pfnum != ++a) 847*34293Skarels goto copy2; 848*34293Skarels } 849*34293Skarels 850*34293Skarels /* made it */ 851*34293Skarels kdbstats.ks_contig++; 852*34293Skarels *mapbase = kvtophys(spte); 853*34293Skarels *offset = o; 854*34293Skarels *info = 0; 855*34293Skarels return (0); 856*34293Skarels 857*34293Skarels copy1: 858*34293Skarels kdbstats.ks_inval++; /* temp */ 859*34293Skarels copy2: 860*34293Skarels #endif /* notdef */ 861*34293Skarels kdbstats.ks_copies++; 862*34293Skarels i = npf + 1; 863*34293Skarels if ((a = rmalloc(ki->ki_map, (long) i)) == 0) { 864*34293Skarels kdbstats.ks_mapwait++; 865*34293Skarels return (-1); 866*34293Skarels } 867*34293Skarels *info = (i << 16) | a; 868*34293Skarels a--; 869*34293Skarels /* if offset > PGOFSET, btop(offset) indexes mapbase */ 870*34293Skarels *mapbase = ki->ki_ptephys; 871*34293Skarels *offset = (a << PGSHIFT) | o; 872*34293Skarels dpte = &ki->ki_pte[a]; 873*34293Skarels while (--i > 0) 874*34293Skarels *(int *)dpte++ = PG_V | *(int *)spte++; 875*34293Skarels *(int *)dpte = 0; 876*34293Skarels return (0); 877*34293Skarels } 878*34293Skarels 879*34293Skarels #define KDBFREE(ki, info) if (info) \ 880*34293Skarels rmfree((ki)->ki_map, (long)((info) >> 16), (long)((info) & 0xffff)) 881*34293Skarels 882*34293Skarels /* 883*34293Skarels * Start up whatever transfers we can find. 884*34293Skarels * Note that kdbstart() must be called at spl5(). 885*34293Skarels */ 886*34293Skarels kdbstart(ki) 887*34293Skarels register struct kdbinfo *ki; 888*34293Skarels { 889*34293Skarels register struct buf *bp, *dp; 890*34293Skarels register struct mscp *mp; 891*34293Skarels register struct uba_device *ui; 892*34293Skarels long mapbase, offset; 893*34293Skarels int info, ncmd = 0; 894*34293Skarels 895*34293Skarels /* 896*34293Skarels * If it is not running, try (again and again...) to initialise 897*34293Skarels * it. If it is currently initialising just ignore it for now. 898*34293Skarels */ 899*34293Skarels if (ki->ki_state != ST_RUN) { 900*34293Skarels if (ki->ki_state == ST_IDLE && kdbinit(ki)) 901*34293Skarels printf("kdb%d: still hung\n", ki->ki_ctlr); 902*34293Skarels return; 903*34293Skarels } 904*34293Skarels 905*34293Skarels loop: 906*34293Skarels /* if insufficient credit, avoid overhead */ 907*34293Skarels if (ki->ki_mi.mi_credits <= MSCP_MINCREDITS) 908*34293Skarels goto out; 909*34293Skarels 910*34293Skarels /* 911*34293Skarels * Service the drive at the head of the queue. We take exactly 912*34293Skarels * one transfer from this drive, then move it to the end of the 913*34293Skarels * controller queue, so as to get more drive overlap. 914*34293Skarels */ 915*34293Skarels if ((dp = ki->ki_tab.b_actf) == NULL) 916*34293Skarels goto out; 917*34293Skarels 918*34293Skarels /* 919*34293Skarels * Get the first request from the drive queue. There must be 920*34293Skarels * one, or something is rotten. 921*34293Skarels */ 922*34293Skarels if ((bp = dp->b_actf) == NULL) 923*34293Skarels panic("kdbstart: bp==NULL\n"); 924*34293Skarels 925*34293Skarels if (ki->ki_kdb->kdb_sa & KDB_ERR) { /* ctlr fatal error */ 926*34293Skarels kdbsaerror(ki); 927*34293Skarels goto out; 928*34293Skarels } 929*34293Skarels 930*34293Skarels /* find or create maps for this transfer */ 931*34293Skarels if (kdbmap(ki, bp, &mapbase, &offset, &info)) 932*34293Skarels goto out; /* effectively, resource wait */ 933*34293Skarels 934*34293Skarels /* 935*34293Skarels * Get an MSCP packet, then figure out what to do. If 936*34293Skarels * we cannot get a command packet, the command ring may 937*34293Skarels * be too small: We should have at least as many command 938*34293Skarels * packets as credits, for best performance. 939*34293Skarels */ 940*34293Skarels if ((mp = mscp_getcp(&ki->ki_mi, MSCP_DONTWAIT)) == NULL) { 941*34293Skarels if (ki->ki_mi.mi_credits > MSCP_MINCREDITS && 942*34293Skarels (ki->ki_flags & KDB_GRIPED) == 0) { 943*34293Skarels log(LOG_NOTICE, "kdb%d: command ring too small\n", 944*34293Skarels ki->ki_ctlr); 945*34293Skarels ki->ki_flags |= KDB_GRIPED;/* complain only once */ 946*34293Skarels } 947*34293Skarels KDBFREE(ki, info); 948*34293Skarels goto out; 949*34293Skarels } 950*34293Skarels 951*34293Skarels /* 952*34293Skarels * Bring the drive on line if it is not already. Get its status 953*34293Skarels * if we do not already have it. Otherwise just start the transfer. 954*34293Skarels */ 955*34293Skarels ui = kdbdinfo[kdbunit(bp->b_dev)]; 956*34293Skarels if ((ui->ui_flags & UNIT_ONLINE) == 0) { 957*34293Skarels mp->mscp_opcode = M_OP_ONLINE; 958*34293Skarels goto common; 959*34293Skarels } 960*34293Skarels if ((ui->ui_flags & UNIT_HAVESTATUS) == 0) { 961*34293Skarels mp->mscp_opcode = M_OP_GETUNITST; 962*34293Skarels common: 963*34293Skarels if (ui->ui_flags & UNIT_REQUEUE) panic("kdbstart"); 964*34293Skarels /* 965*34293Skarels * Take the drive off the controller queue. When the 966*34293Skarels * command finishes, make sure the drive is requeued. 967*34293Skarels * Give up any mapping (not needed now). This last is 968*34293Skarels * not efficient, but is rare. 969*34293Skarels */ 970*34293Skarels KDBFREE(ki, info); 971*34293Skarels ki->ki_tab.b_actf = dp->b_forw; 972*34293Skarels dp->b_active = 0; 973*34293Skarels ui->ui_flags |= UNIT_REQUEUE; 974*34293Skarels mp->mscp_unit = ui->ui_slave; 975*34293Skarels *mp->mscp_addr |= MSCP_OWN | MSCP_INT; 976*34293Skarels ncmd++; 977*34293Skarels goto loop; 978*34293Skarels } 979*34293Skarels 980*34293Skarels mp->mscp_opcode = (bp->b_flags & B_READ) ? M_OP_READ : M_OP_WRITE; 981*34293Skarels mp->mscp_unit = ui->ui_slave; 982*34293Skarels mp->mscp_seq.seq_lbn = bp->b_blkno + 983*34293Skarels kdbtypes[ui->ui_type].ut_sizes[kdbpart(bp->b_dev)].blkoff; 984*34293Skarels mp->mscp_seq.seq_bytecount = bp->b_bcount; 985*34293Skarels 986*34293Skarels mp->mscp_seq.seq_buffer = offset | KDB_MAP; 987*34293Skarels mp->mscp_seq.seq_mapbase = mapbase; 988*34293Skarels 989*34293Skarels /* profile the drive */ 990*34293Skarels if (ui->ui_dk >= 0) { 991*34293Skarels dk_busy |= 1 << ui->ui_dk; 992*34293Skarels dk_xfer[ui->ui_dk]++; 993*34293Skarels dk_wds[ui->ui_dk] += bp->b_bcount >> 6; 994*34293Skarels } 995*34293Skarels 996*34293Skarels /* 997*34293Skarels * Fill in the rest of the MSCP packet and move the buffer to the 998*34293Skarels * I/O wait queue. 999*34293Skarels */ 1000*34293Skarels mscp_go(&ki->ki_mi, mp, info); 1001*34293Skarels ncmd++; /* note the transfer */ 1002*34293Skarels ki->ki_tab.b_active++; /* another one going */ 1003*34293Skarels goto loop; 1004*34293Skarels 1005*34293Skarels out: 1006*34293Skarels if (ncmd >= KS_MAXC) 1007*34293Skarels ncmd = KS_MAXC - 1; 1008*34293Skarels kdbstats.ks_cmd[ncmd]++; 1009*34293Skarels if (ncmd) /* start some transfers */ 1010*34293Skarels ncmd = ki->ki_kdb->kdb_ip; 1011*34293Skarels } 1012*34293Skarels 1013*34293Skarels /* ARGSUSED */ 1014*34293Skarels kdbiodone(mi, bp, info) 1015*34293Skarels struct mscp_info *mi; 1016*34293Skarels struct buf *bp; 1017*34293Skarels int info; 1018*34293Skarels { 1019*34293Skarels register struct kdbinfo *ki = &kdbinfo[mi->mi_ctlr]; 1020*34293Skarels 1021*34293Skarels KDBFREE(ki, info); 1022*34293Skarels biodone(bp); 1023*34293Skarels ki->ki_tab.b_active--; /* another one done */ 1024*34293Skarels } 1025*34293Skarels 1026*34293Skarels /* 1027*34293Skarels * The error bit was set in the controller status register. Gripe, 1028*34293Skarels * reset the controller, requeue pending transfers. 1029*34293Skarels */ 1030*34293Skarels kdbsaerror(ki) 1031*34293Skarels register struct kdbinfo *ki; 1032*34293Skarels { 1033*34293Skarels 1034*34293Skarels printf("kdb%d: controller error, sa=%b\n", ki->ki_ctlr, 1035*34293Skarels ki->ki_kdb->kdb_sa, kdbsr_bits); 1036*34293Skarels mscp_requeue(&ki->ki_mi); 1037*34293Skarels (void) kdbinit(ki); 1038*34293Skarels } 1039*34293Skarels 1040*34293Skarels /* 1041*34293Skarels * Interrupt routine. Depending on the state of the controller, 1042*34293Skarels * continue initialisation, or acknowledge command and response 1043*34293Skarels * interrupts, and process responses. 1044*34293Skarels */ 1045*34293Skarels kdbintr(ctlr) 1046*34293Skarels int ctlr; 1047*34293Skarels { 1048*34293Skarels register struct kdbinfo *ki = &kdbinfo[ctlr]; 1049*34293Skarels register struct kdb_regs *kdbaddr = ki->ki_kdb; 1050*34293Skarels register struct mscp *mp; 1051*34293Skarels register int i; 1052*34293Skarels 1053*34293Skarels ki->ki_wticks = 0; /* reset interrupt watchdog */ 1054*34293Skarels 1055*34293Skarels /* 1056*34293Skarels * Combinations during steps 1, 2, and 3: STEPnMASK 1057*34293Skarels * corresponds to which bits should be tested; 1058*34293Skarels * STEPnGOOD corresponds to the pattern that should 1059*34293Skarels * appear after the interrupt from STEPn initialisation. 1060*34293Skarels * All steps test the bits in ALLSTEPS. 1061*34293Skarels */ 1062*34293Skarels #define ALLSTEPS (KDB_ERR|KDB_STEP4|KDB_STEP3|KDB_STEP2|KDB_STEP1) 1063*34293Skarels 1064*34293Skarels #define STEP1MASK (ALLSTEPS | KDB_IE | KDB_NCNRMASK) 1065*34293Skarels #define STEP1GOOD (KDB_STEP2 | KDB_IE | (NCMDL2 << 3) | NRSPL2) 1066*34293Skarels 1067*34293Skarels #define STEP2MASK (ALLSTEPS | KDB_IE | KDB_IVECMASK) 1068*34293Skarels #define STEP2GOOD (KDB_STEP3 | KDB_IE | (ki->ki_vec >> 2)) 1069*34293Skarels 1070*34293Skarels #define STEP3MASK ALLSTEPS 1071*34293Skarels #define STEP3GOOD KDB_STEP4 1072*34293Skarels 1073*34293Skarels switch (ki->ki_state) { 1074*34293Skarels 1075*34293Skarels case ST_IDLE: 1076*34293Skarels /* 1077*34293Skarels * Ignore unsolicited interrupts. 1078*34293Skarels */ 1079*34293Skarels log(LOG_WARNING, "kdb%d: stray intr\n", ctlr); 1080*34293Skarels return; 1081*34293Skarels 1082*34293Skarels case ST_STEP1: 1083*34293Skarels /* 1084*34293Skarels * Begin step two initialisation. 1085*34293Skarels */ 1086*34293Skarels if ((kdbaddr->kdb_sa & STEP1MASK) != STEP1GOOD) { 1087*34293Skarels i = 1; 1088*34293Skarels initfailed: 1089*34293Skarels printf("kdb%d: init step %d failed, sa=%b\n", 1090*34293Skarels ctlr, i, kdbaddr->kdb_sa, kdbsr_bits); 1091*34293Skarels ki->ki_state = ST_IDLE; 1092*34293Skarels if (ki->ki_flags & KDB_DOWAKE) { 1093*34293Skarels ki->ki_flags &= ~KDB_DOWAKE; 1094*34293Skarels wakeup((caddr_t) &ki->ki_flags); 1095*34293Skarels } 1096*34293Skarels return; 1097*34293Skarels } 1098*34293Skarels kdbaddr->kdb_sw = PHYS(int, &ki->ki_ca.ca_rspdsc[0]); 1099*34293Skarels ki->ki_state = ST_STEP2; 1100*34293Skarels return; 1101*34293Skarels 1102*34293Skarels case ST_STEP2: 1103*34293Skarels /* 1104*34293Skarels * Begin step 3 initialisation. 1105*34293Skarels */ 1106*34293Skarels if ((kdbaddr->kdb_sa & STEP2MASK) != STEP2GOOD) { 1107*34293Skarels i = 2; 1108*34293Skarels goto initfailed; 1109*34293Skarels } 1110*34293Skarels kdbaddr->kdb_sw = PHYS(int, &ki->ki_ca.ca_rspdsc[0]) >> 16; 1111*34293Skarels ki->ki_state = ST_STEP3; 1112*34293Skarels return; 1113*34293Skarels 1114*34293Skarels case ST_STEP3: 1115*34293Skarels /* 1116*34293Skarels * Set controller characteristics (finish initialisation). 1117*34293Skarels */ 1118*34293Skarels if ((kdbaddr->kdb_sa & STEP3MASK) != STEP3GOOD) { 1119*34293Skarels i = 3; 1120*34293Skarels goto initfailed; 1121*34293Skarels } 1122*34293Skarels i = kdbaddr->kdb_sa & 0xff; 1123*34293Skarels if (i != ki->ki_micro) { 1124*34293Skarels ki->ki_micro = i; 1125*34293Skarels printf("kdb%d: version %d model %d\n", 1126*34293Skarels ctlr, i & 0xf, i >> 4); 1127*34293Skarels } 1128*34293Skarels 1129*34293Skarels kdbaddr->kdb_sw = KDB_GO; 1130*34293Skarels 1131*34293Skarels /* initialise hardware data structures */ 1132*34293Skarels for (i = 0, mp = ki->ki_rsp; i < NRSP; i++, mp++) { 1133*34293Skarels ki->ki_ca.ca_rspdsc[i] = MSCP_OWN | MSCP_INT | 1134*34293Skarels PHYS(long, &ki->ki_rsp[i].mscp_cmdref); 1135*34293Skarels mp->mscp_addr = &ki->ki_ca.ca_rspdsc[i]; 1136*34293Skarels mp->mscp_msglen = MSCP_MSGLEN; 1137*34293Skarels } 1138*34293Skarels for (i = 0, mp = ki->ki_cmd; i < NCMD; i++, mp++) { 1139*34293Skarels ki->ki_ca.ca_cmddsc[i] = MSCP_INT | 1140*34293Skarels PHYS(long, &ki->ki_cmd[i].mscp_cmdref); 1141*34293Skarels mp->mscp_addr = &ki->ki_ca.ca_cmddsc[i]; 1142*34293Skarels mp->mscp_msglen = MSCP_MSGLEN; 1143*34293Skarels } 1144*34293Skarels 1145*34293Skarels /* 1146*34293Skarels * Before we can get a command packet, we need some 1147*34293Skarels * credits. Fake some up to keep mscp_getcp() happy, 1148*34293Skarels * get a packet, and cancel all credits (the right 1149*34293Skarels * number should come back in the response to the 1150*34293Skarels * SCC packet). 1151*34293Skarels */ 1152*34293Skarels ki->ki_mi.mi_credits = MSCP_MINCREDITS + 1; 1153*34293Skarels mp = mscp_getcp(&ki->ki_mi, MSCP_DONTWAIT); 1154*34293Skarels if (mp == NULL) /* `cannot happen' */ 1155*34293Skarels panic("kdbintr"); 1156*34293Skarels ki->ki_mi.mi_credits = 0; 1157*34293Skarels mp->mscp_opcode = M_OP_SETCTLRC; 1158*34293Skarels mp->mscp_unit = 0; 1159*34293Skarels mp->mscp_sccc.sccc_ctlrflags = M_CF_ATTN | M_CF_MISC | 1160*34293Skarels M_CF_THIS; 1161*34293Skarels *mp->mscp_addr |= MSCP_OWN | MSCP_INT; 1162*34293Skarels i = kdbaddr->kdb_ip; 1163*34293Skarels ki->ki_state = ST_SETCHAR; 1164*34293Skarels return; 1165*34293Skarels 1166*34293Skarels case ST_SETCHAR: 1167*34293Skarels case ST_RUN: 1168*34293Skarels /* 1169*34293Skarels * Handle Set Ctlr Characteristics responses and operational 1170*34293Skarels * responses (via mscp_dorsp). 1171*34293Skarels */ 1172*34293Skarels break; 1173*34293Skarels 1174*34293Skarels default: 1175*34293Skarels log(LOG_ERR, "kdb%d: driver bug, state %d\n", ctlr, 1176*34293Skarels ki->ki_state); 1177*34293Skarels return; 1178*34293Skarels } 1179*34293Skarels 1180*34293Skarels if (kdbaddr->kdb_sa & KDB_ERR) {/* ctlr fatal error */ 1181*34293Skarels kdbsaerror(ki); 1182*34293Skarels return; 1183*34293Skarels } 1184*34293Skarels 1185*34293Skarels /* 1186*34293Skarels * Handle buffer purge requests. 1187*34293Skarels * KDB DOES NOT HAVE BDPs 1188*34293Skarels */ 1189*34293Skarels if (ki->ki_ca.ca_bdp) { 1190*34293Skarels printf("kdb%d: purge bdp %d\n", ctlr, ki->ki_ca.ca_bdp); 1191*34293Skarels panic("kdb purge"); 1192*34293Skarels } 1193*34293Skarels 1194*34293Skarels /* 1195*34293Skarels * Check for response and command ring transitions. 1196*34293Skarels */ 1197*34293Skarels if (ki->ki_ca.ca_rspint) { 1198*34293Skarels ki->ki_ca.ca_rspint = 0; 1199*34293Skarels mscp_dorsp(&ki->ki_mi); 1200*34293Skarels } 1201*34293Skarels if (ki->ki_ca.ca_cmdint) { 1202*34293Skarels ki->ki_ca.ca_cmdint = 0; 1203*34293Skarels MSCP_DOCMD(&ki->ki_mi); 1204*34293Skarels } 1205*34293Skarels if (ki->ki_tab.b_actf != NULL) 1206*34293Skarels kdbstart(ki); 1207*34293Skarels } 1208*34293Skarels 1209*34293Skarels /* 1210*34293Skarels * Handle an error datagram. All we do now is decode it. 1211*34293Skarels */ 1212*34293Skarels kdbdgram(mi, mp) 1213*34293Skarels struct mscp_info *mi; 1214*34293Skarels struct mscp *mp; 1215*34293Skarels { 1216*34293Skarels 1217*34293Skarels mscp_decodeerror(mi->mi_md->md_mname, mi->mi_ctlr, mp); 1218*34293Skarels } 1219*34293Skarels 1220*34293Skarels /* 1221*34293Skarels * The Set Controller Characteristics command finished. 1222*34293Skarels * Record the new state of the controller. 1223*34293Skarels */ 1224*34293Skarels kdbctlrdone(mi, mp) 1225*34293Skarels struct mscp_info *mi; 1226*34293Skarels struct mscp *mp; 1227*34293Skarels { 1228*34293Skarels register struct kdbinfo *ki = &kdbinfo[mi->mi_ctlr]; 1229*34293Skarels 1230*34293Skarels if ((mp->mscp_status & M_ST_MASK) == M_ST_SUCCESS) 1231*34293Skarels ki->ki_state = ST_RUN; 1232*34293Skarels else { 1233*34293Skarels printf("kdb%d: SETCTLRC failed, status 0x%x\n", 1234*34293Skarels ki->ki_ctlr, mp->mscp_status); 1235*34293Skarels ki->ki_state = ST_IDLE; 1236*34293Skarels } 1237*34293Skarels if (ki->ki_flags & KDB_DOWAKE) { 1238*34293Skarels ki->ki_flags &= ~KDB_DOWAKE; 1239*34293Skarels wakeup((caddr_t) &ki->ki_flags); 1240*34293Skarels } 1241*34293Skarels } 1242*34293Skarels 1243*34293Skarels /* 1244*34293Skarels * Received a response from an as-yet unconfigured drive. Configure it 1245*34293Skarels * in, if possible. 1246*34293Skarels */ 1247*34293Skarels kdbunconf(mi, mp) 1248*34293Skarels struct mscp_info *mi; 1249*34293Skarels register struct mscp *mp; 1250*34293Skarels { 1251*34293Skarels 1252*34293Skarels /* 1253*34293Skarels * If it is a slave response, copy it to kdbslavereply for 1254*34293Skarels * kdbslave() to look at. 1255*34293Skarels */ 1256*34293Skarels if (mp->mscp_opcode == (M_OP_GETUNITST | M_OP_END) && 1257*34293Skarels (kdbinfo[mi->mi_ctlr].ki_flags & KDB_INSLAVE) != 0) { 1258*34293Skarels kdbslavereply = *mp; 1259*34293Skarels return (MSCP_DONE); 1260*34293Skarels } 1261*34293Skarels 1262*34293Skarels /* 1263*34293Skarels * Otherwise, it had better be an available attention response. 1264*34293Skarels */ 1265*34293Skarels if (mp->mscp_opcode != M_OP_AVAILATTN) 1266*34293Skarels return (MSCP_FAILED); 1267*34293Skarels 1268*34293Skarels /* do what autoconf does */ 1269*34293Skarels return (MSCP_FAILED); /* not yet */ 1270*34293Skarels } 1271*34293Skarels 1272*34293Skarels /* 1273*34293Skarels * A drive came on line. Check its type and size. Return DONE if 1274*34293Skarels * we think the drive is truly on line. In any case, awaken anyone 1275*34293Skarels * sleeping on the drive on-line-ness. 1276*34293Skarels */ 1277*34293Skarels kdbonline(ui, mp) 1278*34293Skarels register struct uba_device *ui; 1279*34293Skarels struct mscp *mp; 1280*34293Skarels { 1281*34293Skarels register int type; 1282*34293Skarels 1283*34293Skarels wakeup((caddr_t) &ui->ui_flags); 1284*34293Skarels if ((mp->mscp_status & M_ST_MASK) != M_ST_SUCCESS) { 1285*34293Skarels printf("kdb%d: attempt to bring %s%d on line failed: ", 1286*34293Skarels ui->ui_ctlr, kdbdriver.ud_dname, ui->ui_unit); 1287*34293Skarels mscp_printevent(mp); 1288*34293Skarels return (MSCP_FAILED); 1289*34293Skarels } 1290*34293Skarels 1291*34293Skarels type = mp->mscp_onle.onle_drivetype; 1292*34293Skarels if (type >= NTYPES || kdbtypes[type].ut_name == 0) { 1293*34293Skarels printf("kdb%d: %s%d: unknown type %d\n", 1294*34293Skarels ui->ui_ctlr, kdbdriver.ud_dname, ui->ui_unit, type); 1295*34293Skarels return (MSCP_FAILED); 1296*34293Skarels } 1297*34293Skarels /* 1298*34293Skarels * Note any change of types. Not sure if we should do 1299*34293Skarels * something special about them, or if so, what.... 1300*34293Skarels */ 1301*34293Skarels if (type != ui->ui_type) { 1302*34293Skarels printf("%s%d: changed types! was %s\n", 1303*34293Skarels kdbdriver.ud_dname, ui->ui_unit, 1304*34293Skarels kdbtypes[ui->ui_type].ut_name); 1305*34293Skarels ui->ui_type = type; 1306*34293Skarels } 1307*34293Skarels ra_dsize[ui->ui_unit] = (daddr_t) mp->mscp_onle.onle_unitsize; 1308*34293Skarels printf("%s%d: %s, size = %d sectors\n", 1309*34293Skarels kdbdriver.ud_dname, ui->ui_unit, 1310*34293Skarels kdbtypes[type].ut_name, ra_dsize[ui->ui_unit]); 1311*34293Skarels return (MSCP_DONE); 1312*34293Skarels } 1313*34293Skarels 1314*34293Skarels /* 1315*34293Skarels * We got some (configured) unit's status. Return DONE if it succeeded. 1316*34293Skarels */ 1317*34293Skarels kdbgotstatus(ui, mp) 1318*34293Skarels register struct uba_device *ui; 1319*34293Skarels register struct mscp *mp; 1320*34293Skarels { 1321*34293Skarels 1322*34293Skarels if ((mp->mscp_status & M_ST_MASK) != M_ST_SUCCESS) { 1323*34293Skarels printf("kdb%d: attempt to get status for %s%d failed: ", 1324*34293Skarels ui->ui_ctlr, kdbdriver.ud_dname, ui->ui_unit); 1325*34293Skarels mscp_printevent(mp); 1326*34293Skarels return (MSCP_FAILED); 1327*34293Skarels } 1328*34293Skarels /* need to record later for bad block forwarding - for now, print */ 1329*34293Skarels printf("\ 1330*34293Skarels %s%d: unit %d, nspt %d, group %d, ngpc %d, rctsize %d, nrpt %d, nrct %d\n", 1331*34293Skarels kdbdriver.ud_dname, ui->ui_unit, mp->mscp_unit, 1332*34293Skarels mp->mscp_guse.guse_nspt, mp->mscp_guse.guse_group, 1333*34293Skarels mp->mscp_guse.guse_ngpc, mp->mscp_guse.guse_rctsize, 1334*34293Skarels mp->mscp_guse.guse_nrpt, mp->mscp_guse.guse_nrct); 1335*34293Skarels return (MSCP_DONE); 1336*34293Skarels } 1337*34293Skarels 1338*34293Skarels /* 1339*34293Skarels * A transfer failed. We get a chance to fix or restart it. 1340*34293Skarels * Need to write the bad block forwaring code first.... 1341*34293Skarels */ 1342*34293Skarels /*ARGSUSED*/ 1343*34293Skarels kdbioerror(ui, mp, bp) 1344*34293Skarels register struct uba_device *ui; 1345*34293Skarels register struct mscp *mp; 1346*34293Skarels struct buf *bp; 1347*34293Skarels { 1348*34293Skarels 1349*34293Skarels if (mp->mscp_flags & M_EF_BBLKR) { 1350*34293Skarels /* 1351*34293Skarels * A bad block report. Eventually we will 1352*34293Skarels * restart this transfer, but for now, just 1353*34293Skarels * log it and give up. 1354*34293Skarels */ 1355*34293Skarels log(LOG_ERR, "%s%d: bad block report: %d%s\n", 1356*34293Skarels kdbdriver.ud_dname, ui->ui_unit, mp->mscp_seq.seq_lbn, 1357*34293Skarels mp->mscp_flags & M_EF_BBLKU ? " + others" : ""); 1358*34293Skarels } else { 1359*34293Skarels /* 1360*34293Skarels * What the heck IS a `serious exception' anyway? 1361*34293Skarels */ 1362*34293Skarels if (mp->mscp_flags & M_EF_SEREX) 1363*34293Skarels log(LOG_ERR, "%s%d: serious exception reported\n", 1364*34293Skarels kdbdriver.ud_dname, ui->ui_unit); 1365*34293Skarels } 1366*34293Skarels return (MSCP_FAILED); 1367*34293Skarels } 1368*34293Skarels 1369*34293Skarels 1370*34293Skarels #ifdef notyet 1371*34293Skarels /* 1372*34293Skarels * I/O controls. Not yet! 1373*34293Skarels */ 1374*34293Skarels kdbioctl(dev, cmd, flag, data) 1375*34293Skarels dev_t dev; 1376*34293Skarels int cmd, flag; 1377*34293Skarels caddr_t data; 1378*34293Skarels { 1379*34293Skarels int error = 0; 1380*34293Skarels register int unit = kdbunit(dev); 1381*34293Skarels 1382*34293Skarels if (unit >= NKRA || uddinfo[unit] == NULL) 1383*34293Skarels return (ENXIO); 1384*34293Skarels 1385*34293Skarels switch (cmd) { 1386*34293Skarels 1387*34293Skarels case KDBIOCREPLACE: 1388*34293Skarels /* 1389*34293Skarels * Initiate bad block replacement for the given LBN. 1390*34293Skarels * (Should we allow modifiers?) 1391*34293Skarels */ 1392*34293Skarels error = EOPNOTSUPP; 1393*34293Skarels break; 1394*34293Skarels 1395*34293Skarels case KDBIOCGMICRO: 1396*34293Skarels /* 1397*34293Skarels * Return the microcode revision for the KDB50 running 1398*34293Skarels * this drive. 1399*34293Skarels */ 1400*34293Skarels *(int *) data = kdbinfo[kdbdinfo[unit]->ui_ctlr].ki_micro; 1401*34293Skarels break; 1402*34293Skarels 1403*34293Skarels case KDBIOCGSIZE: 1404*34293Skarels /* 1405*34293Skarels * Return the size (in 512 byte blocks) of this 1406*34293Skarels * disk drive. 1407*34293Skarels */ 1408*34293Skarels *(daddr_t *) data = ra_dsize[unit]; 1409*34293Skarels break; 1410*34293Skarels 1411*34293Skarels default: 1412*34293Skarels error = EINVAL; 1413*34293Skarels break; 1414*34293Skarels } 1415*34293Skarels return (error); 1416*34293Skarels } 1417*34293Skarels #endif 1418*34293Skarels 1419*34293Skarels #ifdef notyet 1420*34293Skarels /* 1421*34293Skarels * Reset a KDB50 (self test and all). 1422*34293Skarels * What if it fails? 1423*34293Skarels */ 1424*34293Skarels kdbreset(ki) 1425*34293Skarels register struct kdbinfo *ki; 1426*34293Skarels { 1427*34293Skarels 1428*34293Skarels printf("reset kdb%d", ki->ki_ctlr); 1429*34293Skarels bi_selftest(&ki->ki_kdb.kdb_bi); 1430*34293Skarels ki->ki_state = ST_IDLE; 1431*34293Skarels rminit(ki->ki_map, (long)KI_PTES, (long)1, "kdb", KI_MAPSIZ); 1432*34293Skarels mscp_requeue(&ki->ki_mi); 1433*34293Skarels if (kdbinit(ctlr)) 1434*34293Skarels printf(" (hung)"); 1435*34293Skarels printf("\n"); 1436*34293Skarels } 1437*34293Skarels #endif 1438*34293Skarels 1439*34293Skarels /* 1440*34293Skarels * Watchdog timer: If the controller is active, and no interrupts 1441*34293Skarels * have occurred for 30 seconds, assume it has gone away. 1442*34293Skarels */ 1443*34293Skarels kdbwatch() 1444*34293Skarels { 1445*34293Skarels register struct kdbinfo *ki; 1446*34293Skarels register int i; 1447*34293Skarels 1448*34293Skarels timeout(kdbwatch, (caddr_t) 0, hz); /* every second */ 1449*34293Skarels for (i = 0, ki = kdbinfo; i < NKDB; i++, ki++) { 1450*34293Skarels if ((ki->ki_flags & KDB_ALIVE) == 0) 1451*34293Skarels continue; 1452*34293Skarels if (ki->ki_state == ST_IDLE) 1453*34293Skarels continue; 1454*34293Skarels if (ki->ki_state == ST_RUN && !ki->ki_tab.b_active) 1455*34293Skarels ki->ki_wticks = 0; 1456*34293Skarels else if (++ki->ki_wticks >= 30) { 1457*34293Skarels ki->ki_wticks = 0; 1458*34293Skarels printf("kdb%d: lost interrupt\n", i); 1459*34293Skarels /* kdbreset(ki); */ 1460*34293Skarels panic("kdb lost interrupt"); 1461*34293Skarels } 1462*34293Skarels } 1463*34293Skarels } 1464*34293Skarels 1465*34293Skarels /* 1466*34293Skarels * Do a panic dump. 1467*34293Skarels */ 1468*34293Skarels #define DBSIZE 32 /* dump 16K at a time */ 1469*34293Skarels 1470*34293Skarels struct kdbdumpspace { 1471*34293Skarels struct kdb1ca kd_ca; 1472*34293Skarels struct mscp kd_rsp; 1473*34293Skarels struct mscp kd_cmd; 1474*34293Skarels } kdbdumpspace; 1475*34293Skarels 1476*34293Skarels kdbdump(dev) 1477*34293Skarels dev_t dev; 1478*34293Skarels { 1479*34293Skarels register struct kdbdumpspace *kd; 1480*34293Skarels register struct kdb_regs *k; 1481*34293Skarels register int i; 1482*34293Skarels struct uba_device *ui; 1483*34293Skarels char *start; 1484*34293Skarels int num, blk, unit, maxsz, blkoff; 1485*34293Skarels 1486*34293Skarels /* 1487*34293Skarels * Make sure the device is a reasonable place on which to dump. 1488*34293Skarels */ 1489*34293Skarels unit = kdbunit(dev); 1490*34293Skarels if (unit >= NKRA) 1491*34293Skarels return (ENXIO); 1492*34293Skarels ui = PHYS(struct uba_device *, kdbdinfo[unit]); 1493*34293Skarels if (ui == NULL || ui->ui_alive == 0) 1494*34293Skarels return (ENXIO); 1495*34293Skarels 1496*34293Skarels /* 1497*34293Skarels * Find and initialise the KDB; get the physical address of the 1498*34293Skarels * device registers, and of communications area and command and 1499*34293Skarels * response packet. 1500*34293Skarels */ 1501*34293Skarels k = PHYS(struct kdbinfo *, &kdbinfo[ui->ui_ctlr])->ki_physkdb; 1502*34293Skarels kd = PHYS(struct kdbdumpspace *, &kdbdumpspace); 1503*34293Skarels 1504*34293Skarels /* 1505*34293Skarels * Initialise the controller, with one command and one response 1506*34293Skarels * packet. 1507*34293Skarels */ 1508*34293Skarels bi_reset(&k->kdb_bi); 1509*34293Skarels if (kdbdumpwait(k, KDB_STEP1)) 1510*34293Skarels return (EFAULT); 1511*34293Skarels k->kdb_sw = KDB_ERR; 1512*34293Skarels if (kdbdumpwait(k, KDB_STEP2)) 1513*34293Skarels return (EFAULT); 1514*34293Skarels k->kdb_sw = (int) &kd->kd_ca.ca_rspdsc; 1515*34293Skarels if (kdbdumpwait(k, KDB_STEP3)) 1516*34293Skarels return (EFAULT); 1517*34293Skarels k->kdb_sw = ((int) &kd->kd_ca.ca_rspdsc) >> 16; 1518*34293Skarels if (kdbdumpwait(k, KDB_STEP4)) 1519*34293Skarels return (EFAULT); 1520*34293Skarels k->kdb_sw = KDB_GO; 1521*34293Skarels 1522*34293Skarels /* 1523*34293Skarels * Set up the command and response descriptor, then set the 1524*34293Skarels * controller characteristics and bring the drive on line. 1525*34293Skarels * Note that all uninitialised locations in kd_cmd are zero. 1526*34293Skarels */ 1527*34293Skarels kd->kd_ca.ca_rspdsc = (long) &kd->kd_rsp.mscp_cmdref; 1528*34293Skarels kd->kd_ca.ca_cmddsc = (long) &kd->kd_cmd.mscp_cmdref; 1529*34293Skarels /* kd->kd_cmd.mscp_sccc.sccc_ctlrflags = 0; */ 1530*34293Skarels /* kd->kd_cmd.mscp_sccc.sccc_version = 0; */ 1531*34293Skarels if (kdbdumpcmd(M_OP_SETCTLRC, k, kd, ui->ui_ctlr)) 1532*34293Skarels return (EFAULT); 1533*34293Skarels kd->kd_cmd.mscp_unit = ui->ui_slave; 1534*34293Skarels if (kdbdumpcmd(M_OP_ONLINE, k, kd, ui->ui_ctlr)) 1535*34293Skarels return (EFAULT); 1536*34293Skarels 1537*34293Skarels /* 1538*34293Skarels * Pick up the drive type from the on line end packet; 1539*34293Skarels * convert that to a dump area size and a disk offset. 1540*34293Skarels * Note that the assembler uses pc-relative addressing 1541*34293Skarels * to get at kdbtypes[], no need for PHYS(). 1542*34293Skarels */ 1543*34293Skarels i = kd->kd_rsp.mscp_onle.onle_drivetype; 1544*34293Skarels if (i >= NTYPES || kdbtypes[i].ut_name == 0) { 1545*34293Skarels printf("disk type %d unknown\ndump "); 1546*34293Skarels return (EINVAL); 1547*34293Skarels } 1548*34293Skarels printf("on %s ", kdbtypes[i].ut_name); 1549*34293Skarels 1550*34293Skarels maxsz = kdbtypes[i].ut_sizes[kdbpart(dev)].nblocks; 1551*34293Skarels blkoff = kdbtypes[i].ut_sizes[kdbpart(dev)].blkoff; 1552*34293Skarels 1553*34293Skarels /* 1554*34293Skarels * Dump all of physical memory, or as much as will fit in the 1555*34293Skarels * space provided. 1556*34293Skarels */ 1557*34293Skarels start = 0; 1558*34293Skarels num = maxfree; 1559*34293Skarels if (dumplo < 0) 1560*34293Skarels return (EINVAL); 1561*34293Skarels if (dumplo + num >= maxsz) 1562*34293Skarels num = maxsz - dumplo; 1563*34293Skarels blkoff += dumplo; 1564*34293Skarels 1565*34293Skarels /* 1566*34293Skarels * Write out memory, DBSIZE pages at a time. 1567*34293Skarels * N.B.: this code depends on the fact that the sector 1568*34293Skarels * size == the page size. 1569*34293Skarels */ 1570*34293Skarels while (num > 0) { 1571*34293Skarels blk = num > DBSIZE ? DBSIZE : num; 1572*34293Skarels kd->kd_cmd.mscp_unit = ui->ui_slave; 1573*34293Skarels kd->kd_cmd.mscp_seq.seq_lbn = btop(start) + blkoff; 1574*34293Skarels kd->kd_cmd.mscp_seq.seq_bytecount = blk << PGSHIFT; 1575*34293Skarels kd->kd_cmd.mscp_seq.seq_buffer = (long)start | KDB_PHYS; 1576*34293Skarels if (kdbdumpcmd(M_OP_WRITE, k, kd, ui->ui_ctlr)) 1577*34293Skarels return (EIO); 1578*34293Skarels start += blk << PGSHIFT; 1579*34293Skarels num -= blk; 1580*34293Skarels } 1581*34293Skarels return (0); /* made it! */ 1582*34293Skarels } 1583*34293Skarels 1584*34293Skarels /* 1585*34293Skarels * Wait for some of the bits in `bits' to come on. If the error bit 1586*34293Skarels * comes on, or ten seconds pass without response, return true (error). 1587*34293Skarels */ 1588*34293Skarels kdbdumpwait(k, bits) 1589*34293Skarels register struct kdb_regs *k; 1590*34293Skarels register int bits; 1591*34293Skarels { 1592*34293Skarels register int timo = todr() + 1000; 1593*34293Skarels 1594*34293Skarels while ((k->kdb_sa & bits) == 0) { 1595*34293Skarels if (k->kdb_sa & KDB_ERR) { 1596*34293Skarels printf("kdb_sa=%b\ndump ", k->kdb_sa, kdbsr_bits); 1597*34293Skarels return (1); 1598*34293Skarels } 1599*34293Skarels if (todr() >= timo) { 1600*34293Skarels printf("timeout\ndump "); 1601*34293Skarels return (1); 1602*34293Skarels } 1603*34293Skarels } 1604*34293Skarels return (0); 1605*34293Skarels } 1606*34293Skarels 1607*34293Skarels /* 1608*34293Skarels * Feed a command to the KDB50, wait for its response, and return 1609*34293Skarels * true iff something went wrong. 1610*34293Skarels */ 1611*34293Skarels kdbdumpcmd(op, k, kd, ctlr) 1612*34293Skarels int op; 1613*34293Skarels register struct kdb_regs *k; 1614*34293Skarels register struct kdbdumpspace *kd; 1615*34293Skarels int ctlr; 1616*34293Skarels { 1617*34293Skarels register int n; 1618*34293Skarels #define mp (&kd->kd_rsp) 1619*34293Skarels 1620*34293Skarels kd->kd_cmd.mscp_opcode = op; 1621*34293Skarels kd->kd_cmd.mscp_msglen = MSCP_MSGLEN; 1622*34293Skarels kd->kd_rsp.mscp_msglen = MSCP_MSGLEN; 1623*34293Skarels kd->kd_ca.ca_rspdsc |= MSCP_OWN | MSCP_INT; 1624*34293Skarels kd->kd_ca.ca_cmddsc |= MSCP_OWN | MSCP_INT; 1625*34293Skarels if (k->kdb_sa & KDB_ERR) { 1626*34293Skarels printf("kdb_sa=%b\ndump ", k->kdb_sa, kdbsr_bits); 1627*34293Skarels return (1); 1628*34293Skarels } 1629*34293Skarels n = k->kdb_ip; 1630*34293Skarels n = todr() + 1000; 1631*34293Skarels for (;;) { 1632*34293Skarels if (todr() > n) { 1633*34293Skarels printf("timeout\ndump "); 1634*34293Skarels return (1); 1635*34293Skarels } 1636*34293Skarels if (kd->kd_ca.ca_cmdint) 1637*34293Skarels kd->kd_ca.ca_cmdint = 0; 1638*34293Skarels if (kd->kd_ca.ca_rspint == 0) 1639*34293Skarels continue; 1640*34293Skarels kd->kd_ca.ca_rspint = 0; 1641*34293Skarels if (mp->mscp_opcode == (op | M_OP_END)) 1642*34293Skarels break; 1643*34293Skarels printf("\n"); 1644*34293Skarels switch (MSCP_MSGTYPE(mp->mscp_msgtc)) { 1645*34293Skarels 1646*34293Skarels case MSCPT_SEQ: 1647*34293Skarels printf("sequential"); 1648*34293Skarels break; 1649*34293Skarels 1650*34293Skarels case MSCPT_DATAGRAM: 1651*34293Skarels mscp_decodeerror("kdb", ctlr, mp); 1652*34293Skarels printf("datagram"); 1653*34293Skarels break; 1654*34293Skarels 1655*34293Skarels case MSCPT_CREDITS: 1656*34293Skarels printf("credits"); 1657*34293Skarels break; 1658*34293Skarels 1659*34293Skarels case MSCPT_MAINTENANCE: 1660*34293Skarels printf("maintenance"); 1661*34293Skarels break; 1662*34293Skarels 1663*34293Skarels default: 1664*34293Skarels printf("unknown (type 0x%x)", 1665*34293Skarels MSCP_MSGTYPE(mp->mscp_msgtc)); 1666*34293Skarels break; 1667*34293Skarels } 1668*34293Skarels printf(" ignored\ndump "); 1669*34293Skarels kd->kd_ca.ca_rspdsc |= MSCP_OWN | MSCP_INT; 1670*34293Skarels } 1671*34293Skarels if ((mp->mscp_status & M_ST_MASK) != M_ST_SUCCESS) { 1672*34293Skarels printf("error: op 0x%x => 0x%x status 0x%x\ndump ", op, 1673*34293Skarels mp->mscp_opcode, mp->mscp_status); 1674*34293Skarels return (1); 1675*34293Skarels } 1676*34293Skarels return (0); 1677*34293Skarels #undef mp 1678*34293Skarels } 1679*34293Skarels 1680*34293Skarels /* 1681*34293Skarels * Return the size of a partition, if known, or -1 if not. 1682*34293Skarels */ 1683*34293Skarels kdbsize(dev) 1684*34293Skarels dev_t dev; 1685*34293Skarels { 1686*34293Skarels register int unit = kdbunit(dev); 1687*34293Skarels register struct uba_device *ui; 1688*34293Skarels register struct size *st; 1689*34293Skarels 1690*34293Skarels if (unit >= NKRA || (ui = kdbdinfo[unit]) == NULL || ui->ui_alive == 0) 1691*34293Skarels return (-1); 1692*34293Skarels st = &kdbtypes[ui->ui_type].ut_sizes[kdbpart(dev)]; 1693*34293Skarels if (st->nblocks == -1) { 1694*34293Skarels int s = spl5(); 1695*34293Skarels 1696*34293Skarels /* 1697*34293Skarels * We need to have the drive on line to find the size 1698*34293Skarels * of this particular partition. 1699*34293Skarels * IS IT OKAY TO GO TO SLEEP IN THIS ROUTINE? 1700*34293Skarels * (If not, better not page on one of these...) 1701*34293Skarels */ 1702*34293Skarels if ((ui->ui_flags & UNIT_ONLINE) == 0) { 1703*34293Skarels if (kdb_bringonline(ui, 0)) { 1704*34293Skarels splx(s); 1705*34293Skarels return (-1); 1706*34293Skarels } 1707*34293Skarels } 1708*34293Skarels splx(s); 1709*34293Skarels if (st->blkoff > ra_dsize[unit]) 1710*34293Skarels return (-1); 1711*34293Skarels return (ra_dsize[unit] - st->blkoff); 1712*34293Skarels } 1713*34293Skarels return (st->nblocks); 1714*34293Skarels } 1715*34293Skarels 1716*34293Skarels #endif NKDB > 0 1717