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