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