|
|
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 are permitted provided ! 9: * that: (1) source distributions retain this entire copyright notice and ! 10: * comment, and (2) distributions including binaries display the following ! 11: * acknowledgement: ``This product includes software developed by the ! 12: * University of California, Berkeley and its contributors'' in the ! 13: * documentation or other materials provided with the distribution and in ! 14: * all advertising materials mentioning features or use of this software. ! 15: * Neither the name of the University nor the names of its contributors may ! 16: * be used to endorse or promote products derived from this software without ! 17: * specific prior written permission. ! 18: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED ! 19: * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF ! 20: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 21: * ! 22: * @(#)uda.c 7.30 (Berkeley) 11/28/90 ! 23: */ ! 24: ! 25: /* ! 26: * UDA50/MSCP device driver ! 27: */ ! 28: ! 29: #define POLLSTATS ! 30: ! 31: /* ! 32: * TODO ! 33: * write bad block forwarding code ! 34: */ ! 35: ! 36: #include "ra.h" ! 37: ! 38: #if NUDA > 0 ! 39: ! 40: /* ! 41: * CONFIGURATION OPTIONS. The next three defines are tunable -- tune away! ! 42: * ! 43: * COMPAT_42 enables 4.2/4.3 compatibility (label mapping) ! 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 unit number (number of drives per ! 52: * controller) we are prepared to handle. ! 53: * ! 54: * DEFAULT_BURST must be at least 1. ! 55: */ ! 56: #define COMPAT_42 ! 57: ! 58: #define NRSPL2 5 /* log2 number of response packets */ ! 59: #define NCMDL2 5 /* log2 number of command packets */ ! 60: #define MAXUNIT 8 /* maximum allowed unit number */ ! 61: #define DEFAULT_BURST 4 /* default DMA burst size */ ! 62: ! 63: #include "param.h" ! 64: #include "systm.h" ! 65: #include "buf.h" ! 66: #include "conf.h" ! 67: #include "file.h" ! 68: #include "ioctl.h" ! 69: #include "user.h" ! 70: #include "map.h" ! 71: #include "vm.h" ! 72: #include "dkstat.h" ! 73: #include "cmap.h" ! 74: #include "disklabel.h" ! 75: #include "syslog.h" ! 76: #include "stat.h" ! 77: ! 78: #include "machine/pte.h" ! 79: ! 80: #include "../vax/cpu.h" ! 81: #include "ubareg.h" ! 82: #include "ubavar.h" ! 83: ! 84: #define NRSP (1 << NRSPL2) ! 85: #define NCMD (1 << NCMDL2) ! 86: ! 87: #include "udareg.h" ! 88: #include "../vax/mscp.h" ! 89: #include "../vax/mscpvar.h" ! 90: #include "../vax/mtpr.h" ! 91: ! 92: /* ! 93: * UDA communications area and MSCP packet pools, per controller. ! 94: */ ! 95: struct uda { ! 96: struct udaca uda_ca; /* communications area */ ! 97: struct mscp uda_rsp[NRSP]; /* response packets */ ! 98: struct mscp uda_cmd[NCMD]; /* command packets */ ! 99: } uda[NUDA]; ! 100: ! 101: /* ! 102: * Software status, per controller. ! 103: */ ! 104: struct uda_softc { ! 105: struct uda *sc_uda; /* Unibus address of uda struct */ ! 106: short sc_state; /* UDA50 state; see below */ ! 107: short sc_flags; /* flags; see below */ ! 108: int sc_micro; /* microcode revision */ ! 109: int sc_ivec; /* interrupt vector address */ ! 110: short sc_ipl; /* interrupt priority, Q-bus */ ! 111: struct mscp_info sc_mi;/* MSCP info (per mscpvar.h) */ ! 112: #ifndef POLLSTATS ! 113: int sc_wticks; /* watchdog timer ticks */ ! 114: #else ! 115: short sc_wticks; ! 116: short sc_ncmd; ! 117: #endif ! 118: } uda_softc[NUDA]; ! 119: ! 120: #ifdef POLLSTATS ! 121: struct udastats { ! 122: int ncmd; ! 123: int cmd[NCMD + 1]; ! 124: } udastats = { NCMD + 1 }; ! 125: #endif ! 126: ! 127: /* ! 128: * Controller states ! 129: */ ! 130: #define ST_IDLE 0 /* uninitialised */ ! 131: #define ST_STEP1 1 /* in `STEP 1' */ ! 132: #define ST_STEP2 2 /* in `STEP 2' */ ! 133: #define ST_STEP3 3 /* in `STEP 3' */ ! 134: #define ST_SETCHAR 4 /* in `Set Controller Characteristics' */ ! 135: #define ST_RUN 5 /* up and running */ ! 136: ! 137: /* ! 138: * Flags ! 139: */ ! 140: #define SC_MAPPED 0x01 /* mapped in Unibus I/O space */ ! 141: #define SC_INSTART 0x02 /* inside udastart() */ ! 142: #define SC_GRIPED 0x04 /* griped about cmd ring too small */ ! 143: #define SC_INSLAVE 0x08 /* inside udaslave() */ ! 144: #define SC_DOWAKE 0x10 /* wakeup when ctlr init done */ ! 145: #define SC_STARTPOLL 0x20 /* need to initiate polling */ ! 146: ! 147: /* ! 148: * Device to unit number and partition and back ! 149: */ ! 150: #define UNITSHIFT 3 ! 151: #define UNITMASK 7 ! 152: #define udaunit(dev) (minor(dev) >> UNITSHIFT) ! 153: #define udapart(dev) (minor(dev) & UNITMASK) ! 154: #define udaminor(u, p) (((u) << UNITSHIFT) | (p)) ! 155: ! 156: /* ! 157: * Drive status, per drive ! 158: */ ! 159: struct ra_info { ! 160: daddr_t ra_dsize; /* size in sectors */ ! 161: /* u_long ra_type; /* drive type */ ! 162: u_long ra_mediaid; /* media id */ ! 163: int ra_state; /* open/closed state */ ! 164: struct ra_geom { /* geometry information */ ! 165: u_short rg_nsectors; /* sectors/track */ ! 166: u_short rg_ngroups; /* track groups */ ! 167: u_short rg_ngpc; /* groups/cylinder */ ! 168: u_short rg_ntracks; /* ngroups*ngpc */ ! 169: u_short rg_ncyl; /* ra_dsize/ntracks/nsectors */ ! 170: #ifdef notyet ! 171: u_short rg_rctsize; /* size of rct */ ! 172: u_short rg_rbns; /* replacement blocks per track */ ! 173: u_short rg_nrct; /* number of rct copies */ ! 174: #endif ! 175: } ra_geom; ! 176: int ra_wlabel; /* label sector is currently writable */ ! 177: u_long ra_openpart; /* partitions open */ ! 178: u_long ra_bopenpart; /* block partitions open */ ! 179: u_long ra_copenpart; /* character partitions open */ ! 180: } ra_info[NRA]; ! 181: ! 182: /* ! 183: * Software state, per drive ! 184: */ ! 185: #define CLOSED 0 ! 186: #define WANTOPEN 1 ! 187: #define RDLABEL 2 ! 188: #define OPEN 3 ! 189: #define OPENRAW 4 ! 190: ! 191: /* ! 192: * Definition of the driver for autoconf. ! 193: */ ! 194: int udaprobe(), udaslave(), udaattach(), udadgo(), udaintr(); ! 195: struct uba_ctlr *udaminfo[NUDA]; ! 196: struct uba_device *udadinfo[NRA]; ! 197: struct disklabel udalabel[NRA]; ! 198: ! 199: u_short udastd[] = { 0772150, 0772550, 0777550, 0 }; ! 200: struct uba_driver udadriver = ! 201: { udaprobe, udaslave, udaattach, udadgo, udastd, "ra", udadinfo, "uda", ! 202: udaminfo }; ! 203: ! 204: /* ! 205: * More driver definitions, for generic MSCP code. ! 206: */ ! 207: int udadgram(), udactlrdone(), udaunconf(), udaiodone(); ! 208: int udaonline(), udagotstatus(), udaioerror(), udareplace(), udabb(); ! 209: ! 210: struct buf udautab[NRA]; /* per drive transfer queue */ ! 211: ! 212: struct mscp_driver udamscpdriver = ! 213: { MAXUNIT, NRA, UNITSHIFT, udautab, udalabel, udadinfo, ! 214: udadgram, udactlrdone, udaunconf, udaiodone, ! 215: udaonline, udagotstatus, udareplace, udaioerror, udabb, ! 216: "uda", "ra" }; ! 217: ! 218: /* ! 219: * Miscellaneous private variables. ! 220: */ ! 221: char udasr_bits[] = UDASR_BITS; ! 222: ! 223: struct uba_device *udaip[NUDA][MAXUNIT]; ! 224: /* inverting pointers: ctlr & unit => Unibus ! 225: device pointer */ ! 226: ! 227: int udaburst[NUDA] = { 0 }; /* burst size, per UDA50, zero => default; ! 228: in data space so patchable via adb */ ! 229: ! 230: struct mscp udaslavereply; /* get unit status response packet, set ! 231: for udaslave by udaunconf, via udaintr */ ! 232: ! 233: static struct uba_ctlr *probeum;/* this is a hack---autoconf should pass ctlr ! 234: info to slave routine; instead, we remember ! 235: the last ctlr argument to probe */ ! 236: ! 237: int udawstart, udawatch(); /* watchdog timer */ ! 238: ! 239: /* ! 240: * Externals ! 241: */ ! 242: int wakeup(); ! 243: int hz; ! 244: ! 245: /* ! 246: * Poke at a supposed UDA50 to see if it is there. ! 247: * This routine duplicates some of the code in udainit() only ! 248: * because autoconf has not set up the right information yet. ! 249: * We have to do everything `by hand'. ! 250: */ ! 251: udaprobe(reg, ctlr, um) ! 252: caddr_t reg; ! 253: int ctlr; ! 254: struct uba_ctlr *um; ! 255: { ! 256: register int br, cvec; ! 257: register struct uda_softc *sc; ! 258: register struct udadevice *udaddr; ! 259: register struct mscp_info *mi; ! 260: int timeout, tries; ! 261: #ifdef QBA ! 262: int s; ! 263: #endif ! 264: ! 265: #ifdef VAX750 ! 266: /* ! 267: * The UDA50 wants to share BDPs on 750s, but not on 780s or ! 268: * 8600s. (730s have no BDPs anyway.) Toward this end, we ! 269: * here set the `keep bdp' flag in the per-driver information ! 270: * if this is a 750. (We just need to do it once, but it is ! 271: * easiest to do it now, for each UDA50.) ! 272: */ ! 273: if (cpu == VAX_750) ! 274: udadriver.ud_keepbdp = 1; ! 275: #endif ! 276: ! 277: probeum = um; /* remember for udaslave() */ ! 278: #ifdef lint ! 279: br = 0; cvec = br; br = cvec; udaintr(0); ! 280: #endif ! 281: /* ! 282: * Set up the controller-specific generic MSCP driver info. ! 283: * Note that this should really be done in the (nonexistent) ! 284: * controller attach routine. ! 285: */ ! 286: sc = &uda_softc[ctlr]; ! 287: mi = &sc->sc_mi; ! 288: mi->mi_md = &udamscpdriver; ! 289: mi->mi_ctlr = um->um_ctlr; ! 290: mi->mi_tab = &um->um_tab; ! 291: mi->mi_ip = udaip[ctlr]; ! 292: mi->mi_cmd.mri_size = NCMD; ! 293: mi->mi_cmd.mri_desc = uda[ctlr].uda_ca.ca_cmddsc; ! 294: mi->mi_cmd.mri_ring = uda[ctlr].uda_cmd; ! 295: mi->mi_rsp.mri_size = NRSP; ! 296: mi->mi_rsp.mri_desc = uda[ctlr].uda_ca.ca_rspdsc; ! 297: mi->mi_rsp.mri_ring = uda[ctlr].uda_rsp; ! 298: mi->mi_wtab.av_forw = mi->mi_wtab.av_back = &mi->mi_wtab; ! 299: ! 300: /* ! 301: * More controller specific variables. Again, this should ! 302: * be in the controller attach routine. ! 303: */ ! 304: if (udaburst[ctlr] == 0) ! 305: udaburst[ctlr] = DEFAULT_BURST; ! 306: ! 307: /* ! 308: * Get an interrupt vector. Note that even if the controller ! 309: * does not respond, we keep the vector. This is not a serious ! 310: * problem; but it would be easily fixed if we had a controller ! 311: * attach routine. Sigh. ! 312: */ ! 313: sc->sc_ivec = (uba_hd[numuba].uh_lastiv -= 4); ! 314: udaddr = (struct udadevice *) reg; ! 315: ! 316: /* ! 317: * Initialise the controller (partially). The UDA50 programmer's ! 318: * manual states that if initialisation fails, it should be retried ! 319: * at least once, but after a second failure the port should be ! 320: * considered `down'; it also mentions that the controller should ! 321: * initialise within ten seconds. Or so I hear; I have not seen ! 322: * this manual myself. ! 323: */ ! 324: #if defined(QBA) && !defined(GENERIC) ! 325: s = spl6(); ! 326: #endif ! 327: tries = 0; ! 328: again: ! 329: udaddr->udaip = 0; /* start initialisation */ ! 330: timeout = todr() + 1000; /* timeout in 10 seconds */ ! 331: while ((udaddr->udasa & UDA_STEP1) == 0) ! 332: if (todr() > timeout) ! 333: goto bad; ! 334: udaddr->udasa = UDA_ERR | (NCMDL2 << 11) | (NRSPL2 << 8) | UDA_IE | ! 335: (sc->sc_ivec >> 2); ! 336: while ((udaddr->udasa & UDA_STEP2) == 0) ! 337: if (todr() > timeout) ! 338: goto bad; ! 339: ! 340: /* should have interrupted by now */ ! 341: #ifdef QBA ! 342: #ifndef GENERIC ! 343: sc->sc_ipl = br = qbgetpri(); ! 344: #else ! 345: sc->sc_ipl = br = 0x15; ! 346: #endif ! 347: #endif ! 348: return (sizeof (struct udadevice)); ! 349: bad: ! 350: if (++tries < 2) ! 351: goto again; ! 352: #if defined(QBA) && !defined(GENERIC) ! 353: splx(s); ! 354: #endif ! 355: return (0); ! 356: } ! 357: ! 358: /* ! 359: * Find a slave. We allow wildcard slave numbers (something autoconf ! 360: * is not really prepared to deal with); and we need to know the ! 361: * controller number to talk to the UDA. For the latter, we keep ! 362: * track of the last controller probed, since a controller probe ! 363: * immediately precedes all slave probes for that controller. For the ! 364: * former, we simply put the unit number into ui->ui_slave after we ! 365: * have found one. ! 366: * ! 367: * Note that by the time udaslave is called, the interrupt vector ! 368: * for the UDA50 has been set up (so that udaunconf() will be called). ! 369: */ ! 370: udaslave(ui, reg) ! 371: register struct uba_device *ui; ! 372: caddr_t reg; ! 373: { ! 374: register struct uba_ctlr *um = probeum; ! 375: register struct mscp *mp; ! 376: register struct uda_softc *sc; ! 377: int next = 0, timeout, tries, i; ! 378: ! 379: #ifdef lint ! 380: i = 0; i = i; ! 381: #endif ! 382: /* ! 383: * Make sure the controller is fully initialised, by waiting ! 384: * for it if necessary. ! 385: */ ! 386: sc = &uda_softc[um->um_ctlr]; ! 387: if (sc->sc_state == ST_RUN) ! 388: goto findunit; ! 389: tries = 0; ! 390: again: ! 391: if (udainit(ui->ui_ctlr)) ! 392: return (0); ! 393: timeout = todr() + 1000; /* 10 seconds */ ! 394: while (todr() < timeout) ! 395: if (sc->sc_state == ST_RUN) /* made it */ ! 396: goto findunit; ! 397: if (++tries < 2) ! 398: goto again; ! 399: printf("uda%d: controller hung\n", um->um_ctlr); ! 400: return (0); ! 401: ! 402: /* ! 403: * The controller is all set; go find the unit. Grab an ! 404: * MSCP packet and send out a Get Unit Status command, with ! 405: * the `next unit' modifier if we are looking for a generic ! 406: * unit. We set the `in slave' flag so that udaunconf() ! 407: * knows to copy the response to `udaslavereply'. ! 408: */ ! 409: findunit: ! 410: udaslavereply.mscp_opcode = 0; ! 411: sc->sc_flags |= SC_INSLAVE; ! 412: if ((mp = mscp_getcp(&sc->sc_mi, MSCP_DONTWAIT)) == NULL) ! 413: panic("udaslave"); /* `cannot happen' */ ! 414: mp->mscp_opcode = M_OP_GETUNITST; ! 415: if (ui->ui_slave == '?') { ! 416: mp->mscp_unit = next; ! 417: mp->mscp_modifier = M_GUM_NEXTUNIT; ! 418: } else { ! 419: mp->mscp_unit = ui->ui_slave; ! 420: mp->mscp_modifier = 0; ! 421: } ! 422: *mp->mscp_addr |= MSCP_OWN | MSCP_INT; ! 423: i = ((struct udadevice *) reg)->udaip; /* initiate polling */ ! 424: mp = &udaslavereply; ! 425: timeout = todr() + 1000; ! 426: while (todr() < timeout) ! 427: if (mp->mscp_opcode) ! 428: goto gotit; ! 429: printf("uda%d: no response to Get Unit Status request\n", ! 430: um->um_ctlr); ! 431: sc->sc_flags &= ~SC_INSLAVE; ! 432: return (0); ! 433: ! 434: gotit: ! 435: sc->sc_flags &= ~SC_INSLAVE; ! 436: ! 437: /* ! 438: * Got a slave response. If the unit is there, use it. ! 439: */ ! 440: switch (mp->mscp_status & M_ST_MASK) { ! 441: ! 442: case M_ST_SUCCESS: /* worked */ ! 443: case M_ST_AVAILABLE: /* found another drive */ ! 444: break; /* use it */ ! 445: ! 446: case M_ST_OFFLINE: ! 447: /* ! 448: * Figure out why it is off line. It may be because ! 449: * it is nonexistent, or because it is spun down, or ! 450: * for some other reason. ! 451: */ ! 452: switch (mp->mscp_status & ~M_ST_MASK) { ! 453: ! 454: case M_OFFLINE_UNKNOWN: ! 455: /* ! 456: * No such drive, and there are none with ! 457: * higher unit numbers either, if we are ! 458: * using M_GUM_NEXTUNIT. ! 459: */ ! 460: return (0); ! 461: ! 462: case M_OFFLINE_UNMOUNTED: ! 463: /* ! 464: * The drive is not spun up. Use it anyway. ! 465: * ! 466: * N.B.: this seems to be a common occurrance ! 467: * after a power failure. The first attempt ! 468: * to bring it on line seems to spin it up ! 469: * (and thus takes several minutes). Perhaps ! 470: * we should note here that the on-line may ! 471: * take longer than usual. ! 472: */ ! 473: break; ! 474: ! 475: default: ! 476: /* ! 477: * In service, or something else equally unusable. ! 478: */ ! 479: printf("uda%d: unit %d off line: ", um->um_ctlr, ! 480: mp->mscp_unit); ! 481: mscp_printevent(mp); ! 482: goto try_another; ! 483: } ! 484: break; ! 485: ! 486: default: ! 487: printf("uda%d: unable to get unit status: ", um->um_ctlr); ! 488: mscp_printevent(mp); ! 489: return (0); ! 490: } ! 491: ! 492: /* ! 493: * Does this ever happen? What (if anything) does it mean? ! 494: */ ! 495: if (mp->mscp_unit < next) { ! 496: printf("uda%d: unit %d, next %d\n", ! 497: um->um_ctlr, mp->mscp_unit, next); ! 498: return (0); ! 499: } ! 500: ! 501: if (mp->mscp_unit >= MAXUNIT) { ! 502: printf("uda%d: cannot handle unit number %d (max is %d)\n", ! 503: um->um_ctlr, mp->mscp_unit, MAXUNIT - 1); ! 504: return (0); ! 505: } ! 506: ! 507: /* ! 508: * See if we already handle this drive. ! 509: * (Only likely if ui->ui_slave=='?'.) ! 510: */ ! 511: if (udaip[um->um_ctlr][mp->mscp_unit] != NULL) { ! 512: try_another: ! 513: if (ui->ui_slave != '?') ! 514: return (0); ! 515: next = mp->mscp_unit + 1; ! 516: goto findunit; ! 517: } ! 518: ! 519: /* ! 520: * Voila! ! 521: */ ! 522: uda_rasave(ui->ui_unit, mp, 0); ! 523: ui->ui_flags = 0; /* not on line, nor anything else */ ! 524: ui->ui_slave = mp->mscp_unit; ! 525: return (1); ! 526: } ! 527: ! 528: /* ! 529: * Attach a found slave. Make sure the watchdog timer is running. ! 530: * If this disk is being profiled, fill in the `wpms' value (used by ! 531: * what?). Set up the inverting pointer, and attempt to bring the ! 532: * drive on line and read its label. ! 533: */ ! 534: udaattach(ui) ! 535: register struct uba_device *ui; ! 536: { ! 537: register int unit = ui->ui_unit; ! 538: ! 539: if (udawstart == 0) { ! 540: timeout(udawatch, (caddr_t) 0, hz); ! 541: udawstart++; ! 542: } ! 543: ! 544: /* ! 545: * Floppies cannot be brought on line unless there is ! 546: * a disk in the drive. Since an ONLINE while cold ! 547: * takes ten seconds to fail, and (when notyet becomes now) ! 548: * no sensible person will swap to one, we just ! 549: * defer the ONLINE until someone tries to use the drive. ! 550: * ! 551: * THIS ASSUMES THAT DRIVE TYPES ?X? ARE FLOPPIES ! 552: */ ! 553: if (MSCP_MID_ECH(1, ra_info[unit].ra_mediaid) == 'X' - '@') { ! 554: printf(": floppy"); ! 555: return; ! 556: } ! 557: if (ui->ui_dk >= 0) ! 558: dk_wpms[ui->ui_dk] = (60 * 31 * 256); /* approx */ ! 559: udaip[ui->ui_ctlr][ui->ui_slave] = ui; ! 560: ! 561: if (uda_rainit(ui, 0)) ! 562: printf(": offline"); ! 563: else if (ra_info[unit].ra_state == OPEN) { ! 564: printf(": %s, size = %d sectors", ! 565: udalabel[unit].d_typename, ra_info[unit].ra_dsize); ! 566: #ifdef notyet ! 567: addswap(makedev(UDADEVNUM, udaminor(unit, 0)), &udalabel[unit]); ! 568: #endif ! 569: } ! 570: } ! 571: ! 572: /* ! 573: * Initialise a UDA50. Return true iff something goes wrong. ! 574: */ ! 575: udainit(ctlr) ! 576: int ctlr; ! 577: { ! 578: register struct uda_softc *sc; ! 579: register struct udadevice *udaddr; ! 580: struct uba_ctlr *um; ! 581: int timo, ubinfo; ! 582: ! 583: sc = &uda_softc[ctlr]; ! 584: um = udaminfo[ctlr]; ! 585: if ((sc->sc_flags & SC_MAPPED) == 0) { ! 586: /* ! 587: * Map the communication area and command and ! 588: * response packets into Unibus space. ! 589: */ ! 590: ubinfo = uballoc(um->um_ubanum, (caddr_t) &uda[ctlr], ! 591: sizeof (struct uda), UBA_CANTWAIT); ! 592: if (ubinfo == 0) { ! 593: printf("uda%d: uballoc map failed\n", ctlr); ! 594: return (-1); ! 595: } ! 596: sc->sc_uda = (struct uda *) UBAI_ADDR(ubinfo); ! 597: sc->sc_flags |= SC_MAPPED; ! 598: } ! 599: ! 600: /* ! 601: * While we are thinking about it, reset the next command ! 602: * and response indicies. ! 603: */ ! 604: sc->sc_mi.mi_cmd.mri_next = 0; ! 605: sc->sc_mi.mi_rsp.mri_next = 0; ! 606: ! 607: /* ! 608: * Start up the hardware initialisation sequence. ! 609: */ ! 610: #define STEP0MASK (UDA_ERR | UDA_STEP4 | UDA_STEP3 | UDA_STEP2 | \ ! 611: UDA_STEP1 | UDA_NV) ! 612: ! 613: sc->sc_state = ST_IDLE; /* in case init fails */ ! 614: udaddr = (struct udadevice *)um->um_addr; ! 615: udaddr->udaip = 0; ! 616: timo = todr() + 1000; ! 617: while ((udaddr->udasa & STEP0MASK) == 0) { ! 618: if (todr() > timo) { ! 619: printf("uda%d: timeout during init\n", ctlr); ! 620: return (-1); ! 621: } ! 622: } ! 623: if ((udaddr->udasa & STEP0MASK) != UDA_STEP1) { ! 624: printf("uda%d: init failed, sa=%b\n", ctlr, ! 625: udaddr->udasa, udasr_bits); ! 626: udasaerror(um, 0); ! 627: return (-1); ! 628: } ! 629: ! 630: /* ! 631: * Success! Record new state, and start step 1 initialisation. ! 632: * The rest is done in the interrupt handler. ! 633: */ ! 634: sc->sc_state = ST_STEP1; ! 635: udaddr->udasa = UDA_ERR | (NCMDL2 << 11) | (NRSPL2 << 8) | UDA_IE | ! 636: (sc->sc_ivec >> 2); ! 637: return (0); ! 638: } ! 639: ! 640: /* ! 641: * Open a drive. ! 642: */ ! 643: /*ARGSUSED*/ ! 644: udaopen(dev, flag, fmt) ! 645: dev_t dev; ! 646: int flag, fmt; ! 647: { ! 648: register int unit; ! 649: register struct uba_device *ui; ! 650: register struct uda_softc *sc; ! 651: register struct disklabel *lp; ! 652: register struct partition *pp; ! 653: register struct ra_info *ra; ! 654: int s, i, part, mask, error = 0; ! 655: daddr_t start, end; ! 656: ! 657: /* ! 658: * Make sure this is a reasonable open request. ! 659: */ ! 660: unit = udaunit(dev); ! 661: if (unit >= NRA || (ui = udadinfo[unit]) == 0 || ui->ui_alive == 0) ! 662: return (ENXIO); ! 663: ! 664: /* ! 665: * Make sure the controller is running, by (re)initialising it if ! 666: * necessary. ! 667: */ ! 668: sc = &uda_softc[ui->ui_ctlr]; ! 669: s = spl5(); ! 670: if (sc->sc_state != ST_RUN) { ! 671: if (sc->sc_state == ST_IDLE && udainit(ui->ui_ctlr)) { ! 672: splx(s); ! 673: return (EIO); ! 674: } ! 675: /* ! 676: * In case it does not come up, make sure we will be ! 677: * restarted in 10 seconds. This corresponds to the ! 678: * 10 second timeouts in udaprobe() and udaslave(). ! 679: */ ! 680: sc->sc_flags |= SC_DOWAKE; ! 681: timeout(wakeup, (caddr_t) sc, 10 * hz); ! 682: sleep((caddr_t) sc, PRIBIO); ! 683: if (sc->sc_state != ST_RUN) { ! 684: splx(s); ! 685: printf("uda%d: controller hung\n", ui->ui_ctlr); ! 686: return (EIO); ! 687: } ! 688: untimeout(wakeup, (caddr_t) sc); ! 689: } ! 690: ! 691: /* ! 692: * Wait for the state to settle ! 693: */ ! 694: ra = &ra_info[unit]; ! 695: while (ra->ra_state != OPEN && ra->ra_state != OPENRAW && ! 696: ra->ra_state != CLOSED) ! 697: if (error = tsleep((caddr_t)ra, (PZERO + 1) | PCATCH, ! 698: devopn, 0)) { ! 699: splx(s); ! 700: return (error); ! 701: } ! 702: ! 703: /* ! 704: * If not on line, or we are not sure of the label, reinitialise ! 705: * the drive. ! 706: */ ! 707: if ((ui->ui_flags & UNIT_ONLINE) == 0 || ! 708: (ra->ra_state != OPEN && ra->ra_state != OPENRAW)) ! 709: error = uda_rainit(ui, flag); ! 710: splx(s); ! 711: if (error) ! 712: return (error); ! 713: ! 714: part = udapart(dev); ! 715: lp = &udalabel[unit]; ! 716: if (part >= lp->d_npartitions) ! 717: return (ENXIO); ! 718: /* ! 719: * Warn if a partition is opened that overlaps another ! 720: * already open, unless either is the `raw' partition ! 721: * (whole disk). ! 722: */ ! 723: #define RAWPART 2 /* 'c' partition */ /* XXX */ ! 724: mask = 1 << part; ! 725: if ((ra->ra_openpart & mask) == 0 && part != RAWPART) { ! 726: pp = &lp->d_partitions[part]; ! 727: start = pp->p_offset; ! 728: end = pp->p_offset + pp->p_size; ! 729: for (pp = lp->d_partitions, i = 0; ! 730: i < lp->d_npartitions; pp++, i++) { ! 731: if (pp->p_offset + pp->p_size <= start || ! 732: pp->p_offset >= end || i == RAWPART) ! 733: continue; ! 734: if (ra->ra_openpart & (1 << i)) ! 735: log(LOG_WARNING, ! 736: "ra%d%c: overlaps open partition (%c)\n", ! 737: unit, part + 'a', i + 'a'); ! 738: } ! 739: } ! 740: switch (fmt) { ! 741: case S_IFCHR: ! 742: ra->ra_copenpart |= mask; ! 743: break; ! 744: case S_IFBLK: ! 745: ra->ra_bopenpart |= mask; ! 746: break; ! 747: } ! 748: ra->ra_openpart |= mask; ! 749: return (0); ! 750: } ! 751: ! 752: /* ARGSUSED */ ! 753: udaclose(dev, flags, fmt) ! 754: dev_t dev; ! 755: int flags, fmt; ! 756: { ! 757: register int unit = udaunit(dev); ! 758: register struct ra_info *ra = &ra_info[unit]; ! 759: int s, mask = (1 << udapart(dev)); ! 760: ! 761: switch (fmt) { ! 762: case S_IFCHR: ! 763: ra->ra_copenpart &= ~mask; ! 764: break; ! 765: case S_IFBLK: ! 766: ra->ra_bopenpart &= ~mask; ! 767: break; ! 768: } ! 769: ra->ra_openpart = ra->ra_copenpart | ra->ra_bopenpart; ! 770: ! 771: /* ! 772: * Should wait for I/O to complete on this partition even if ! 773: * others are open, but wait for work on blkflush(). ! 774: */ ! 775: if (ra->ra_openpart == 0) { ! 776: s = spl5(); ! 777: while (udautab[unit].b_actf) ! 778: sleep((caddr_t)&udautab[unit], PZERO - 1); ! 779: splx(s); ! 780: ra->ra_state = CLOSED; ! 781: ra->ra_wlabel = 0; ! 782: } ! 783: return (0); ! 784: } ! 785: ! 786: /* ! 787: * Initialise a drive. If it is not already, bring it on line, ! 788: * and set a timeout on it in case it fails to respond. ! 789: * When on line, read in the pack label. ! 790: */ ! 791: uda_rainit(ui, flags) ! 792: register struct uba_device *ui; ! 793: int flags; ! 794: { ! 795: register struct uda_softc *sc = &uda_softc[ui->ui_ctlr]; ! 796: register struct disklabel *lp; ! 797: register struct mscp *mp; ! 798: register int unit = ui->ui_unit; ! 799: register struct ra_info *ra; ! 800: char *msg, *readdisklabel(); ! 801: int s, i, udastrategy(); ! 802: extern int cold; ! 803: ! 804: ra = &ra_info[unit]; ! 805: if ((ui->ui_flags & UNIT_ONLINE) == 0) { ! 806: mp = mscp_getcp(&sc->sc_mi, MSCP_WAIT); ! 807: mp->mscp_opcode = M_OP_ONLINE; ! 808: mp->mscp_unit = ui->ui_slave; ! 809: mp->mscp_cmdref = (long)&ui->ui_flags; ! 810: *mp->mscp_addr |= MSCP_OWN | MSCP_INT; ! 811: ra->ra_state = WANTOPEN; ! 812: if (!cold) ! 813: s = spl5(); ! 814: i = ((struct udadevice *)ui->ui_addr)->udaip; ! 815: ! 816: if (cold) { ! 817: i = todr() + 1000; ! 818: while ((ui->ui_flags & UNIT_ONLINE) == 0) ! 819: if (todr() > i) ! 820: break; ! 821: } else { ! 822: timeout(wakeup, (caddr_t)&ui->ui_flags, 10 * hz); ! 823: sleep((caddr_t)&ui->ui_flags, PSWP + 1); ! 824: splx(s); ! 825: untimeout(wakeup, (caddr_t)&ui->ui_flags); ! 826: } ! 827: if (ra->ra_state != OPENRAW) { ! 828: ra->ra_state = CLOSED; ! 829: wakeup((caddr_t)ra); ! 830: return (EIO); ! 831: } ! 832: } ! 833: ! 834: lp = &udalabel[unit]; ! 835: lp->d_secsize = DEV_BSIZE; ! 836: lp->d_secperunit = ra->ra_dsize; ! 837: ! 838: if (flags & O_NDELAY) ! 839: return (0); ! 840: ra->ra_state = RDLABEL; ! 841: /* ! 842: * Set up default sizes until we have the label, or longer ! 843: * if there is none. Set secpercyl, as readdisklabel wants ! 844: * to compute b_cylin (although we do not need it), and set ! 845: * nsectors in case diskerr is called. ! 846: */ ! 847: lp->d_secpercyl = 1; ! 848: lp->d_npartitions = 1; ! 849: lp->d_secsize = 512; ! 850: lp->d_secperunit = ra->ra_dsize; ! 851: lp->d_nsectors = ra->ra_geom.rg_nsectors; ! 852: lp->d_partitions[0].p_size = lp->d_secperunit; ! 853: lp->d_partitions[0].p_offset = 0; ! 854: ! 855: /* ! 856: * Read pack label. ! 857: */ ! 858: if ((msg = readdisklabel(udaminor(unit, 0), udastrategy, lp)) != NULL) { ! 859: if (cold) ! 860: printf(": %s", msg); ! 861: else ! 862: log(LOG_ERR, "ra%d: %s", unit, msg); ! 863: #ifdef COMPAT_42 ! 864: if (udamaptype(unit, lp)) ! 865: ra->ra_state = OPEN; ! 866: else ! 867: ra->ra_state = OPENRAW; ! 868: #else ! 869: ra->ra_state = OPENRAW; ! 870: uda_makefakelabel(ra, lp); ! 871: #endif ! 872: } else ! 873: ra->ra_state = OPEN; ! 874: wakeup((caddr_t)ra); ! 875: return (0); ! 876: } ! 877: ! 878: /* ! 879: * Copy the geometry information for the given ra from a ! 880: * GET UNIT STATUS response. If check, see if it changed. ! 881: */ ! 882: uda_rasave(unit, mp, check) ! 883: int unit; ! 884: register struct mscp *mp; ! 885: int check; ! 886: { ! 887: register struct ra_info *ra = &ra_info[unit]; ! 888: ! 889: if (check && ra->ra_mediaid != mp->mscp_guse.guse_mediaid) { ! 890: printf("ra%d: changed types! was %d now %d\n", unit, ! 891: ra->ra_mediaid, mp->mscp_guse.guse_mediaid); ! 892: ra->ra_state = CLOSED; /* ??? */ ! 893: } ! 894: /* ra->ra_type = mp->mscp_guse.guse_drivetype; */ ! 895: ra->ra_mediaid = mp->mscp_guse.guse_mediaid; ! 896: ra->ra_geom.rg_nsectors = mp->mscp_guse.guse_nspt; ! 897: ra->ra_geom.rg_ngroups = mp->mscp_guse.guse_group; ! 898: ra->ra_geom.rg_ngpc = mp->mscp_guse.guse_ngpc; ! 899: ra->ra_geom.rg_ntracks = ra->ra_geom.rg_ngroups * ra->ra_geom.rg_ngpc; ! 900: /* ra_geom.rg_ncyl cannot be computed until we have ra_dsize */ ! 901: #ifdef notyet ! 902: ra->ra_geom.rg_rctsize = mp->mscp_guse.guse_rctsize; ! 903: ra->ra_geom.rg_rbns = mp->mscp_guse.guse_nrpt; ! 904: ra->ra_geom.rg_nrct = mp->mscp_guse.guse_nrct; ! 905: #endif ! 906: } ! 907: ! 908: /* ! 909: * Queue a transfer request, and if possible, hand it to the controller. ! 910: * ! 911: * This routine is broken into two so that the internal version ! 912: * udastrat1() can be called by the (nonexistent, as yet) bad block ! 913: * revectoring routine. ! 914: */ ! 915: udastrategy(bp) ! 916: register struct buf *bp; ! 917: { ! 918: register int unit; ! 919: register struct uba_device *ui; ! 920: register struct ra_info *ra; ! 921: struct partition *pp; ! 922: int p; ! 923: daddr_t sz, maxsz; ! 924: ! 925: /* ! 926: * Make sure this is a reasonable drive to use. ! 927: */ ! 928: if ((unit = udaunit(bp->b_dev)) >= NRA || ! 929: (ui = udadinfo[unit]) == NULL || ui->ui_alive == 0 || ! 930: (ra = &ra_info[unit])->ra_state == CLOSED) { ! 931: bp->b_error = ENXIO; ! 932: goto bad; ! 933: } ! 934: ! 935: /* ! 936: * If drive is open `raw' or reading label, let it at it. ! 937: */ ! 938: if (ra->ra_state < OPEN) { ! 939: udastrat1(bp); ! 940: return; ! 941: } ! 942: p = udapart(bp->b_dev); ! 943: if ((ra->ra_openpart & (1 << p)) == 0) { ! 944: bp->b_error = ENODEV; ! 945: goto bad; ! 946: } ! 947: ! 948: /* ! 949: * Determine the size of the transfer, and make sure it is ! 950: * within the boundaries of the partition. ! 951: */ ! 952: pp = &udalabel[unit].d_partitions[p]; ! 953: maxsz = pp->p_size; ! 954: if (pp->p_offset + pp->p_size > ra->ra_dsize) ! 955: maxsz = ra->ra_dsize - pp->p_offset; ! 956: sz = (bp->b_bcount + DEV_BSIZE - 1) >> DEV_BSHIFT; ! 957: if (bp->b_blkno + pp->p_offset <= LABELSECTOR && ! 958: #if LABELSECTOR != 0 ! 959: bp->b_blkno + pp->p_offset + sz > LABELSECTOR && ! 960: #endif ! 961: (bp->b_flags & B_READ) == 0 && ra->ra_wlabel == 0) { ! 962: bp->b_error = EROFS; ! 963: goto bad; ! 964: } ! 965: if (bp->b_blkno < 0 || bp->b_blkno + sz > maxsz) { ! 966: /* if exactly at end of disk, return an EOF */ ! 967: if (bp->b_blkno == maxsz) { ! 968: bp->b_resid = bp->b_bcount; ! 969: biodone(bp); ! 970: return; ! 971: } ! 972: /* or truncate if part of it fits */ ! 973: sz = maxsz - bp->b_blkno; ! 974: if (sz <= 0) { ! 975: bp->b_error = EINVAL; /* or hang it up */ ! 976: goto bad; ! 977: } ! 978: bp->b_bcount = sz << DEV_BSHIFT; ! 979: } ! 980: udastrat1(bp); ! 981: return; ! 982: bad: ! 983: bp->b_flags |= B_ERROR; ! 984: biodone(bp); ! 985: } ! 986: ! 987: /* ! 988: * Work routine for udastrategy. ! 989: */ ! 990: udastrat1(bp) ! 991: register struct buf *bp; ! 992: { ! 993: register int unit = udaunit(bp->b_dev); ! 994: register struct uba_ctlr *um; ! 995: register struct buf *dp; ! 996: struct uba_device *ui; ! 997: int s = spl5(); ! 998: ! 999: /* ! 1000: * Append the buffer to the drive queue, and if it is not ! 1001: * already there, the drive to the controller queue. (However, ! 1002: * if the drive queue is marked to be requeued, we must be ! 1003: * awaiting an on line or get unit status command; in this ! 1004: * case, leave it off the controller queue.) ! 1005: */ ! 1006: um = (ui = udadinfo[unit])->ui_mi; ! 1007: dp = &udautab[unit]; ! 1008: APPEND(bp, dp, av_forw); ! 1009: if (dp->b_active == 0 && (ui->ui_flags & UNIT_REQUEUE) == 0) { ! 1010: APPEND(dp, &um->um_tab, b_forw); ! 1011: dp->b_active++; ! 1012: } ! 1013: ! 1014: /* ! 1015: * Start activity on the controller. Note that unlike other ! 1016: * Unibus drivers, we must always do this, not just when the ! 1017: * controller is not active. ! 1018: */ ! 1019: udastart(um); ! 1020: splx(s); ! 1021: } ! 1022: ! 1023: /* ! 1024: * Start up whatever transfers we can find. ! 1025: * Note that udastart() must be called at spl5(). ! 1026: */ ! 1027: udastart(um) ! 1028: register struct uba_ctlr *um; ! 1029: { ! 1030: register struct uda_softc *sc = &uda_softc[um->um_ctlr]; ! 1031: register struct buf *bp, *dp; ! 1032: register struct mscp *mp; ! 1033: struct uba_device *ui; ! 1034: struct udadevice *udaddr; ! 1035: struct partition *pp; ! 1036: int i, sz; ! 1037: ! 1038: #ifdef lint ! 1039: i = 0; i = i; ! 1040: #endif ! 1041: /* ! 1042: * If it is not running, try (again and again...) to initialise ! 1043: * it. If it is currently initialising just ignore it for now. ! 1044: */ ! 1045: if (sc->sc_state != ST_RUN) { ! 1046: if (sc->sc_state == ST_IDLE && udainit(um->um_ctlr)) ! 1047: printf("uda%d: still hung\n", um->um_ctlr); ! 1048: return; ! 1049: } ! 1050: ! 1051: /* ! 1052: * If um_cmd is nonzero, this controller is on the Unibus ! 1053: * resource wait queue. It will not help to try more requests; ! 1054: * instead, when the Unibus unblocks and calls udadgo(), we ! 1055: * will call udastart() again. ! 1056: */ ! 1057: if (um->um_cmd) ! 1058: return; ! 1059: ! 1060: sc->sc_flags |= SC_INSTART; ! 1061: udaddr = (struct udadevice *) um->um_addr; ! 1062: ! 1063: loop: ! 1064: /* ! 1065: * Service the drive at the head of the queue. It may not ! 1066: * need anything, in which case it might be shutting down ! 1067: * in udaclose(). ! 1068: */ ! 1069: if ((dp = um->um_tab.b_actf) == NULL) ! 1070: goto out; ! 1071: if ((bp = dp->b_actf) == NULL) { ! 1072: dp->b_active = 0; ! 1073: um->um_tab.b_actf = dp->b_forw; ! 1074: if (ra_info[dp - udautab].ra_openpart == 0) ! 1075: wakeup((caddr_t)dp); /* finish close protocol */ ! 1076: goto loop; ! 1077: } ! 1078: ! 1079: if (udaddr->udasa & UDA_ERR) { /* ctlr fatal error */ ! 1080: udasaerror(um, 1); ! 1081: goto out; ! 1082: } ! 1083: ! 1084: /* ! 1085: * Get an MSCP packet, then figure out what to do. If ! 1086: * we cannot get a command packet, the command ring may ! 1087: * be too small: We should have at least as many command ! 1088: * packets as credits, for best performance. ! 1089: */ ! 1090: if ((mp = mscp_getcp(&sc->sc_mi, MSCP_DONTWAIT)) == NULL) { ! 1091: if (sc->sc_mi.mi_credits > MSCP_MINCREDITS && ! 1092: (sc->sc_flags & SC_GRIPED) == 0) { ! 1093: log(LOG_NOTICE, "uda%d: command ring too small\n", ! 1094: um->um_ctlr); ! 1095: sc->sc_flags |= SC_GRIPED;/* complain only once */ ! 1096: } ! 1097: goto out; ! 1098: } ! 1099: ! 1100: /* ! 1101: * Bring the drive on line if it is not already. Get its status ! 1102: * if we do not already have it. Otherwise just start the transfer. ! 1103: */ ! 1104: ui = udadinfo[udaunit(bp->b_dev)]; ! 1105: if ((ui->ui_flags & UNIT_ONLINE) == 0) { ! 1106: mp->mscp_opcode = M_OP_ONLINE; ! 1107: goto common; ! 1108: } ! 1109: if ((ui->ui_flags & UNIT_HAVESTATUS) == 0) { ! 1110: mp->mscp_opcode = M_OP_GETUNITST; ! 1111: common: ! 1112: if (ui->ui_flags & UNIT_REQUEUE) panic("udastart"); ! 1113: /* ! 1114: * Take the drive off the controller queue. When the ! 1115: * command finishes, make sure the drive is requeued. ! 1116: */ ! 1117: um->um_tab.b_actf = dp->b_forw; ! 1118: dp->b_active = 0; ! 1119: ui->ui_flags |= UNIT_REQUEUE; ! 1120: mp->mscp_unit = ui->ui_slave; ! 1121: *mp->mscp_addr |= MSCP_OWN | MSCP_INT; ! 1122: sc->sc_flags |= SC_STARTPOLL; ! 1123: #ifdef POLLSTATS ! 1124: sc->sc_ncmd++; ! 1125: #endif ! 1126: goto loop; ! 1127: } ! 1128: ! 1129: pp = &udalabel[ui->ui_unit].d_partitions[udapart(bp->b_dev)]; ! 1130: mp->mscp_opcode = (bp->b_flags & B_READ) ? M_OP_READ : M_OP_WRITE; ! 1131: mp->mscp_unit = ui->ui_slave; ! 1132: mp->mscp_seq.seq_lbn = bp->b_blkno + pp->p_offset; ! 1133: sz = (bp->b_bcount + DEV_BSIZE - 1) >> DEV_BSHIFT; ! 1134: mp->mscp_seq.seq_bytecount = bp->b_blkno + sz > pp->p_size ? ! 1135: (pp->p_size - bp->b_blkno) >> DEV_BSHIFT : bp->b_bcount; ! 1136: /* mscp_cmdref is filled in by mscp_go() */ ! 1137: ! 1138: /* ! 1139: * Drop the packet pointer into the `command' field so udadgo() ! 1140: * can tell what to start. If ubago returns 1, we can do another ! 1141: * transfer. If not, um_cmd will still point at mp, so we will ! 1142: * know that we are waiting for resources. ! 1143: */ ! 1144: um->um_cmd = (int)mp; ! 1145: if (ubago(ui)) ! 1146: goto loop; ! 1147: ! 1148: /* ! 1149: * All done, or blocked in ubago(). If we managed to ! 1150: * issue some commands, start up the beast. ! 1151: */ ! 1152: out: ! 1153: if (sc->sc_flags & SC_STARTPOLL) { ! 1154: #ifdef POLLSTATS ! 1155: udastats.cmd[sc->sc_ncmd]++; ! 1156: sc->sc_ncmd = 0; ! 1157: #endif ! 1158: i = ((struct udadevice *)um->um_addr)->udaip; ! 1159: } ! 1160: sc->sc_flags &= ~(SC_INSTART | SC_STARTPOLL); ! 1161: } ! 1162: ! 1163: /* ! 1164: * Start a transfer. ! 1165: * ! 1166: * If we are not called from within udastart(), we must have been ! 1167: * blocked, so call udastart to do more requests (if any). If ! 1168: * this calls us again immediately we will not recurse, because ! 1169: * that time we will be in udastart(). Clever.... ! 1170: */ ! 1171: udadgo(um) ! 1172: register struct uba_ctlr *um; ! 1173: { ! 1174: struct uda_softc *sc = &uda_softc[um->um_ctlr]; ! 1175: struct mscp *mp = (struct mscp *)um->um_cmd; ! 1176: ! 1177: um->um_tab.b_active++; /* another transfer going */ ! 1178: ! 1179: /* ! 1180: * Fill in the MSCP packet and move the buffer to the ! 1181: * I/O wait queue. Mark the controller as no longer on ! 1182: * the resource queue, and remember to initiate polling. ! 1183: */ ! 1184: mp->mscp_seq.seq_buffer = UBAI_ADDR(um->um_ubinfo) | ! 1185: (UBAI_BDP(um->um_ubinfo) << 24); ! 1186: mscp_go(&sc->sc_mi, mp, um->um_ubinfo); ! 1187: um->um_cmd = 0; ! 1188: um->um_ubinfo = 0; /* tyke it awye */ ! 1189: sc->sc_flags |= SC_STARTPOLL; ! 1190: #ifdef POLLSTATS ! 1191: sc->sc_ncmd++; ! 1192: #endif ! 1193: if ((sc->sc_flags & SC_INSTART) == 0) ! 1194: udastart(um); ! 1195: } ! 1196: ! 1197: udaiodone(mi, bp, info) ! 1198: register struct mscp_info *mi; ! 1199: struct buf *bp; ! 1200: int info; ! 1201: { ! 1202: register struct uba_ctlr *um = udaminfo[mi->mi_ctlr]; ! 1203: ! 1204: um->um_ubinfo = info; ! 1205: ubadone(um); ! 1206: biodone(bp); ! 1207: if (um->um_bdp && mi->mi_wtab.av_forw == &mi->mi_wtab) ! 1208: ubarelse(um->um_ubanum, &um->um_bdp); ! 1209: um->um_tab.b_active--; /* another transfer done */ ! 1210: } ! 1211: ! 1212: static struct saerr { ! 1213: int code; /* error code (including UDA_ERR) */ ! 1214: char *desc; /* what it means: Efoo => foo error */ ! 1215: } saerr[] = { ! 1216: { 0100001, "Eunibus packet read" }, ! 1217: { 0100002, "Eunibus packet write" }, ! 1218: { 0100003, "EUDA ROM and RAM parity" }, ! 1219: { 0100004, "EUDA RAM parity" }, ! 1220: { 0100005, "EUDA ROM parity" }, ! 1221: { 0100006, "Eunibus ring read" }, ! 1222: { 0100007, "Eunibus ring write" }, ! 1223: { 0100010, " unibus interrupt master failure" }, ! 1224: { 0100011, "Ehost access timeout" }, ! 1225: { 0100012, " host exceeded command limit" }, ! 1226: { 0100013, " unibus bus master failure" }, ! 1227: { 0100014, " DM XFC fatal error" }, ! 1228: { 0100015, " hardware timeout of instruction loop" }, ! 1229: { 0100016, " invalid virtual circuit id" }, ! 1230: { 0100017, "Eunibus interrupt write" }, ! 1231: { 0104000, "Efatal sequence" }, ! 1232: { 0104040, " D proc ALU" }, ! 1233: { 0104041, "ED proc control ROM parity" }, ! 1234: { 0105102, "ED proc w/no BD#2 or RAM parity" }, ! 1235: { 0105105, "ED proc RAM buffer" }, ! 1236: { 0105152, "ED proc SDI" }, ! 1237: { 0105153, "ED proc write mode wrap serdes" }, ! 1238: { 0105154, "ED proc read mode serdes, RSGEN & ECC" }, ! 1239: { 0106040, "EU proc ALU" }, ! 1240: { 0106041, "EU proc control reg" }, ! 1241: { 0106042, " U proc DFAIL/cntl ROM parity/BD #1 test CNT" }, ! 1242: { 0106047, " U proc const PROM err w/D proc running SDI test" }, ! 1243: { 0106055, " unexpected trap" }, ! 1244: { 0106071, "EU proc const PROM" }, ! 1245: { 0106072, "EU proc control ROM parity" }, ! 1246: { 0106200, "Estep 1 data" }, ! 1247: { 0107103, "EU proc RAM parity" }, ! 1248: { 0107107, "EU proc RAM buffer" }, ! 1249: { 0107115, " test count wrong (BD 12)" }, ! 1250: { 0112300, "Estep 2" }, ! 1251: { 0122240, "ENPR" }, ! 1252: { 0122300, "Estep 3" }, ! 1253: { 0142300, "Estep 4" }, ! 1254: { 0, " unknown error code" } ! 1255: }; ! 1256: ! 1257: /* ! 1258: * If the error bit was set in the controller status register, gripe, ! 1259: * then (optionally) reset the controller and requeue pending transfers. ! 1260: */ ! 1261: udasaerror(um, doreset) ! 1262: register struct uba_ctlr *um; ! 1263: int doreset; ! 1264: { ! 1265: register int code = ((struct udadevice *)um->um_addr)->udasa; ! 1266: register struct saerr *e; ! 1267: ! 1268: if ((code & UDA_ERR) == 0) ! 1269: return; ! 1270: for (e = saerr; e->code; e++) ! 1271: if (e->code == code) ! 1272: break; ! 1273: printf("uda%d: controller error, sa=0%o (%s%s)\n", ! 1274: um->um_ctlr, code, e->desc + 1, ! 1275: *e->desc == 'E' ? " error" : ""); ! 1276: if (doreset) { ! 1277: mscp_requeue(&uda_softc[um->um_ctlr].sc_mi); ! 1278: (void) udainit(um->um_ctlr); ! 1279: } ! 1280: } ! 1281: ! 1282: /* ! 1283: * Interrupt routine. Depending on the state of the controller, ! 1284: * continue initialisation, or acknowledge command and response ! 1285: * interrupts, and process responses. ! 1286: */ ! 1287: udaintr(ctlr) ! 1288: int ctlr; ! 1289: { ! 1290: register struct uba_ctlr *um = udaminfo[ctlr]; ! 1291: register struct uda_softc *sc = &uda_softc[ctlr]; ! 1292: register struct udadevice *udaddr = (struct udadevice *)um->um_addr; ! 1293: register struct uda *ud; ! 1294: register struct mscp *mp; ! 1295: register int i; ! 1296: ! 1297: #ifdef QBA ! 1298: splx(sc->sc_ipl); /* Qbus interrupt protocol is odd */ ! 1299: #endif ! 1300: sc->sc_wticks = 0; /* reset interrupt watchdog */ ! 1301: ! 1302: /* ! 1303: * Combinations during steps 1, 2, and 3: STEPnMASK ! 1304: * corresponds to which bits should be tested; ! 1305: * STEPnGOOD corresponds to the pattern that should ! 1306: * appear after the interrupt from STEPn initialisation. ! 1307: * All steps test the bits in ALLSTEPS. ! 1308: */ ! 1309: #define ALLSTEPS (UDA_ERR|UDA_STEP4|UDA_STEP3|UDA_STEP2|UDA_STEP1) ! 1310: ! 1311: #define STEP1MASK (ALLSTEPS | UDA_IE | UDA_NCNRMASK) ! 1312: #define STEP1GOOD (UDA_STEP2 | UDA_IE | (NCMDL2 << 3) | NRSPL2) ! 1313: ! 1314: #define STEP2MASK (ALLSTEPS | UDA_IE | UDA_IVECMASK) ! 1315: #define STEP2GOOD (UDA_STEP3 | UDA_IE | (sc->sc_ivec >> 2)) ! 1316: ! 1317: #define STEP3MASK ALLSTEPS ! 1318: #define STEP3GOOD UDA_STEP4 ! 1319: ! 1320: switch (sc->sc_state) { ! 1321: ! 1322: case ST_IDLE: ! 1323: /* ! 1324: * Ignore unsolicited interrupts. ! 1325: */ ! 1326: log(LOG_WARNING, "uda%d: stray intr\n", ctlr); ! 1327: return; ! 1328: ! 1329: case ST_STEP1: ! 1330: /* ! 1331: * Begin step two initialisation. ! 1332: */ ! 1333: if ((udaddr->udasa & STEP1MASK) != STEP1GOOD) { ! 1334: i = 1; ! 1335: initfailed: ! 1336: printf("uda%d: init step %d failed, sa=%b\n", ! 1337: ctlr, i, udaddr->udasa, udasr_bits); ! 1338: udasaerror(um, 0); ! 1339: sc->sc_state = ST_IDLE; ! 1340: if (sc->sc_flags & SC_DOWAKE) { ! 1341: sc->sc_flags &= ~SC_DOWAKE; ! 1342: wakeup((caddr_t)sc); ! 1343: } ! 1344: return; ! 1345: } ! 1346: udaddr->udasa = (int)&sc->sc_uda->uda_ca.ca_rspdsc[0] | ! 1347: (cpu == VAX_780 || cpu == VAX_8600 ? UDA_PI : 0); ! 1348: sc->sc_state = ST_STEP2; ! 1349: return; ! 1350: ! 1351: case ST_STEP2: ! 1352: /* ! 1353: * Begin step 3 initialisation. ! 1354: */ ! 1355: if ((udaddr->udasa & STEP2MASK) != STEP2GOOD) { ! 1356: i = 2; ! 1357: goto initfailed; ! 1358: } ! 1359: udaddr->udasa = ((int)&sc->sc_uda->uda_ca.ca_rspdsc[0]) >> 16; ! 1360: sc->sc_state = ST_STEP3; ! 1361: return; ! 1362: ! 1363: case ST_STEP3: ! 1364: /* ! 1365: * Set controller characteristics (finish initialisation). ! 1366: */ ! 1367: if ((udaddr->udasa & STEP3MASK) != STEP3GOOD) { ! 1368: i = 3; ! 1369: goto initfailed; ! 1370: } ! 1371: i = udaddr->udasa & 0xff; ! 1372: if (i != sc->sc_micro) { ! 1373: sc->sc_micro = i; ! 1374: printf("uda%d: version %d model %d\n", ! 1375: ctlr, i & 0xf, i >> 4); ! 1376: } ! 1377: ! 1378: /* ! 1379: * Present the burst size, then remove it. Why this ! 1380: * should be done this way, I have no idea. ! 1381: * ! 1382: * Note that this assumes udaburst[ctlr] > 0. ! 1383: */ ! 1384: udaddr->udasa = UDA_GO | (udaburst[ctlr] - 1) << 2; ! 1385: udaddr->udasa = UDA_GO; ! 1386: printf("uda%d: DMA burst size set to %d\n", ! 1387: ctlr, udaburst[ctlr]); ! 1388: ! 1389: udainitds(ctlr); /* initialise data structures */ ! 1390: ! 1391: /* ! 1392: * Before we can get a command packet, we need some ! 1393: * credits. Fake some up to keep mscp_getcp() happy, ! 1394: * get a packet, and cancel all credits (the right ! 1395: * number should come back in the response to the ! 1396: * SCC packet). ! 1397: */ ! 1398: sc->sc_mi.mi_credits = MSCP_MINCREDITS + 1; ! 1399: mp = mscp_getcp(&sc->sc_mi, MSCP_DONTWAIT); ! 1400: if (mp == NULL) /* `cannot happen' */ ! 1401: panic("udaintr"); ! 1402: sc->sc_mi.mi_credits = 0; ! 1403: mp->mscp_opcode = M_OP_SETCTLRC; ! 1404: mp->mscp_unit = 0; ! 1405: mp->mscp_sccc.sccc_ctlrflags = M_CF_ATTN | M_CF_MISC | ! 1406: M_CF_THIS; ! 1407: *mp->mscp_addr |= MSCP_OWN | MSCP_INT; ! 1408: i = udaddr->udaip; ! 1409: sc->sc_state = ST_SETCHAR; ! 1410: return; ! 1411: ! 1412: case ST_SETCHAR: ! 1413: case ST_RUN: ! 1414: /* ! 1415: * Handle Set Ctlr Characteristics responses and operational ! 1416: * responses (via mscp_dorsp). ! 1417: */ ! 1418: break; ! 1419: ! 1420: default: ! 1421: printf("uda%d: driver bug, state %d\n", ctlr, sc->sc_state); ! 1422: panic("udastate"); ! 1423: } ! 1424: ! 1425: if (udaddr->udasa & UDA_ERR) { /* ctlr fatal error */ ! 1426: udasaerror(um, 1); ! 1427: return; ! 1428: } ! 1429: ! 1430: ud = &uda[ctlr]; ! 1431: ! 1432: /* ! 1433: * Handle buffer purge requests. ! 1434: */ ! 1435: if (ud->uda_ca.ca_bdp) { ! 1436: UBAPURGE(um->um_hd->uh_uba, ud->uda_ca.ca_bdp); ! 1437: ud->uda_ca.ca_bdp = 0; ! 1438: udaddr->udasa = 0; /* signal purge complete */ ! 1439: } ! 1440: ! 1441: /* ! 1442: * Check for response and command ring transitions. ! 1443: */ ! 1444: if (ud->uda_ca.ca_rspint) { ! 1445: ud->uda_ca.ca_rspint = 0; ! 1446: mscp_dorsp(&sc->sc_mi); ! 1447: } ! 1448: if (ud->uda_ca.ca_cmdint) { ! 1449: ud->uda_ca.ca_cmdint = 0; ! 1450: MSCP_DOCMD(&sc->sc_mi); ! 1451: } ! 1452: udastart(um); ! 1453: } ! 1454: ! 1455: /* ! 1456: * Initialise the various data structures that control the UDA50. ! 1457: */ ! 1458: udainitds(ctlr) ! 1459: int ctlr; ! 1460: { ! 1461: register struct uda *ud = &uda[ctlr]; ! 1462: register struct uda *uud = uda_softc[ctlr].sc_uda; ! 1463: register struct mscp *mp; ! 1464: register int i; ! 1465: ! 1466: for (i = 0, mp = ud->uda_rsp; i < NRSP; i++, mp++) { ! 1467: ud->uda_ca.ca_rspdsc[i] = MSCP_OWN | MSCP_INT | ! 1468: (long)&uud->uda_rsp[i].mscp_cmdref; ! 1469: mp->mscp_addr = &ud->uda_ca.ca_rspdsc[i]; ! 1470: mp->mscp_msglen = MSCP_MSGLEN; ! 1471: } ! 1472: for (i = 0, mp = ud->uda_cmd; i < NCMD; i++, mp++) { ! 1473: ud->uda_ca.ca_cmddsc[i] = MSCP_INT | ! 1474: (long)&uud->uda_cmd[i].mscp_cmdref; ! 1475: mp->mscp_addr = &ud->uda_ca.ca_cmddsc[i]; ! 1476: mp->mscp_msglen = MSCP_MSGLEN; ! 1477: } ! 1478: } ! 1479: ! 1480: /* ! 1481: * Handle an error datagram. ! 1482: */ ! 1483: udadgram(mi, mp) ! 1484: struct mscp_info *mi; ! 1485: struct mscp *mp; ! 1486: { ! 1487: ! 1488: mscp_decodeerror(mi->mi_md->md_mname, mi->mi_ctlr, mp); ! 1489: /* ! 1490: * SDI status information bytes 10 and 11 are the microprocessor ! 1491: * error code and front panel code respectively. These vary per ! 1492: * drive type and are printed purely for field service information. ! 1493: */ ! 1494: if (mp->mscp_format == M_FM_SDI) ! 1495: printf("\tsdi uproc error code 0x%x, front panel code 0x%x\n", ! 1496: mp->mscp_erd.erd_sdistat[10], ! 1497: mp->mscp_erd.erd_sdistat[11]); ! 1498: } ! 1499: ! 1500: /* ! 1501: * The Set Controller Characteristics command finished. ! 1502: * Record the new state of the controller. ! 1503: */ ! 1504: udactlrdone(mi, mp) ! 1505: register struct mscp_info *mi; ! 1506: struct mscp *mp; ! 1507: { ! 1508: register struct uda_softc *sc = &uda_softc[mi->mi_ctlr]; ! 1509: ! 1510: if ((mp->mscp_status & M_ST_MASK) == M_ST_SUCCESS) ! 1511: sc->sc_state = ST_RUN; ! 1512: else { ! 1513: printf("uda%d: SETCTLRC failed: ", ! 1514: mi->mi_ctlr, mp->mscp_status); ! 1515: mscp_printevent(mp); ! 1516: sc->sc_state = ST_IDLE; ! 1517: } ! 1518: if (sc->sc_flags & SC_DOWAKE) { ! 1519: sc->sc_flags &= ~SC_DOWAKE; ! 1520: wakeup((caddr_t)sc); ! 1521: } ! 1522: } ! 1523: ! 1524: /* ! 1525: * Received a response from an as-yet unconfigured drive. Configure it ! 1526: * in, if possible. ! 1527: */ ! 1528: udaunconf(mi, mp) ! 1529: struct mscp_info *mi; ! 1530: register struct mscp *mp; ! 1531: { ! 1532: ! 1533: /* ! 1534: * If it is a slave response, copy it to udaslavereply for ! 1535: * udaslave() to look at. ! 1536: */ ! 1537: if (mp->mscp_opcode == (M_OP_GETUNITST | M_OP_END) && ! 1538: (uda_softc[mi->mi_ctlr].sc_flags & SC_INSLAVE) != 0) { ! 1539: udaslavereply = *mp; ! 1540: return (MSCP_DONE); ! 1541: } ! 1542: ! 1543: /* ! 1544: * Otherwise, it had better be an available attention response. ! 1545: */ ! 1546: if (mp->mscp_opcode != M_OP_AVAILATTN) ! 1547: return (MSCP_FAILED); ! 1548: ! 1549: /* do what autoconf does */ ! 1550: return (MSCP_FAILED); /* not yet, arwhite, not yet */ ! 1551: } ! 1552: ! 1553: /* ! 1554: * A drive came on line. Check its type and size. Return DONE if ! 1555: * we think the drive is truly on line. In any case, awaken anyone ! 1556: * sleeping on the drive on-line-ness. ! 1557: */ ! 1558: udaonline(ui, mp) ! 1559: register struct uba_device *ui; ! 1560: struct mscp *mp; ! 1561: { ! 1562: register struct ra_info *ra = &ra_info[ui->ui_unit]; ! 1563: ! 1564: wakeup((caddr_t)&ui->ui_flags); ! 1565: if ((mp->mscp_status & M_ST_MASK) != M_ST_SUCCESS) { ! 1566: if (!cold) ! 1567: printf("uda%d: ra%d", ui->ui_ctlr, ui->ui_unit); ! 1568: printf(": attempt to bring on line failed: "); ! 1569: mscp_printevent(mp); ! 1570: ra->ra_state = CLOSED; ! 1571: return (MSCP_FAILED); ! 1572: } ! 1573: ! 1574: ra->ra_state = OPENRAW; ! 1575: ra->ra_dsize = (daddr_t)mp->mscp_onle.onle_unitsize; ! 1576: if (!cold) ! 1577: printf("ra%d: uda%d, unit %d, size = %d sectors\n", ui->ui_unit, ! 1578: ui->ui_ctlr, mp->mscp_unit, ra->ra_dsize); ! 1579: /* can now compute ncyl */ ! 1580: ra->ra_geom.rg_ncyl = ra->ra_dsize / ra->ra_geom.rg_ntracks / ! 1581: ra->ra_geom.rg_nsectors; ! 1582: return (MSCP_DONE); ! 1583: } ! 1584: ! 1585: /* ! 1586: * We got some (configured) unit's status. Return DONE if it succeeded. ! 1587: */ ! 1588: udagotstatus(ui, mp) ! 1589: register struct uba_device *ui; ! 1590: register struct mscp *mp; ! 1591: { ! 1592: ! 1593: if ((mp->mscp_status & M_ST_MASK) != M_ST_SUCCESS) { ! 1594: printf("uda%d: attempt to get status for ra%d failed: ", ! 1595: ui->ui_ctlr, ui->ui_unit); ! 1596: mscp_printevent(mp); ! 1597: return (MSCP_FAILED); ! 1598: } ! 1599: /* record for (future) bad block forwarding and whatever else */ ! 1600: uda_rasave(ui->ui_unit, mp, 1); ! 1601: return (MSCP_DONE); ! 1602: } ! 1603: ! 1604: /* ! 1605: * A transfer failed. We get a chance to fix or restart it. ! 1606: * Need to write the bad block forwaring code first.... ! 1607: */ ! 1608: /*ARGSUSED*/ ! 1609: udaioerror(ui, mp, bp) ! 1610: register struct uba_device *ui; ! 1611: register struct mscp *mp; ! 1612: struct buf *bp; ! 1613: { ! 1614: ! 1615: if (mp->mscp_flags & M_EF_BBLKR) { ! 1616: /* ! 1617: * A bad block report. Eventually we will ! 1618: * restart this transfer, but for now, just ! 1619: * log it and give up. ! 1620: */ ! 1621: log(LOG_ERR, "ra%d: bad block report: %d%s\n", ! 1622: ui->ui_unit, mp->mscp_seq.seq_lbn, ! 1623: mp->mscp_flags & M_EF_BBLKU ? " + others" : ""); ! 1624: } else { ! 1625: /* ! 1626: * What the heck IS a `serious exception' anyway? ! 1627: * IT SURE WOULD BE NICE IF DEC SOLD DOCUMENTATION ! 1628: * FOR THEIR OWN CONTROLLERS. ! 1629: */ ! 1630: if (mp->mscp_flags & M_EF_SEREX) ! 1631: log(LOG_ERR, "ra%d: serious exception reported\n", ! 1632: ui->ui_unit); ! 1633: } ! 1634: return (MSCP_FAILED); ! 1635: } ! 1636: ! 1637: /* ! 1638: * A replace operation finished. ! 1639: */ ! 1640: /*ARGSUSED*/ ! 1641: udareplace(ui, mp) ! 1642: struct uba_device *ui; ! 1643: struct mscp *mp; ! 1644: { ! 1645: ! 1646: panic("udareplace"); ! 1647: } ! 1648: ! 1649: /* ! 1650: * A bad block related operation finished. ! 1651: */ ! 1652: /*ARGSUSED*/ ! 1653: udabb(ui, mp, bp) ! 1654: struct uba_device *ui; ! 1655: struct mscp *mp; ! 1656: struct buf *bp; ! 1657: { ! 1658: ! 1659: panic("udabb"); ! 1660: } ! 1661: ! 1662: ! 1663: /* ! 1664: * I/O controls. ! 1665: */ ! 1666: udaioctl(dev, cmd, data, flag) ! 1667: dev_t dev; ! 1668: int cmd; ! 1669: caddr_t data; ! 1670: int flag; ! 1671: { ! 1672: register int unit = udaunit(dev); ! 1673: register struct disklabel *lp; ! 1674: register struct ra_info *ra = &ra_info[unit]; ! 1675: int error = 0; ! 1676: ! 1677: lp = &udalabel[unit]; ! 1678: ! 1679: switch (cmd) { ! 1680: ! 1681: case DIOCGDINFO: ! 1682: *(struct disklabel *)data = *lp; ! 1683: break; ! 1684: ! 1685: case DIOCGPART: ! 1686: ((struct partinfo *)data)->disklab = lp; ! 1687: ((struct partinfo *)data)->part = ! 1688: &lp->d_partitions[udapart(dev)]; ! 1689: break; ! 1690: ! 1691: case DIOCSDINFO: ! 1692: if ((flag & FWRITE) == 0) ! 1693: error = EBADF; ! 1694: else ! 1695: error = setdisklabel(lp, (struct disklabel *)data, ! 1696: (ra->ra_state == OPENRAW) ? 0 : ra->ra_openpart); ! 1697: break; ! 1698: ! 1699: case DIOCWLABEL: ! 1700: if ((flag & FWRITE) == 0) ! 1701: error = EBADF; ! 1702: else ! 1703: ra->ra_wlabel = *(int *)data; ! 1704: break; ! 1705: ! 1706: case DIOCWDINFO: ! 1707: if ((flag & FWRITE) == 0) ! 1708: error = EBADF; ! 1709: else if ((error = setdisklabel(lp, (struct disklabel *)data, ! 1710: (ra->ra_state == OPENRAW) ? 0 : ra->ra_openpart)) == 0) { ! 1711: int wlab; ! 1712: ! 1713: ra->ra_state = OPEN; ! 1714: /* simulate opening partition 0 so write succeeds */ ! 1715: ra->ra_openpart |= (1 << 0); /* XXX */ ! 1716: wlab = ra->ra_wlabel; ! 1717: ra->ra_wlabel = 1; ! 1718: error = writedisklabel(dev, udastrategy, lp); ! 1719: ra->ra_openpart = ra->ra_copenpart | ra->ra_bopenpart; ! 1720: ra->ra_wlabel = wlab; ! 1721: } ! 1722: break; ! 1723: ! 1724: #ifdef notyet ! 1725: case UDAIOCREPLACE: ! 1726: /* ! 1727: * Initiate bad block replacement for the given LBN. ! 1728: * (Should we allow modifiers?) ! 1729: */ ! 1730: error = EOPNOTSUPP; ! 1731: break; ! 1732: ! 1733: case UDAIOCGMICRO: ! 1734: /* ! 1735: * Return the microcode revision for the UDA50 running ! 1736: * this drive. ! 1737: */ ! 1738: *(int *)data = uda_softc[uddinfo[unit]->ui_ctlr].sc_micro; ! 1739: break; ! 1740: #endif ! 1741: ! 1742: default: ! 1743: error = ENOTTY; ! 1744: break; ! 1745: } ! 1746: return (error); ! 1747: } ! 1748: ! 1749: /* ! 1750: * A Unibus reset has occurred on UBA uban. Reinitialise the controller(s) ! 1751: * on that Unibus, and requeue outstanding I/O. ! 1752: */ ! 1753: udareset(uban) ! 1754: int uban; ! 1755: { ! 1756: register struct uba_ctlr *um; ! 1757: register struct uda_softc *sc; ! 1758: register int ctlr; ! 1759: ! 1760: for (ctlr = 0, sc = uda_softc; ctlr < NUDA; ctlr++, sc++) { ! 1761: if ((um = udaminfo[ctlr]) == NULL || um->um_ubanum != uban || ! 1762: um->um_alive == 0) ! 1763: continue; ! 1764: printf(" uda%d", ctlr); ! 1765: ! 1766: /* ! 1767: * Our BDP (if any) is gone; our command (if any) is ! 1768: * flushed; the device is no longer mapped; and the ! 1769: * UDA50 is not yet initialised. ! 1770: */ ! 1771: if (um->um_bdp) { ! 1772: printf("<%d>", UBAI_BDP(um->um_bdp)); ! 1773: um->um_bdp = 0; ! 1774: } ! 1775: um->um_ubinfo = 0; ! 1776: um->um_cmd = 0; ! 1777: sc->sc_flags &= ~SC_MAPPED; ! 1778: sc->sc_state = ST_IDLE; ! 1779: ! 1780: /* reset queues and requeue pending transfers */ ! 1781: mscp_requeue(&sc->sc_mi); ! 1782: ! 1783: /* ! 1784: * If it fails to initialise we will notice later and ! 1785: * try again (and again...). Do not call udastart() ! 1786: * here; it will be done after the controller finishes ! 1787: * initialisation. ! 1788: */ ! 1789: if (udainit(ctlr)) ! 1790: printf(" (hung)"); ! 1791: } ! 1792: } ! 1793: ! 1794: /* ! 1795: * Watchdog timer: If the controller is active, and no interrupts ! 1796: * have occurred for 30 seconds, assume it has gone away. ! 1797: */ ! 1798: udawatch() ! 1799: { ! 1800: register int i; ! 1801: register struct uba_ctlr *um; ! 1802: register struct uda_softc *sc; ! 1803: ! 1804: timeout(udawatch, (caddr_t) 0, hz); /* every second */ ! 1805: for (i = 0, sc = uda_softc; i < NUDA; i++, sc++) { ! 1806: if ((um = udaminfo[i]) == 0 || !um->um_alive) ! 1807: continue; ! 1808: if (sc->sc_state == ST_IDLE) ! 1809: continue; ! 1810: if (sc->sc_state == ST_RUN && !um->um_tab.b_active) ! 1811: sc->sc_wticks = 0; ! 1812: else if (++sc->sc_wticks >= 30) { ! 1813: sc->sc_wticks = 0; ! 1814: printf("uda%d: lost interrupt\n", i); ! 1815: ubareset(um->um_ubanum); ! 1816: } ! 1817: } ! 1818: } ! 1819: ! 1820: /* ! 1821: * Do a panic dump. We set up the controller for one command packet ! 1822: * and one response packet, for which we use `struct uda1'. ! 1823: */ ! 1824: struct uda1 { ! 1825: struct uda1ca uda1_ca; /* communications area */ ! 1826: struct mscp uda1_rsp; /* response packet */ ! 1827: struct mscp uda1_cmd; /* command packet */ ! 1828: } uda1; ! 1829: ! 1830: #define DBSIZE 32 /* dump 16K at a time */ ! 1831: ! 1832: udadump(dev) ! 1833: dev_t dev; ! 1834: { ! 1835: struct udadevice *udaddr; ! 1836: struct uda1 *ud_ubaddr; ! 1837: char *start; ! 1838: int num, blk, unit, maxsz, blkoff, reg; ! 1839: struct partition *pp; ! 1840: register struct uba_regs *uba; ! 1841: register struct uba_device *ui; ! 1842: register struct uda1 *ud; ! 1843: register struct pte *io; ! 1844: register int i; ! 1845: ! 1846: /* ! 1847: * Make sure the device is a reasonable place on which to dump. ! 1848: */ ! 1849: unit = udaunit(dev); ! 1850: if (unit >= NRA) ! 1851: return (ENXIO); ! 1852: #define phys(cast, addr) ((cast) ((int)addr & 0x7fffffff)) ! 1853: ui = phys(struct uba_device *, udadinfo[unit]); ! 1854: if (ui == NULL || ui->ui_alive == 0) ! 1855: return (ENXIO); ! 1856: ! 1857: /* ! 1858: * Find and initialise the UBA; get the physical address of the ! 1859: * device registers, and of communications area and command and ! 1860: * response packet. ! 1861: */ ! 1862: uba = phys(struct uba_hd *, ui->ui_hd)->uh_physuba; ! 1863: ubainit(uba); ! 1864: udaddr = (struct udadevice *)ui->ui_physaddr; ! 1865: ud = phys(struct uda1 *, &uda1); ! 1866: ! 1867: /* ! 1868: * Map the ca+packets into Unibus I/O space so the UDA50 can get ! 1869: * at them. Use the registers at the end of the Unibus map (since ! 1870: * we will use the registers at the beginning to map the memory ! 1871: * we are dumping). ! 1872: */ ! 1873: num = btoc(sizeof(struct uda1)) + 1; ! 1874: reg = NUBMREG - num; ! 1875: io = &uba->uba_map[reg]; ! 1876: for (i = 0; i < num; i++) ! 1877: *(int *)io++ = UBAMR_MRV | (btop(ud) + i); ! 1878: ud_ubaddr = (struct uda1 *)(((int)ud & PGOFSET) | (reg << 9)); ! 1879: ! 1880: /* ! 1881: * Initialise the controller, with one command and one response ! 1882: * packet. ! 1883: */ ! 1884: udaddr->udaip = 0; ! 1885: if (udadumpwait(udaddr, UDA_STEP1)) ! 1886: return (EFAULT); ! 1887: udaddr->udasa = UDA_ERR; ! 1888: if (udadumpwait(udaddr, UDA_STEP2)) ! 1889: return (EFAULT); ! 1890: udaddr->udasa = (int)&ud_ubaddr->uda1_ca.ca_rspdsc; ! 1891: if (udadumpwait(udaddr, UDA_STEP3)) ! 1892: return (EFAULT); ! 1893: udaddr->udasa = ((int)&ud_ubaddr->uda1_ca.ca_rspdsc) >> 16; ! 1894: if (udadumpwait(udaddr, UDA_STEP4)) ! 1895: return (EFAULT); ! 1896: uda_softc[ui->ui_ctlr].sc_micro = udaddr->udasa & 0xff; ! 1897: udaddr->udasa = UDA_GO; ! 1898: ! 1899: /* ! 1900: * Set up the command and response descriptor, then set the ! 1901: * controller characteristics and bring the drive on line. ! 1902: * Note that all uninitialised locations in uda1_cmd are zero. ! 1903: */ ! 1904: ud->uda1_ca.ca_rspdsc = (long)&ud_ubaddr->uda1_rsp.mscp_cmdref; ! 1905: ud->uda1_ca.ca_cmddsc = (long)&ud_ubaddr->uda1_cmd.mscp_cmdref; ! 1906: /* ud->uda1_cmd.mscp_sccc.sccc_ctlrflags = 0; */ ! 1907: /* ud->uda1_cmd.mscp_sccc.sccc_version = 0; */ ! 1908: if (udadumpcmd(M_OP_SETCTLRC, ud, ui)) ! 1909: return (EFAULT); ! 1910: ud->uda1_cmd.mscp_unit = ui->ui_slave; ! 1911: if (udadumpcmd(M_OP_ONLINE, ud, ui)) ! 1912: return (EFAULT); ! 1913: ! 1914: pp = phys(struct partition *, ! 1915: &udalabel[unit].d_partitions[udapart(dev)]); ! 1916: maxsz = pp->p_size; ! 1917: blkoff = pp->p_offset; ! 1918: ! 1919: /* ! 1920: * Dump all of physical memory, or as much as will fit in the ! 1921: * space provided. ! 1922: */ ! 1923: start = 0; ! 1924: num = maxfree; ! 1925: if (dumplo + num >= maxsz) ! 1926: num = maxsz - dumplo; ! 1927: blkoff += dumplo; ! 1928: ! 1929: /* ! 1930: * Write out memory, DBSIZE pages at a time. ! 1931: * N.B.: this code depends on the fact that the sector ! 1932: * size == the page size. ! 1933: */ ! 1934: while (num > 0) { ! 1935: blk = num > DBSIZE ? DBSIZE : num; ! 1936: io = uba->uba_map; ! 1937: /* ! 1938: * Map in the pages to write, leaving an invalid entry ! 1939: * at the end to guard against wild Unibus transfers. ! 1940: * Then do the write. ! 1941: */ ! 1942: for (i = 0; i < blk; i++) ! 1943: *(int *)io++ = UBAMR_MRV | (btop(start) + i); ! 1944: *(int *)io = 0; ! 1945: ud->uda1_cmd.mscp_unit = ui->ui_slave; ! 1946: ud->uda1_cmd.mscp_seq.seq_lbn = btop(start) + blkoff; ! 1947: ud->uda1_cmd.mscp_seq.seq_bytecount = blk << PGSHIFT; ! 1948: if (udadumpcmd(M_OP_WRITE, ud, ui)) ! 1949: return (EIO); ! 1950: start += blk << PGSHIFT; ! 1951: num -= blk; ! 1952: } ! 1953: return (0); /* made it! */ ! 1954: } ! 1955: ! 1956: /* ! 1957: * Wait for some of the bits in `bits' to come on. If the error bit ! 1958: * comes on, or ten seconds pass without response, return true (error). ! 1959: */ ! 1960: udadumpwait(udaddr, bits) ! 1961: register struct udadevice *udaddr; ! 1962: register int bits; ! 1963: { ! 1964: register int timo = todr() + 1000; ! 1965: ! 1966: while ((udaddr->udasa & bits) == 0) { ! 1967: if (udaddr->udasa & UDA_ERR) { ! 1968: printf("udasa=%b\ndump ", udaddr->udasa, udasr_bits); ! 1969: return (1); ! 1970: } ! 1971: if (todr() >= timo) { ! 1972: printf("timeout\ndump "); ! 1973: return (1); ! 1974: } ! 1975: } ! 1976: return (0); ! 1977: } ! 1978: ! 1979: /* ! 1980: * Feed a command to the UDA50, wait for its response, and return ! 1981: * true iff something went wrong. ! 1982: */ ! 1983: udadumpcmd(op, ud, ui) ! 1984: int op; ! 1985: register struct uda1 *ud; ! 1986: struct uba_device *ui; ! 1987: { ! 1988: register struct udadevice *udaddr; ! 1989: register int n; ! 1990: #define mp (&ud->uda1_rsp) ! 1991: ! 1992: udaddr = (struct udadevice *)ui->ui_physaddr; ! 1993: ud->uda1_cmd.mscp_opcode = op; ! 1994: ud->uda1_cmd.mscp_msglen = MSCP_MSGLEN; ! 1995: ud->uda1_rsp.mscp_msglen = MSCP_MSGLEN; ! 1996: ud->uda1_ca.ca_rspdsc |= MSCP_OWN | MSCP_INT; ! 1997: ud->uda1_ca.ca_cmddsc |= MSCP_OWN | MSCP_INT; ! 1998: if (udaddr->udasa & UDA_ERR) { ! 1999: printf("udasa=%b\ndump ", udaddr->udasa, udasr_bits); ! 2000: return (1); ! 2001: } ! 2002: n = udaddr->udaip; ! 2003: n = todr() + 1000; ! 2004: for (;;) { ! 2005: if (todr() > n) { ! 2006: printf("timeout\ndump "); ! 2007: return (1); ! 2008: } ! 2009: if (ud->uda1_ca.ca_cmdint) ! 2010: ud->uda1_ca.ca_cmdint = 0; ! 2011: if (ud->uda1_ca.ca_rspint == 0) ! 2012: continue; ! 2013: ud->uda1_ca.ca_rspint = 0; ! 2014: if (mp->mscp_opcode == (op | M_OP_END)) ! 2015: break; ! 2016: printf("\n"); ! 2017: switch (MSCP_MSGTYPE(mp->mscp_msgtc)) { ! 2018: ! 2019: case MSCPT_SEQ: ! 2020: printf("sequential"); ! 2021: break; ! 2022: ! 2023: case MSCPT_DATAGRAM: ! 2024: mscp_decodeerror("uda", ui->ui_ctlr, mp); ! 2025: printf("datagram"); ! 2026: break; ! 2027: ! 2028: case MSCPT_CREDITS: ! 2029: printf("credits"); ! 2030: break; ! 2031: ! 2032: case MSCPT_MAINTENANCE: ! 2033: printf("maintenance"); ! 2034: break; ! 2035: ! 2036: default: ! 2037: printf("unknown (type 0x%x)", ! 2038: MSCP_MSGTYPE(mp->mscp_msgtc)); ! 2039: break; ! 2040: } ! 2041: printf(" ignored\ndump "); ! 2042: ud->uda1_ca.ca_rspdsc |= MSCP_OWN | MSCP_INT; ! 2043: } ! 2044: if ((mp->mscp_status & M_ST_MASK) != M_ST_SUCCESS) { ! 2045: printf("error: op 0x%x => 0x%x status 0x%x\ndump ", op, ! 2046: mp->mscp_opcode, mp->mscp_status); ! 2047: return (1); ! 2048: } ! 2049: return (0); ! 2050: #undef mp ! 2051: } ! 2052: ! 2053: /* ! 2054: * Return the size of a partition, if known, or -1 if not. ! 2055: */ ! 2056: udasize(dev) ! 2057: dev_t dev; ! 2058: { ! 2059: register int unit = udaunit(dev); ! 2060: register struct uba_device *ui; ! 2061: ! 2062: if (unit >= NRA || (ui = udadinfo[unit]) == NULL || ! 2063: ui->ui_alive == 0 || (ui->ui_flags & UNIT_ONLINE) == 0 || ! 2064: ra_info[unit].ra_state != OPEN) ! 2065: return (-1); ! 2066: return ((int)udalabel[unit].d_partitions[udapart(dev)].p_size); ! 2067: } ! 2068: ! 2069: #ifdef COMPAT_42 ! 2070: /* ! 2071: * Tables mapping unlabelled drives. ! 2072: */ ! 2073: struct size { ! 2074: daddr_t nblocks; ! 2075: daddr_t blkoff; ! 2076: } ra60_sizes[8] = { ! 2077: 15884, 0, /* A=sectors 0 thru 15883 */ ! 2078: 33440, 15884, /* B=sectors 15884 thru 49323 */ ! 2079: 400176, 0, /* C=sectors 0 thru 400175 */ ! 2080: 82080, 49324, /* 4.2 G => D=sectors 49324 thru 131403 */ ! 2081: 268772, 131404, /* 4.2 H => E=sectors 131404 thru 400175 */ ! 2082: 350852, 49324, /* F=sectors 49324 thru 400175 */ ! 2083: 157570, 242606, /* UCB G => G=sectors 242606 thru 400175 */ ! 2084: 193282, 49324, /* UCB H => H=sectors 49324 thru 242605 */ ! 2085: }, ra70_sizes[8] = { ! 2086: 15884, 0, /* A=blk 0 thru 15883 */ ! 2087: 33440, 15972, /* B=blk 15972 thru 49323 */ ! 2088: -1, 0, /* C=blk 0 thru end */ ! 2089: 15884, 341220, /* D=blk 341220 thru 357103 */ ! 2090: 55936, 357192, /* E=blk 357192 thru 413127 */ ! 2091: -1, 413457, /* F=blk 413457 thru end */ ! 2092: -1, 341220, /* G=blk 341220 thru end */ ! 2093: 291346, 49731, /* H=blk 49731 thru 341076 */ ! 2094: }, ra80_sizes[8] = { ! 2095: 15884, 0, /* A=sectors 0 thru 15883 */ ! 2096: 33440, 15884, /* B=sectors 15884 thru 49323 */ ! 2097: 242606, 0, /* C=sectors 0 thru 242605 */ ! 2098: 0, 0, /* D=unused */ ! 2099: 193282, 49324, /* UCB H => E=sectors 49324 thru 242605 */ ! 2100: 82080, 49324, /* 4.2 G => F=sectors 49324 thru 131403 */ ! 2101: 192696, 49910, /* G=sectors 49910 thru 242605 */ ! 2102: 111202, 131404, /* 4.2 H => H=sectors 131404 thru 242605 */ ! 2103: }, ra81_sizes[8] ={ ! 2104: /* ! 2105: * These are the new standard partition sizes for ra81's. ! 2106: * An RA_COMPAT system is compiled with D, E, and F corresponding ! 2107: * to the 4.2 partitions for G, H, and F respectively. ! 2108: */ ! 2109: #ifndef UCBRA ! 2110: 15884, 0, /* A=sectors 0 thru 15883 */ ! 2111: 66880, 16422, /* B=sectors 16422 thru 83301 */ ! 2112: 891072, 0, /* C=sectors 0 thru 891071 */ ! 2113: #ifdef RA_COMPAT ! 2114: 82080, 49324, /* 4.2 G => D=sectors 49324 thru 131403 */ ! 2115: 759668, 131404, /* 4.2 H => E=sectors 131404 thru 891071 */ ! 2116: 478582, 412490, /* 4.2 F => F=sectors 412490 thru 891071 */ ! 2117: #else ! 2118: 15884, 375564, /* D=sectors 375564 thru 391447 */ ! 2119: 307200, 391986, /* E=sectors 391986 thru 699185 */ ! 2120: 191352, 699720, /* F=sectors 699720 thru 891071 */ ! 2121: #endif RA_COMPAT ! 2122: 515508, 375564, /* G=sectors 375564 thru 891071 */ ! 2123: 291346, 83538, /* H=sectors 83538 thru 374883 */ ! 2124: ! 2125: /* ! 2126: * These partitions correspond to the sizes used by sites at Berkeley, ! 2127: * and by those sites that have received copies of the Berkeley driver ! 2128: * with deltas 6.2 or greater (11/15/83). ! 2129: */ ! 2130: #else UCBRA ! 2131: ! 2132: 15884, 0, /* A=sectors 0 thru 15883 */ ! 2133: 33440, 15884, /* B=sectors 15884 thru 49323 */ ! 2134: 891072, 0, /* C=sectors 0 thru 891071 */ ! 2135: 15884, 242606, /* D=sectors 242606 thru 258489 */ ! 2136: 307200, 258490, /* E=sectors 258490 thru 565689 */ ! 2137: 325382, 565690, /* F=sectors 565690 thru 891071 */ ! 2138: 648466, 242606, /* G=sectors 242606 thru 891071 */ ! 2139: 193282, 49324, /* H=sectors 49324 thru 242605 */ ! 2140: ! 2141: #endif UCBRA ! 2142: }, ra82_sizes[8] = { ! 2143: 15884, 0, /* A=blk 0 thru 15883 */ ! 2144: 66880, 16245, /* B=blk 16245 thru 83124 */ ! 2145: -1, 0, /* C=blk 0 thru end */ ! 2146: 15884, 375345, /* D=blk 375345 thru 391228 */ ! 2147: 307200, 391590, /* E=blk 391590 thru 698789 */ ! 2148: -1, 699390, /* F=blk 699390 thru end */ ! 2149: -1, 375345, /* G=blk 375345 thru end */ ! 2150: 291346, 83790, /* H=blk 83790 thru 375135 */ ! 2151: }, rc25_sizes[8] = { ! 2152: 15884, 0, /* A=blk 0 thru 15883 */ ! 2153: 10032, 15884, /* B=blk 15884 thru 49323 */ ! 2154: -1, 0, /* C=blk 0 thru end */ ! 2155: 0, 0, /* D=blk 340670 thru 356553 */ ! 2156: 0, 0, /* E=blk 356554 thru 412489 */ ! 2157: 0, 0, /* F=blk 412490 thru end */ ! 2158: -1, 25916, /* G=blk 49324 thru 131403 */ ! 2159: 0, 0, /* H=blk 131404 thru end */ ! 2160: }, rd52_sizes[8] = { ! 2161: 15884, 0, /* A=blk 0 thru 15883 */ ! 2162: 9766, 15884, /* B=blk 15884 thru 25649 */ ! 2163: -1, 0, /* C=blk 0 thru end */ ! 2164: 0, 0, /* D=unused */ ! 2165: 0, 0, /* E=unused */ ! 2166: 0, 0, /* F=unused */ ! 2167: -1, 25650, /* G=blk 25650 thru end */ ! 2168: 0, 0, /* H=unused */ ! 2169: }, rd53_sizes[8] = { ! 2170: 15884, 0, /* A=blk 0 thru 15883 */ ! 2171: 33440, 15884, /* B=blk 15884 thru 49323 */ ! 2172: -1, 0, /* C=blk 0 thru end */ ! 2173: 0, 0, /* D=unused */ ! 2174: 33440, 0, /* E=blk 0 thru 33439 */ ! 2175: -1, 33440, /* F=blk 33440 thru end */ ! 2176: -1, 49324, /* G=blk 49324 thru end */ ! 2177: -1, 15884, /* H=blk 15884 thru end */ ! 2178: }, rd54_sizes[8] = { ! 2179: 15884, 0, /* A=blk 0 thru 15883 */ ! 2180: 33440, 15884, /* B=blk 15884 thru 49323 */ ! 2181: -1, 0, /* C=blk 0 thru end */ ! 2182: 130938, 49324, /* D=blk 49324 thru 180261 */ ! 2183: 130938, 180262, /* E=blk 180262 thru 311199 (end) */ ! 2184: 0, 0, /* F=unused */ ! 2185: 261876, 49324, /* G=blk 49324 thru 311199 (end) */ ! 2186: 0, 0, /* H=unused */ ! 2187: }, rx50_sizes[8] = { ! 2188: 800, 0, /* A=blk 0 thru 799 */ ! 2189: 0, 0, ! 2190: -1, 0, /* C=blk 0 thru end */ ! 2191: 0, 0, ! 2192: 0, 0, ! 2193: 0, 0, ! 2194: 0, 0, ! 2195: 0, 0, ! 2196: }; ! 2197: ! 2198: /* ! 2199: * Media ID decoding table. ! 2200: */ ! 2201: struct udatypes { ! 2202: u_long ut_id; /* media drive ID */ ! 2203: char *ut_name; /* drive type name */ ! 2204: struct size *ut_sizes; /* partition tables */ ! 2205: int ut_nsectors, ut_ntracks, ut_ncylinders; ! 2206: } udatypes[] = { ! 2207: { MSCP_MKDRIVE2('R', 'A', 60), "ra60", ra60_sizes, 42, 4, 2382 }, ! 2208: { MSCP_MKDRIVE2('R', 'A', 70), "ra70", ra70_sizes, 33, 11, 1507 }, ! 2209: { MSCP_MKDRIVE2('R', 'A', 80), "ra80", ra80_sizes, 31, 14, 559 }, ! 2210: { MSCP_MKDRIVE2('R', 'A', 81), "ra81", ra81_sizes, 51, 14, 1248 }, ! 2211: { MSCP_MKDRIVE2('R', 'A', 82), "ra82", ra82_sizes, 57, 14, 1423 }, ! 2212: { MSCP_MKDRIVE2('R', 'C', 25), "rc25-removable", ! 2213: rc25_sizes, 42, 4, 302 }, ! 2214: { MSCP_MKDRIVE3('R', 'C', 'F', 25), "rc25-fixed", ! 2215: rc25_sizes, 42, 4, 302 }, ! 2216: { MSCP_MKDRIVE2('R', 'D', 52), "rd52", rd52_sizes, 18, 7, 480 }, ! 2217: { MSCP_MKDRIVE2('R', 'D', 53), "rd53", rd53_sizes, 18, 8, 963 }, ! 2218: { MSCP_MKDRIVE2('R', 'D', 32), "rd54-from-rd32", ! 2219: rd54_sizes, 17, 15, 1220 }, ! 2220: { MSCP_MKDRIVE2('R', 'D', 54), "rd54", rd54_sizes, 17, 15, 1220 }, ! 2221: { MSCP_MKDRIVE2('R', 'X', 50), "rx50", rx50_sizes, 10, 1, 80 }, ! 2222: 0 ! 2223: }; ! 2224: ! 2225: #define NTYPES (sizeof(udatypes) / sizeof(*udatypes)) ! 2226: ! 2227: udamaptype(unit, lp) ! 2228: int unit; ! 2229: register struct disklabel *lp; ! 2230: { ! 2231: register struct udatypes *ut; ! 2232: register struct size *sz; ! 2233: register struct partition *pp; ! 2234: register char *p; ! 2235: register int i; ! 2236: register struct ra_info *ra = &ra_info[unit]; ! 2237: ! 2238: i = MSCP_MEDIA_DRIVE(ra->ra_mediaid); ! 2239: for (ut = udatypes; ut->ut_id; ut++) ! 2240: if (ut->ut_id == i && ! 2241: ut->ut_nsectors == ra->ra_geom.rg_nsectors && ! 2242: ut->ut_ntracks == ra->ra_geom.rg_ntracks && ! 2243: ut->ut_ncylinders == ra->ra_geom.rg_ncyl) ! 2244: goto found; ! 2245: ! 2246: /* not one we know; fake up a label for the whole drive */ ! 2247: uda_makefakelabel(ra, lp); ! 2248: i = ra->ra_mediaid; /* print the port type too */ ! 2249: addlog(": no partition table for %c%c %c%c%c%d, size %d;\n\ ! 2250: using (s,t,c)=(%d,%d,%d)", ! 2251: MSCP_MID_CHAR(4, i), MSCP_MID_CHAR(3, i), ! 2252: MSCP_MID_CHAR(2, i), MSCP_MID_CHAR(1, i), ! 2253: MSCP_MID_CHAR(0, i), MSCP_MID_NUM(i), lp->d_secperunit, ! 2254: lp->d_nsectors, lp->d_ntracks, lp->d_ncylinders); ! 2255: if (!cold) ! 2256: addlog("\n"); ! 2257: return (0); ! 2258: found: ! 2259: p = ut->ut_name; ! 2260: for (i = 0; i < sizeof(lp->d_typename) - 1 && *p; i++) ! 2261: lp->d_typename[i] = *p++; ! 2262: lp->d_typename[i] = 0; ! 2263: sz = ut->ut_sizes; ! 2264: lp->d_nsectors = ut->ut_nsectors; ! 2265: lp->d_ntracks = ut->ut_ntracks; ! 2266: lp->d_ncylinders = ut->ut_ncylinders; ! 2267: lp->d_npartitions = 8; ! 2268: lp->d_secpercyl = lp->d_nsectors * lp->d_ntracks; ! 2269: for (pp = lp->d_partitions; pp < &lp->d_partitions[8]; pp++, sz++) { ! 2270: pp->p_offset = sz->blkoff; ! 2271: if ((pp->p_size = sz->nblocks) == (u_long)-1) ! 2272: pp->p_size = ra->ra_dsize - sz->blkoff; ! 2273: } ! 2274: return (1); ! 2275: } ! 2276: #endif /* COMPAT_42 */ ! 2277: ! 2278: /* ! 2279: * Construct a label for a drive from geometry information ! 2280: * if we have no better information. ! 2281: */ ! 2282: uda_makefakelabel(ra, lp) ! 2283: register struct ra_info *ra; ! 2284: register struct disklabel *lp; ! 2285: { ! 2286: lp->d_nsectors = ra->ra_geom.rg_nsectors; ! 2287: lp->d_ntracks = ra->ra_geom.rg_ntracks; ! 2288: lp->d_ncylinders = ra->ra_geom.rg_ncyl; ! 2289: lp->d_secpercyl = lp->d_nsectors * lp->d_ntracks; ! 2290: bcopy("ra??", lp->d_typename, sizeof("ra??")); ! 2291: lp->d_npartitions = 1; ! 2292: lp->d_partitions[0].p_offset = 0; ! 2293: lp->d_partitions[0].p_size = lp->d_secperunit; ! 2294: } ! 2295: #endif /* NUDA > 0 */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.