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