1: /* 2: * Copyright (c) 1986 Regents of the University of California. 3: * All rights reserved. The Berkeley software License Agreement 4: * specifies the terms and conditions for redistribution. 5: * 6: * @(#)ra.c 3.4 (2.11BSD GTE) 1998/4/3 7: */ 8: 9: /*********************************************************************** 10: * Copyright (c) 1983 by * 11: * Digital Equipment Corporation, Maynard, MA * 12: * All rights reserved. * 13: ***********************************************************************/ 14: 15: /* 16: * ra.c - MSCP Driver 17: * Date: April 3, 1998 18: * Implement a sysctl interface for manipulating datagram/error logging (as was 19: * done for the TMSCP driver earlier). Finish changing printf() statements to 20: * log() statements. Clean the drive up by removing obsolete debugging state- 21: * ments. 22: * 23: * Date: January 28, 1998 24: * Define the 'mscp_header' structure in the mscp_common.h and change the 25: * member names from ra_* to mscp_*. A small step towards merging the MSCP 26: * and TMSCP drivers. 27: * 28: * Date: February 14, 1997 29: * Use 'hz' to calculate delays rather than compile time constant. 30: * 31: * Date: October 28, 1995 32: * Fix multicontroller support (which was badly broken when disklabels were 33: * added). Accessing drives on the second controller would cause serious 34: * filesystem corruption on the the corresponding drives on the first 35: * controller. 36: * 37: * Date: August 1, 1995 38: * Fix a bug which prohibited labeling previously disks which were unlabeled 39: * or had a corrupted label. The default ('a' partition spanning the volume) 40: * must be left in place to allow the write of the label. 41: * 42: * Date: July 3, 1995 43: * Fix a couple bugs and simplify the close protocol. 44: * 45: * Date: June 16, 1995 46: * Use the common label ioctl routine created today. 47: * 48: * Date: June 15, 1995 49: * Disklabels work! A few minor changes made - raopen() needed to always 50: * validate the partition number not just when the drive was first brought 51: * online. 52: * 53: * Date: May 20, 1995 54: * Minor changes before beginning testing. 55: * 56: * Date: May 03, 1995 57: * Resume adding disklabel support. The past several weeks were spent 58: * porting/rewriting 'newfs', 'disklabel', 'getdiskbyname' and so on. 59: * 60: * Date: Apr 13, 1995 61: * Begin implementing disklabels. First job was to remove/change references 62: * to dkunit() since that macro has moved from buf.h to disk.h and takes a 63: * 'dev_t' now instead of 'buf *'. 64: * 65: * Date: Jan 11, 1995 66: * Remove extra parameter to ra_error() call in radump(). 67: * 68: * Date: Dec 1992, Jan 1993 69: * Add the partition size routine. Remove unibus map ifdefs, the run time 70: * check for 'ubmap' is sufficient and does the right thing. 71: * 72: * Date: Nov 1992 73: * Add raVec() routine. This is called by autoconfig to set the vector 74: * (from /etc/dtab) for controllers other than the root (1st). The boot/root 75: * controller's vector is always set to 0154. 76: * 77: * Date: Jul 1992 78: * Major rework of the partition tables. Some old (RA60,80,81,RD53) tables 79: * were retained (the rd54 'c' partition is now 'g' but the sizes stay 80: * the same) for compatibility. RC25, RD51, RA82 entries were removed (unlikely 81: * that the RA82 was used since the disktab entry was wrong). A _brand new_ 82: * scheme utilizing 5 "generic" partition tables was created based on the 83: * size of the disc. This was needed due to the rapid proliferation of 84: * MSCP drive types, it was simply not feasible to have a 64 byte partition 85: * table for each of the (currently 28 to 30) types of MSCP discs. 86: * 87: * More attention is paid to bits in the media id beyond the 7 bit 88: * numeric id. These bits can be used to distinquish between a RZ24 and a 89: * RZ24L for example. 90: * 91: * Some of the diagnostic output was trimmed in an attempt to offset the 92: * growth of an already large drive. 93: * 94: * Date: Dec 18 1991 95: * The controller number (bits 6 and 7 of the minor device) were not 96: * being masked off after using dkunit(). This caused a crash when 97: * the controller number was other than 0. 98: * 99: * Date: Sep 22 1991 100: * The read and write entries were removed as part of implementing the 101: * common rawread and rawwrite routines. 102: * 103: * Date: Mar 16 1991 104: * The command packets were moved to an external heap which is dynamically 105: * allocated in a manner similar to m_ioget in the networking code. 106: * MSCP controllers used too much valuable kernel D space. For UNIBUS 107: * machines sufficient UMRs were allocated to map the heap, removing the 108: * need to allocate a UMR per controller at open time. This has the side 109: * effect of greatly simplifying the physical (Q22) or virtual (UMR) address 110: * calculation of the command packets. It also eliminates the need for 111: * 'struct buf racomphys', saving 24 bytes of D space. 112: * 113: * The error message output was rearranged saving another 82 bytes of 114: * kernel D space. Also, there was an extraneous buffer header allocated, 115: * it was removed, saving a further 24 bytes of D space. 116: * sms@wlv.iipo.gtegsc.com (was wlv.imsd.contel.com at the time). 117: * 118: * Date: Jan 30 1984 119: * This thing has been beaten beyound belief. 120: * decvax!rich. 121: */ 122: 123: /* 124: * MSCP disk device driver 125: * Tim Tucker, Gould Electronics, Sep 1985 126: * Note: This driver is based on the UDA50 4.3 BSD source. 127: */ 128: 129: #include "ra.h" 130: #if NRAD > 0 && NRAC > 0 131: #include "param.h" 132: #include "../machine/seg.h" 133: #include "../machine/mscp.h" 134: 135: #include "systm.h" 136: #include "buf.h" 137: #include "conf.h" 138: #include "map.h" 139: #include "syslog.h" 140: #include "ioctl.h" 141: #include "uba.h" 142: #include "rareg.h" 143: #include "dk.h" 144: #include "disklabel.h" 145: #include "disk.h" 146: #include "errno.h" 147: #include "file.h" 148: #include "stat.h" 149: #include <sys/kernel.h> 150: 151: #define RACON(x) ((minor(x) >> 6) & 03) 152: #define RAUNIT(x) (dkunit(x) & 07) 153: 154: #define NRSPL2 3 /* log2 number of response packets */ 155: #define NCMDL2 3 /* log2 number of command packets */ 156: #define NRSP (1<<NRSPL2) 157: #define NCMD (1<<NCMDL2) 158: 159: typedef struct { /* Swap shorts for MSCP controller! */ 160: short lsh; 161: short hsh; 162: } Trl; 163: 164: /* 165: * RA Communications Area 166: */ 167: struct raca { 168: short ca_xxx1; /* unused */ 169: char ca_xxx2; /* unused */ 170: char ca_bdp; /* BDP to purge */ 171: short ca_cmdint; /* command queue transition interrupt flag */ 172: short ca_rspint; /* response queue transition interrupt flag */ 173: Trl ca_rsp[NRSP]; /* response descriptors */ 174: Trl ca_cmd[NCMD]; /* command descriptors */ 175: }; 176: 177: #define RINGBASE (4 * sizeof(short)) 178: 179: #define RA_OWN 0x8000 /* Controller owns this descriptor */ 180: #define RA_INT 0x4000 /* allow interrupt on ring transition */ 181: 182: typedef struct { 183: struct raca ra_ca; /* communications area */ 184: struct mscp ra_rsp[NRSP]; /* response packets */ 185: struct mscp ra_cmd[NCMD]; /* command packets */ 186: } ra_comT; /* 1096 bytes per controller */ 187: 188: typedef struct ra_info { 189: struct dkdevice ra_dk; /* General disk info structure */ 190: daddr_t ra_nblks; /* Volume size from online pkt */ 191: short ra_unit; /* controller unit # */ 192: struct buf ra_utab; /* buffer header for drive */ 193: } ra_infoT; 194: 195: #define ra_bopen ra_dk.dk_bopenmask 196: #define ra_copen ra_dk.dk_copenmask 197: #define ra_open ra_dk.dk_openmask 198: #define ra_flags ra_dk.dk_flags 199: #define ra_label ra_dk.dk_label 200: #define ra_parts ra_dk.dk_parts 201: 202: typedef struct { 203: radeviceT *RAADDR; /* Controller bus address */ 204: short sc_unit; /* attach controller # */ 205: short sc_state; /* state of controller */ 206: short sc_ivec; /* interrupt vector address */ 207: short sc_credits; /* transfer credits */ 208: short sc_lastcmd; /* pointer into command ring */ 209: short sc_lastrsp; /* pointer into response ring */ 210: struct buf sc_ctab; /* Controller queue */ 211: struct buf sc_wtab; /* I/O wait queue, for controller */ 212: short sc_cp_wait; /* Command packet wait flag */ 213: ra_comT *sc_com; /* Communications area pointer */ 214: ra_infoT *sc_drives[8]; /* Disk drive info blocks */ 215: } ra_softcT; 216: 217: ra_softcT ra_sc[NRAC]; /* Controller table */ 218: memaddr ra_com[NRAC]; /* Communications area table */ 219: ra_infoT ra_disks[NRAD]; /* Disk table */ 220: 221: #define MAPSEGDESC (((btoc(sizeof (ra_comT))-1)<<8)|RW) 222: 223: #ifdef UCB_METER 224: static int ra_dkn = -1; /* number for iostat */ 225: #endif 226: 227: /* 228: * Controller states 229: */ 230: #define S_IDLE 0 /* hasn't been initialized */ 231: #define S_STEP1 1 /* doing step 1 init */ 232: #define S_STEP2 2 /* doing step 2 init */ 233: #define S_STEP3 3 /* doing step 3 init */ 234: #define S_SCHAR 4 /* doing "set controller characteristics" */ 235: #define S_RUN 5 /* running */ 236: 237: int rastrategy(); 238: daddr_t rasize(); 239: /* 240: * Bit 0 = print/log all non successful response packets 241: * Bit 1 = print/log datagram arrival 242: * Bit 2 = print status of all response packets _except_ for datagrams 243: * Bit 3 = enable debug/log statements not covered by one of the above 244: */ 245: int mscpprintf = 0x1; 246: 247: extern int wakeup(); 248: extern ubadr_t _iomap(); 249: extern size_t physmem; /* used by the crash dump routine */ 250: void ragetinfo(), radfltlbl(); 251: struct mscp *ragetcp(); 252: 253: #define b_qsize b_resid /* queue size per drive, in rqdtab */ 254: 255: /* 256: * Setup root MSCP device (use bootcsr passed from ROMs). In the event 257: * the system was not booted from a MSCP drive but swapdev is a MSCP drive 258: * we fake the old behaviour of attaching the first (172150) controller. If 259: * the system was booted from a MSCP drive then this routine has already been 260: * called with the CSR of the booting controller and the attach routine will 261: * ignore further calls to attach controller 0. 262: * 263: * This whole thing is a hack and should go away somehow. 264: */ 265: raroot(csr) 266: register radeviceT *csr; 267: { 268: if (!csr) /* XXX */ 269: csr = (radeviceT *) 0172150; /* XXX */ 270: raattach(csr, 0); 271: raVec(0, 0154); 272: } 273: 274: /* 275: * Called from autoconfig and raroot() to set the vector for a controller. 276: * It is an error to attempt to set the vector more than once except for 277: * the first controller which may have had the vector set from raroot(). 278: * In this case the error is ignored and the vector left unchanged. 279: */ 280: 281: raVec(ctlr, vector) 282: register int ctlr; 283: int vector; 284: { 285: register ra_softcT *sc = &ra_sc[ctlr]; 286: 287: if (ctlr >= NRAC) 288: return(-1); 289: if (sc->sc_ivec == 0) 290: sc->sc_ivec = vector; 291: else if (ctlr) 292: return(-1); 293: return(0); 294: } 295: 296: /* 297: * Attach controller for autoconfig system. 298: */ 299: raattach(addr, unit) 300: register radeviceT *addr; 301: register int unit; 302: { 303: register ra_softcT *sc = &ra_sc[unit]; 304: 305: #ifdef UCB_METER 306: if (ra_dkn < 0) 307: dk_alloc(&ra_dkn, NRAD, "ra", 60L * 31L * 256L); 308: #endif 309: 310: /* Check for bad address (no such controller) */ 311: if (sc->RAADDR == NULL && addr != NULL) { 312: sc->RAADDR = addr; 313: sc->sc_unit = unit; 314: sc->sc_com = (ra_comT *)SEG5; 315: ra_com[unit] = (memaddr)_ioget(sizeof (ra_comT)); 316: return(1); 317: } 318: 319: /* 320: * Binit and autoconfig both attempt to attach unit zero if ra is 321: * rootdev 322: */ 323: return(unit ? 0 : 1); 324: } 325: 326: /* 327: * Return a pointer to a free disk table entry 328: */ 329: ra_infoT * 330: ragetdd() 331: { 332: register int i; 333: register ra_infoT *p; 334: 335: for (i = NRAD, p = ra_disks; i--; p++) 336: if ((p->ra_flags & DKF_ALIVE) == 0) 337: { 338: p->ra_flags = DKF_ALIVE; 339: return(p); 340: } 341: return(NULL); 342: } 343: 344: /* 345: * Open a RA. Initialize the device and set the unit online. 346: */ 347: raopen(dev, flag, mode) 348: dev_t dev; 349: int flag; 350: int mode; 351: { 352: register ra_infoT *disk; 353: register struct mscp *mp; 354: register ra_softcT *sc = &ra_sc[RACON(dev)]; 355: int unit = RAUNIT(dev); 356: int ctlr = RACON(dev); 357: int mask; 358: int s, i; 359: 360: /* Check that controller exists */ 361: if (ctlr >= NRAC || sc->RAADDR == NULL) 362: return(ENXIO); 363: 364: /* Open device */ 365: if (sc->sc_state != S_RUN) { 366: s = splbio(); 367: 368: /* initialize controller if idle */ 369: if (sc->sc_state == S_IDLE) { 370: if (rainit(sc)) { 371: splx(s); 372: return(ENXIO); 373: } 374: } 375: 376: /* wait for initialization to complete */ 377: timeout(wakeup, (caddr_t)&sc->sc_ctab, 12 * hz); 378: sleep((caddr_t)&sc->sc_ctab, PSWP+1); 379: if (sc->sc_state != S_RUN) { 380: splx(s); 381: return(EIO); 382: } 383: splx(s); 384: } 385: 386: /* 387: * Check to see if the device is really there. This code was 388: * taken from Fred Canters 11 driver. 389: */ 390: disk = sc->sc_drives[unit]; 391: if (disk == NULL) { 392: s = splbio(); 393: /* Allocate disk table entry for disk */ 394: if ((disk = ragetdd()) != NULL) { 395: sc->sc_drives[unit] = disk; 396: disk->ra_unit = ctlr; /* controller number */ 397: } else { 398: if (mscpprintf & 0x8) 399: log(LOG_NOTICE, "ra: !disk struc\n"); 400: splx(s); 401: return(ENXIO); 402: } 403: } 404: /* Try to online disk unit, it might have gone offline */ 405: if ((disk->ra_flags & DKF_ONLINE) == 0) { 406: /* In high kernel, don't saveseg5, just use normalseg5 later on. */ 407: while ((mp = ragetcp(sc)) == 0) { 408: ++sc->sc_cp_wait; 409: sleep(&sc->sc_cp_wait, PSWP+1); 410: --sc->sc_cp_wait; 411: } 412: mapseg5(ra_com[sc->sc_unit], MAPSEGDESC); 413: mp->m_opcode = M_OP_ONLIN; 414: mp->m_unit = unit; 415: mp->m_cmdref = (unsigned)&disk->ra_flags; 416: ((Trl *)mp->m_dscptr)->hsh |= RA_OWN|RA_INT; 417: normalseg5(); 418: i = sc->RAADDR->raip; 419: timeout(wakeup, (caddr_t)&disk->ra_flags, 10 * hz); 420: sleep((caddr_t)&disk->ra_flags, PSWP+1); 421: splx(s); 422: } 423: 424: /* Did it go online? */ 425: if ((disk->ra_flags & DKF_ONLINE) == 0) { 426: s = splbio(); 427: disk->ra_flags = 0; 428: sc->sc_drives[unit] = NULL; 429: splx(s); 430: return(EIO); 431: } 432: /* 433: * Now we read the label. Allocate an external label structure if one has 434: * not already been assigned to this drive. First wait for any pending 435: * opens/closes to complete. 436: */ 437: 438: while (disk->ra_flags & (DKF_OPENING | DKF_CLOSING)) 439: sleep(disk, PRIBIO); 440: 441: /* 442: * Next if an external label buffer has not already been allocated do so 443: * now. This "can not fail" because if the initial pool of label buffers 444: * has been exhausted the allocation takes place from main memory. The 445: * return value is the 'click' address to be used when mapping in the label. 446: */ 447: 448: if (disk->ra_label == 0) 449: disk->ra_label = disklabelalloc(); 450: 451: /* 452: * On first open get label and partition info. We may block reading the 453: * label so be careful to stop any other opens. 454: */ 455: if (disk->ra_open == 0) 456: { 457: disk->ra_flags |= DKF_OPENING; 458: ragetinfo(disk, dev); 459: disk->ra_flags &= ~DKF_OPENING; 460: wakeup(disk); 461: } 462: /* 463: * Need to make sure the partition is not out of bounds. This requires 464: * mapping in the external label. This only happens when a partition 465: * is opened (at mount time) and isn't an efficiency problem. 466: */ 467: mapseg5(disk->ra_label, LABELDESC); 468: i = ((struct disklabel *)SEG5)->d_npartitions; 469: normalseg5(); 470: if (dkpart(dev) >= i) 471: return(ENXIO); 472: 473: mask = 1 << dkpart(dev); 474: dkoverlapchk(disk->ra_open, dev, disk->ra_label, "ra"); 475: if (mode == S_IFCHR) 476: disk->ra_copen |= mask; 477: else if (mode == S_IFBLK) 478: disk->ra_bopen |= mask; 479: else 480: return(EINVAL); 481: disk->ra_open |= mask; 482: return(0); 483: } 484: 485: /* 486: * Disk drivers now have to have close entry points in order to keep 487: * track of what partitions are still active on a drive. 488: */ 489: raclose(dev, flag, mode) 490: register dev_t dev; 491: int flag, mode; 492: { 493: int s, unit = RAUNIT(dev); 494: register int mask; 495: register ra_infoT *disk; 496: ra_softcT *sc = &ra_sc[RACON(dev)]; 497: 498: disk = sc->sc_drives[unit]; 499: mask = 1 << dkpart(dev); 500: if (mode == S_IFCHR) 501: disk->ra_copen &= ~mask; 502: else if (mode == S_IFBLK) 503: disk->ra_bopen &= ~mask; 504: else 505: return(EINVAL); 506: disk->ra_open = disk->ra_bopen | disk->ra_copen; 507: if (disk->ra_open == 0) 508: { 509: disk->ra_flags |= DKF_CLOSING; 510: s = splbio(); 511: while (disk->ra_utab.b_actf) 512: sleep(&disk->ra_utab, PRIBIO); 513: splx(s); 514: disk->ra_flags &= ~DKF_CLOSING; 515: wakeup(disk); 516: } 517: return(0); 518: } 519: 520: /* 521: * This code was moved from ragetinfo() because it is fairly large and used 522: * twice - once to initialize for reading the label and a second time if 523: * there is no valid label present on the drive and the default one must be 524: * used. 525: */ 526: 527: void 528: radfltlbl(disk, lp) 529: ra_infoT *disk; 530: register struct disklabel *lp; 531: { 532: register struct partition *pi = &lp->d_partitions[0]; 533: 534: bzero(lp, sizeof (*lp)); 535: lp->d_type = DTYPE_MSCP; 536: lp->d_secsize = 512; /* XXX */ 537: lp->d_nsectors = 32; 538: lp->d_ntracks = 1; 539: lp->d_secpercyl = 20 * 32; 540: lp->d_npartitions = 1; /* 'a' */ 541: pi->p_size = disk->ra_nblks; /* entire volume */ 542: pi->p_fstype = FS_V71K; 543: pi->p_frag = 1; 544: pi->p_fsize = 1024; 545: /* 546: * Put where rastrategy() will look. 547: */ 548: bcopy(pi, disk->ra_parts, sizeof (lp->d_partitions)); 549: } 550: 551: /* 552: * Read disklabel. It is tempting to generalize this routine so that 553: * all disk drivers could share it. However by the time all of the 554: * necessary parameters are setup and passed the savings vanish. Also, 555: * each driver has a different method of calculating the number of blocks 556: * to use if one large partition must cover the disk. 557: * 558: * This routine used to always return success and callers carefully checked 559: * the return status. Silly. This routine will fake a label (a single 560: * partition spanning the drive) if necessary but will never return an error. 561: * 562: * It is the caller's responsibility to check the validity of partition 563: * numbers, etc. 564: */ 565: 566: void 567: ragetinfo(disk, dev) 568: register ra_infoT *disk; 569: dev_t dev; 570: { 571: struct disklabel locallabel; 572: char *msg; 573: register struct disklabel *lp = &locallabel; 574: /* 575: * NOTE: partition 0 ('a') is used to read the label. Therefore 'a' must 576: * start at the beginning of the disk! If there is no label or the label 577: * is corrupted then 'a' will span the entire disk 578: */ 579: 580: radfltlbl(disk, lp); /* set up default/fake label */ 581: msg = readdisklabel((dev & ~7) | 0, rastrategy, lp); /* 'a' */ 582: if (msg != 0) 583: { 584: if (mscpprintf & 0x8) 585: log(LOG_NOTICE, "ra%da=entire disk: %s\n", 586: dkunit(dev), msg); 587: radfltlbl(disk, lp); 588: } 589: mapseg5(disk->ra_label, LABELDESC); 590: bcopy(lp, (struct disklabel *)SEG5, sizeof (struct disklabel)); 591: normalseg5(); 592: bcopy(lp->d_partitions, disk->ra_parts, sizeof (lp->d_partitions)); 593: return; 594: } 595: 596: /* 597: * Initialize controller, data structures, and start hardware 598: * initialization sequence. 599: */ 600: rainit(sc) 601: register ra_softcT *sc; 602: { 603: long adr; 604: 605: /* 606: * Cold init of controller 607: */ 608: ++sc->sc_ctab.b_active; 609: 610: /* 611: * Get physical address of RINGBASE 612: */ 613: 614: adr = _iomap(ra_com[sc->sc_unit]) + RINGBASE; 615: 616: /* 617: * Get individual controller RINGBASE physical address 618: */ 619: sc->sc_ctab.b_un.b_addr = (caddr_t)loint(adr); 620: sc->sc_ctab.b_xmem = hiint(adr); 621: 622: /* 623: * Start the hardware initialization sequence. 624: */ 625: sc->RAADDR->raip = 0; 626: while ((sc->RAADDR->rasa & RA_STEP1) == 0) 627: if (sc->RAADDR->rasa & RA_ERR) 628: return(1); 629: sc->RAADDR->rasa = RA_ERR | (NCMDL2 << 11) | (NRSPL2 << 8) | RA_IE 630: | (sc->sc_ivec / 4); 631: 632: /* 633: * Initialization continues in interrupt routine. 634: */ 635: sc->sc_state = S_STEP1; 636: sc->sc_credits = 0; 637: return(0); 638: } 639: 640: rastrategy(bp) 641: register struct buf *bp; 642: { 643: ra_infoT *disk; 644: register struct buf *dp; 645: register ra_softcT *sc = &ra_sc[RACON(bp->b_dev)]; 646: int s; 647: 648: /* Is disk online */ 649: if ((disk = sc->sc_drives[RAUNIT(bp->b_dev)]) == NULL || 650: !(disk->ra_flags & (DKF_ONLINE | DKF_ALIVE))) 651: goto bad; 652: s = partition_check(bp, &disk->ra_dk); 653: if (s < 0) 654: goto bad; 655: if (s == 0) 656: goto done; 657: mapalloc(bp); /* Unibus Map buffer if required */ 658: 659: /* 660: * Link the buffer onto the drive queue 661: */ 662: s = splbio(); 663: dp = &disk->ra_utab; 664: if (dp->b_actf == 0) 665: dp->b_actf = bp; 666: else 667: dp->b_actl->av_forw = bp; 668: dp->b_actl = bp; 669: bp->av_forw = 0; 670: 671: /* 672: * Link the drive onto the controller queue 673: */ 674: if (dp->b_active == 0) { 675: dp->b_forw = NULL; 676: if (sc->sc_ctab.b_actf == NULL) 677: sc->sc_ctab.b_actf = dp; 678: else 679: sc->sc_ctab.b_actl->b_forw = dp; 680: sc->sc_ctab.b_actl = dp; 681: dp->b_active = 1; 682: } 683: 684: /* 685: * Start controller if idle. 686: */ 687: if (sc->sc_ctab.b_active == 0) 688: rastart(sc); 689: splx(s); 690: return; 691: bad: 692: bp->b_flags |= B_ERROR; 693: done: 694: iodone(bp); 695: return; 696: } 697: 698: /* Start i/o, must be called at level splbio */ 699: rastart(sc) 700: register ra_softcT *sc; 701: { 702: register struct mscp *mp; 703: register struct buf *bp; 704: struct buf *dp; 705: struct partition *pi; 706: ra_infoT *disk; 707: int i; 708: long temp; 709: segm seg5; 710: 711: saveseg5(seg5); /* save it just once */ 712: loop: 713: /* 714: * Anything left to do on this controller? 715: */ 716: if ((dp = sc->sc_ctab.b_actf) == NULL) { 717: sc->sc_ctab.b_active = 0; 718: 719: /* 720: * Check for response ring transitions lost in race 721: * condition 722: */ 723: mapseg5(ra_com[sc->sc_unit], MAPSEGDESC); 724: rarspring(sc); 725: restorseg5(seg5); 726: return(0); 727: } 728: 729: /* Get first request waiting on queue */ 730: if ((bp = dp->b_actf) == NULL) { 731: /* 732: * No more requests for this drive, remove 733: * from controller queue and look at next drive. 734: * We know we're at the head of the controller queue. 735: * The drive may not need anything, in which case it might 736: * be shutting down in raclose() and a wakeup is needed. 737: */ 738: dp->b_active = 0; 739: sc->sc_ctab.b_actf = dp->b_forw; 740: i = offsetof(ra_infoT, ra_utab); 741: disk = (ra_infoT *)((int)dp - i); 742: if (disk->ra_open == 0) 743: wakeup(dp); /* finish close protocol */ 744: goto loop; 745: } 746: 747: ++sc->sc_ctab.b_active; 748: if (sc->RAADDR->rasa & RA_ERR || sc->sc_state != S_RUN) { 749: harderr(bp, "ra"); 750: /* Should requeue outstanding requests somehow */ 751: rainit(sc); 752: out: 753: restorseg5(seg5); 754: return(0); 755: } 756: 757: /* Issue command */ 758: mapseg5(ra_com[sc->sc_unit], MAPSEGDESC); 759: if ((mp = ragetcp(sc)) == NULL) 760: goto out; 761: mp->m_cmdref = (unsigned)bp; /* pointer to get back */ 762: mp->m_opcode = bp->b_flags & B_READ ? M_OP_READ : M_OP_WRITE; 763: mp->m_unit = RAUNIT(bp->b_dev); 764: disk = sc->sc_drives[mp->m_unit]; 765: pi = &disk->ra_parts[dkpart(bp->b_dev)]; 766: temp = bp->b_blkno + pi->p_offset; 767: mp->m_lbn_l = loint(temp); 768: mp->m_lbn_h = hiint(temp); 769: mp->m_bytecnt = bp->b_bcount; 770: mp->m_buf_l = (u_short)bp->b_un.b_addr; 771: mp->m_buf_h = bp->b_xmem; 772: ((Trl *)mp->m_dscptr)->hsh |= RA_OWN|RA_INT; 773: i = sc->RAADDR->raip; /* initiate polling */ 774: 775: #ifdef UCB_METER 776: if (ra_dkn >= 0) { 777: int dkn = ra_dkn + mp->m_unit; 778: 779: /* Messy, should do something better than this. Ideas? */ 780: ++dp->b_qsize; 781: dk_busy |= 1<<dkn; 782: dk_xfer[dkn]++; 783: dk_wds[dkn] += bp->b_bcount>>6; 784: } 785: #endif 786: 787: /* 788: * Move drive to the end of the controller queue 789: */ 790: if (dp->b_forw != NULL) { 791: sc->sc_ctab.b_actf = dp->b_forw; 792: sc->sc_ctab.b_actl->b_forw = dp; 793: sc->sc_ctab.b_actl = dp; 794: dp->b_forw = NULL; 795: } 796: 797: /* 798: * Move buffer to I/O wait queue 799: */ 800: dp->b_actf = bp->av_forw; 801: dp = &sc->sc_wtab; 802: bp->av_forw = dp; 803: bp->av_back = dp->av_back; 804: dp->av_back->av_forw = bp; 805: dp->av_back = bp; 806: goto loop; 807: } 808: 809: /* 810: * RA interrupt routine. 811: */ 812: raintr(unit) 813: int unit; 814: { 815: register ra_softcT *sc = &ra_sc[unit]; 816: register struct mscp *mp; 817: register struct buf *bp; 818: u_int i; 819: segm seg5; 820: 821: saveseg5(seg5); /* save it just once */ 822: 823: switch (sc->sc_state) { 824: case S_STEP1: 825: #define STEP1MASK 0174377 826: #define STEP1GOOD (RA_STEP2|RA_IE|(NCMDL2<<3)|NRSPL2) 827: if (radostep(sc, STEP1MASK, STEP1GOOD)) 828: return; 829: sc->RAADDR->rasa = (short)sc->sc_ctab.b_un.b_addr; 830: sc->sc_state = S_STEP2; 831: return; 832: case S_STEP2: 833: #define STEP2MASK 0174377 834: #define STEP2GOOD (RA_STEP3|RA_IE|(sc->sc_ivec/4)) 835: if (radostep(sc, STEP2MASK, STEP2GOOD)) 836: return; 837: sc->RAADDR->rasa = sc->sc_ctab.b_xmem; 838: sc->sc_state = S_STEP3; 839: return; 840: case S_STEP3: 841: #define STEP3MASK 0174000 842: #define STEP3GOOD RA_STEP4 843: if (radostep(sc, STEP3MASK, STEP3GOOD)) 844: return; 845: i = sc->RAADDR->rasa; 846: log(LOG_NOTICE, "ra%d: Ver %d mod %d\n", sc->sc_unit, 847: i & 0xf, (i >> 4) & 0xf); 848: sc->RAADDR->rasa = RA_GO; 849: sc->sc_state = S_SCHAR; 850: 851: /* 852: * Initialize the data structures. 853: */ 854: mapseg5(ra_com[sc->sc_unit], MAPSEGDESC); 855: ramsginit(sc, sc->sc_com->ra_ca.ca_rsp, sc->sc_com->ra_rsp, 856: 0, NRSP, RA_INT | RA_OWN); 857: ramsginit(sc, sc->sc_com->ra_ca.ca_cmd, sc->sc_com->ra_cmd, 858: NRSP, NCMD, RA_INT); 859: bp = &sc->sc_wtab; 860: bp->av_forw = bp->av_back = bp; 861: sc->sc_lastcmd = 1; 862: sc->sc_lastrsp = 0; 863: mp = sc->sc_com->ra_cmd; 864: ramsgclear(mp); 865: mp->m_opcode = M_OP_STCON; 866: mp->m_cntflgs = M_CF_ATTN | M_CF_MISC | M_CF_THIS; 867: ((Trl *)mp->m_dscptr)->hsh |= RA_OWN|RA_INT; 868: i = sc->RAADDR->raip; 869: restorseg5(seg5); 870: return; 871: case S_SCHAR: 872: case S_RUN: 873: break; 874: default: 875: log(LOG_NOTICE, "ra: st %d\n", sc->sc_state); 876: return; 877: } 878: 879: /* 880: * If this happens we are in BIG trouble! 881: */ 882: if (radostep(sc, RA_ERR, 0)) 883: log(LOG_ERR, "ra: err %o\n", sc->RAADDR->rasa); 884: 885: mapseg5(ra_com[sc->sc_unit], MAPSEGDESC); 886: 887: /* 888: * Check for buffer purge request 889: */ 890: if (sc->sc_com->ra_ca.ca_bdp) { 891: sc->sc_com->ra_ca.ca_bdp = 0; 892: sc->RAADDR->rasa = 0; 893: } 894: 895: /* 896: * Check for response ring transition. 897: */ 898: if (sc->sc_com->ra_ca.ca_rspint) 899: rarspring(sc); 900: 901: /* 902: * Check for command ring transition (Should never happen!) 903: */ 904: if (sc->sc_com->ra_ca.ca_cmdint) 905: sc->sc_com->ra_ca.ca_cmdint = 0; 906: 907: restorseg5(seg5); 908: 909: /* Waiting for command? */ 910: if (sc->sc_cp_wait) 911: wakeup((caddr_t)&sc->sc_cp_wait); 912: rastart(sc); 913: } 914: 915: radostep(sc, mask, good) 916: register ra_softcT *sc; 917: int mask, good; 918: { 919: 920: if ((sc->RAADDR->rasa & mask) != good) 921: { 922: sc->sc_state = S_IDLE; 923: sc->sc_ctab.b_active = 0; 924: wakeup((caddr_t)&sc->sc_ctab); 925: return(1); 926: } 927: return(0); 928: } 929: 930: /* 931: * Init mscp communications area 932: */ 933: ramsginit(sc, com, msgs, offset, length, flags) 934: register ra_softcT *sc; 935: register Trl *com; 936: register struct mscp *msgs; 937: int offset, length, flags; 938: { 939: long vaddr; 940: 941: /* 942: * Figure out Unibus or physical(Q22) address of message 943: * skip comm area and mscp messages header and previous messages 944: */ 945: vaddr = _iomap(ra_com[sc->sc_unit]); /* base adr in heap */ 946: vaddr += sizeof(struct raca) /* skip comm area */ 947: +sizeof(struct mscp_header); /* m_cmdref disp */ 948: vaddr += offset * sizeof(struct mscp); /* skip previous */ 949: while (length--) { 950: com->lsh = loint(vaddr); 951: com->hsh = flags | hiint(vaddr); 952: msgs->m_dscptr = (long *)com; 953: msgs->m_header.mscp_msglen = sizeof(struct mscp); 954: ++com; ++msgs; vaddr += sizeof(struct mscp); 955: } 956: } 957: 958: /* 959: * Try and find an unused command packet 960: */ 961: struct mscp * 962: ragetcp(sc) 963: register ra_softcT *sc; 964: { 965: register struct mscp *mp = NULL; 966: register int i; 967: int s; 968: segm seg5; 969: 970: s = splbio(); 971: saveseg5(seg5); 972: mapseg5(ra_com[sc->sc_unit], MAPSEGDESC); 973: i = sc->sc_lastcmd; 974: if ((sc->sc_com->ra_ca.ca_cmd[i].hsh & (RA_OWN|RA_INT)) == RA_INT 975: && sc->sc_credits >= 2) { 976: --sc->sc_credits; 977: sc->sc_com->ra_ca.ca_cmd[i].hsh &= ~RA_INT; 978: mp = &sc->sc_com->ra_cmd[i]; 979: ramsgclear(mp); 980: sc->sc_lastcmd = (i + 1) % NCMD; 981: } 982: restorseg5(seg5); 983: splx(s); 984: return(mp); 985: } 986: 987: /* Clear a mscp command packet */ 988: ramsgclear(mp) 989: register struct mscp *mp; 990: { 991: mp->m_unit = mp->m_modifier = mp->m_flags = 992: mp->m_bytecnt = mp->m_buf_l = mp->m_buf_h = 993: mp->m_elgfll = mp->m_copyspd = mp->m_elgflh = 994: mp->m_opcode = mp->m_cntflgs = 0; 995: } 996: 997: /* Scan for response messages */ 998: rarspring(sc) 999: register ra_softcT *sc; 1000: { 1001: register int i; 1002: 1003: sc->sc_com->ra_ca.ca_rspint = 0; 1004: i = sc->sc_lastrsp; 1005: for (;;) { 1006: i %= NRSP; 1007: if (sc->sc_com->ra_ca.ca_rsp[i].hsh & RA_OWN) 1008: break; 1009: rarsp(&sc->sc_com->ra_rsp[i], sc); 1010: sc->sc_com->ra_ca.ca_rsp[i].hsh |= RA_OWN; 1011: ++i; 1012: } 1013: sc->sc_lastrsp = i; 1014: } 1015: 1016: /* 1017: * Process a response packet 1018: */ 1019: rarsp(mp, sc) 1020: register struct mscp *mp; 1021: register ra_softcT *sc; 1022: { 1023: register struct buf *dp; 1024: struct buf *bp; 1025: ra_infoT *disk; 1026: int st; 1027: 1028: /* 1029: * Reset packet length and check controller credits 1030: */ 1031: mp->m_header.mscp_msglen = sizeof(struct mscp); 1032: sc->sc_credits += mp->m_header.mscp_credits & 0xf; 1033: if ((mp->m_header.mscp_credits & 0xf0) > 0x10) 1034: return; 1035: 1036: /* 1037: * If it's an error log message (datagram), 1038: * pass it on for more extensive processing. 1039: */ 1040: if ((mp->m_header.mscp_credits & 0xf0) == 0x10) { 1041: ra_error(sc->sc_unit, (struct mslg *)mp); 1042: return; 1043: } 1044: 1045: /* 1046: * The controller interrupts as drive ZERO so check for it first. 1047: */ 1048: st = mp->m_status & M_ST_MASK; 1049: if (mscpprintf & 0x4 || ((mscpprintf & 0x1) && (st != M_ST_SUCC))) 1050: log(LOG_INFO, "ra%d st=%x sb=%x fl=%x en=%x\n", 1051: sc->sc_unit*8 + mp->m_unit, st, 1052: mp->m_status >> M_ST_SBBIT, 1053: mp->m_flags, mp->m_opcode & ~M_OP_END); 1054: if (mp->m_opcode == (M_OP_STCON|M_OP_END)) { 1055: if (st == M_ST_SUCC) 1056: sc->sc_state = S_RUN; 1057: else 1058: sc->sc_state = S_IDLE; 1059: sc->sc_ctab.b_active = 0; 1060: wakeup((caddr_t)&sc->sc_ctab); 1061: return; 1062: } 1063: 1064: /* 1065: * Check drive and then decode response and take action. 1066: */ 1067: switch (mp->m_opcode) { 1068: case M_OP_ONLIN|M_OP_END: 1069: if ((disk = sc->sc_drives[mp->m_unit]) == NULL) 1070: break; 1071: dp = &disk->ra_utab; 1072: 1073: if (st == M_ST_SUCC) { 1074: /* Link the drive onto the controller queue */ 1075: dp->b_forw = NULL; 1076: if (sc->sc_ctab.b_actf == NULL) 1077: sc->sc_ctab.b_actf = dp; 1078: else 1079: sc->sc_ctab.b_actl->b_forw = dp; 1080: sc->sc_ctab.b_actl = dp; 1081: 1082: /* mark it online */ 1083: radisksetup(disk, mp); 1084: dp->b_active = 1; 1085: } else { 1086: while (bp = dp->b_actf) { 1087: dp->b_actf = bp->av_forw; 1088: bp->b_flags |= B_ERROR; 1089: iodone(bp); 1090: } 1091: } 1092: 1093: /* Wakeup in open if online came from there */ 1094: if (mp->m_cmdref != NULL) 1095: wakeup((caddr_t)mp->m_cmdref); 1096: break; 1097: case M_OP_AVATN: 1098: /* it went offline and we didn't notice */ 1099: if ((disk = sc->sc_drives[mp->m_unit]) != NULL) 1100: disk->ra_flags &= ~DKF_ONLINE; 1101: break; 1102: case M_OP_END: 1103: /* controller incorrectly returns code 0200 instead of 0241 */ 1104: bp = (struct buf *)mp->m_cmdref; 1105: bp->b_flags |= B_ERROR; 1106: case M_OP_READ | M_OP_END: 1107: case M_OP_WRITE | M_OP_END: 1108: /* normal termination of read/write request */ 1109: if ((disk = sc->sc_drives[mp->m_unit]) == NULL) 1110: break; 1111: bp = (struct buf *)mp->m_cmdref; 1112: 1113: /* 1114: * Unlink buffer from I/O wait queue. 1115: */ 1116: bp->av_back->av_forw = bp->av_forw; 1117: bp->av_forw->av_back = bp->av_back; 1118: dp = &disk->ra_utab; 1119: 1120: #ifdef UCB_METER 1121: if (ra_dkn >= 0) { 1122: /* Messy, Should come up with a good way to do this */ 1123: if (--dp->b_qsize == 0) 1124: dk_busy &= ~(1 << (ra_dkn + mp->m_unit)); 1125: } 1126: #endif 1127: if (st == M_ST_OFFLN || st == M_ST_AVLBL) { 1128: /* mark unit offline */ 1129: disk->ra_flags &= ~DKF_ONLINE; 1130: 1131: /* Link the buffer onto the front of the drive queue */ 1132: if ((bp->av_forw = dp->b_actf) == 0) 1133: dp->b_actl = bp; 1134: dp->b_actf = bp; 1135: 1136: /* Link the drive onto the controller queue */ 1137: if (dp->b_active == 0) { 1138: dp->b_forw = NULL; 1139: if (sc->sc_ctab.b_actf == NULL) 1140: sc->sc_ctab.b_actf = dp; 1141: else 1142: sc->sc_ctab.b_actl->b_forw = dp; 1143: sc->sc_ctab.b_actl = dp; 1144: dp->b_active = 1; 1145: } 1146: return; 1147: } 1148: if (st != M_ST_SUCC) { 1149: harderr(bp, "ra"); 1150: log(LOG_INFO, "status %o\n", mp->m_status); 1151: bp->b_flags |= B_ERROR; 1152: } 1153: bp->b_resid = bp->b_bcount - mp->m_bytecnt; 1154: iodone(bp); 1155: break; 1156: case M_OP_GTUNT|M_OP_END: 1157: break; 1158: default: 1159: ra_error(sc->sc_unit, (caddr_t)mp); 1160: } 1161: } 1162: 1163: /* 1164: * Init disk info structure from data in mscp packet 1165: */ 1166: radisksetup(disk, mp) 1167: register ra_infoT *disk; 1168: register struct mscp *mp; 1169: { 1170: int nameid, numid; 1171: 1172: nameid = (((loint(mp->m_mediaid) & 0x3f) << 9) | 1173: ((hiint(mp->m_mediaid) >> 7) & 0x1ff)); 1174: numid = hiint(mp->m_mediaid) & 0x7f; 1175: 1176: /* Get unit total block count */ 1177: disk->ra_nblks = mp->m_uslow + ((long)mp->m_ushigh << 16); 1178: 1179: /* spill the beans about what we have brought online */ 1180: log(LOG_NOTICE, "ra%d: %c%c%d%c size=%D\n", 1181: disk->ra_unit * 8 + mp->m_unit, 1182: mx(nameid,2), mx(nameid,1), numid, mx(nameid,0), 1183: disk->ra_nblks); 1184: disk->ra_flags |= DKF_ONLINE; 1185: } 1186: 1187: /* 1188: * this is a routine rather than a macro to save space - shifting, etc 1189: * generates a lot of code. 1190: */ 1191: 1192: mx(l, i) 1193: int l, i; 1194: { 1195: register int c; 1196: 1197: c = (l >> (5 * i)) & 0x1f; 1198: if (c == 0) 1199: c = ' ' - '@'; 1200: return(c + '@'); 1201: } 1202: 1203: raioctl(dev, cmd, data, flag) 1204: dev_t dev; 1205: int cmd; 1206: caddr_t data; 1207: int flag; 1208: { 1209: ra_softcT *sc = &ra_sc[RACON(dev)]; 1210: ra_infoT *disk = sc->sc_drives[RAUNIT(dev)]; 1211: int error; 1212: 1213: error = ioctldisklabel(dev, cmd, data, flag, disk, rastrategy); 1214: return(error); 1215: } 1216: 1217: /* 1218: * For now just count the datagrams and log a short message of (hopefully) 1219: * interesting fields if the appropriate bit in turned on in mscpprintf. 1220: * 1221: * An error log daemon is in the process of being written. When it is ready 1222: * many drivers (including this one) will be converted to use it. 1223: */ 1224: 1225: u_short mscp_datagrams[NRAC]; 1226: 1227: ra_error(ctlr, mp) 1228: int ctlr; 1229: register struct mslg *mp; 1230: { 1231: 1232: mscp_datagrams[ctlr]++; 1233: if (mscpprintf & 0x2) 1234: log(LOG_INFO, "ra%d dgram fmt %x grp %x hdr %x evt %x cyl %x\n", 1235: ctlr*8 + mp->me_unit, mp->me_format, mp->me_group, 1236: mp->me_hdr, mp->me_event, mp->me_sdecyl); 1237: } 1238: 1239: /* 1240: * RA dump routines (act like stand alone driver) 1241: */ 1242: #ifdef RA_DUMP 1243: #define DBSIZE 16 /* number of blocks to write */ 1244: 1245: radump(dev) 1246: dev_t dev; 1247: { 1248: register ra_softcT *sc; 1249: register ra_infoT *disk; 1250: register struct mscp *mp; 1251: struct mscp *racmd(); 1252: struct partition *pi; 1253: daddr_t bn, dumpsize; 1254: long paddr, maddr; 1255: int count, memblks; 1256: struct ubmap *ubp; 1257: int unit, partition; 1258: segm seg5; 1259: 1260: /* paranoia, space hack */ 1261: unit = RAUNIT(dev); 1262: sc = &ra_sc[RACON(dev)]; 1263: partition = dkpart(dev); 1264: if (sc->RAADDR == NULL) 1265: return(EINVAL); 1266: disk = sc->sc_drives[unit]; 1267: /* 1268: * The drive to which we dump must be present and alive. 1269: */ 1270: if (!disk || !(disk->ra_flags & DKF_ALIVE)) 1271: return(ENXIO); 1272: pi = &disk->ra_parts[partition]; 1273: /* 1274: * Paranoia - we do not dump to a partition if it has not been declared as 1275: * a 'swap' type of filesystem. 1276: */ 1277: if (pi->p_fstype != FS_SWAP) 1278: return(EFTYPE); 1279: 1280: /* Init RA controller */ 1281: paddr = _iomap(ra_com[sc->sc_unit]); 1282: if (ubmap) { 1283: ubp = UBMAP; 1284: ubp->ub_lo = loint(paddr); 1285: ubp->ub_hi = hiint(paddr); 1286: } 1287: 1288: /* Get communications area and clear out packets */ 1289: paddr += RINGBASE; 1290: saveseg5(seg5); 1291: mapseg5(ra_com[sc->sc_unit], MAPSEGDESC); 1292: mp = sc->sc_com->ra_rsp; 1293: sc->sc_com->ra_ca.ca_cmdint = sc->sc_com->ra_ca.ca_rspint = 0; 1294: bzero((caddr_t)mp, 2 * sizeof(*mp)); 1295: 1296: /* Init controller */ 1297: sc->RAADDR->raip = 0; 1298: while ((sc->RAADDR->rasa & RA_STEP1) == 0) 1299: /*void*/; 1300: sc->RAADDR->rasa = RA_ERR; 1301: while ((sc->RAADDR->rasa & RA_STEP2) == 0) 1302: /*void*/; 1303: sc->RAADDR->rasa = loint(paddr); 1304: while ((sc->RAADDR->rasa & RA_STEP3) == 0) 1305: /*void*/; 1306: sc->RAADDR->rasa = hiint(paddr); 1307: while ((sc->RAADDR->rasa & RA_STEP4) == 0) 1308: /*void*/; 1309: sc->RAADDR->rasa = RA_GO; 1310: ramsginit(sc, sc->sc_com->ra_ca.ca_rsp, mp, 0, 2, 0); 1311: if (!racmd(M_OP_STCON, unit, sc)) 1312: return(EFAULT); 1313: 1314: /* Bring disk for dump online */ 1315: if (!(mp = racmd(M_OP_ONLIN, unit, sc))) 1316: return(EFAULT); 1317: 1318: dumpsize = rasize(dev) - dumplo; 1319: memblks = ctod(physmem); 1320: 1321: /* Check if dump ok on this disk */ 1322: if (dumplo < 0 || dumpsize <= 0) 1323: return(EINVAL); 1324: if (memblks > dumpsize) 1325: memblks = dumpsize; 1326: bn = dumplo + pi->p_offset; 1327: 1328: /* Save core to dump partition */ 1329: ubp = &UBMAP[1]; 1330: for (paddr = 0L; memblks > 0; ) { 1331: count = MIN(memblks, DBSIZE); 1332: maddr = paddr; 1333: 1334: if (ubmap) { 1335: ubp->ub_lo = loint(paddr); 1336: ubp->ub_hi = hiint(paddr); 1337: maddr = (u_int)(1 << 13); 1338: } 1339: 1340: /* Write it to the disk */ 1341: mp = &sc->sc_com->ra_rsp[1]; 1342: mp->m_lbn_l = loint(bn); 1343: mp->m_lbn_h = hiint(bn); 1344: mp->m_bytecnt = count * NBPG; 1345: mp->m_buf_l = loint(maddr); 1346: mp->m_buf_h = hiint(maddr); 1347: if (racmd(M_OP_WRITE, unit, sc) == 0) 1348: return(EIO); 1349: paddr += (count << PGSHIFT); 1350: bn += count; 1351: memblks -= count; 1352: } 1353: restorseg5(seg5); 1354: return(0); 1355: } 1356: 1357: struct mscp * 1358: racmd(op, unit, sc) 1359: int op, unit; 1360: register ra_softcT *sc; 1361: { 1362: register struct mscp *cmp, *rmp; 1363: Trl *rlp; 1364: int i; 1365: 1366: cmp = &sc->sc_com->ra_rsp[1]; 1367: rmp = &sc->sc_com->ra_rsp[0]; 1368: rlp = &sc->sc_com->ra_ca.ca_rsp[0]; 1369: cmp->m_opcode = op; 1370: cmp->m_unit = unit; 1371: cmp->m_header.mscp_msglen = rmp->m_header.mscp_msglen = 1372: sizeof(struct mscp); 1373: rlp[0].hsh &= ~RA_INT; 1374: rlp[1].hsh &= ~RA_INT; 1375: rlp[0].hsh &= ~RA_INT; 1376: rlp[1].hsh &= ~RA_INT; 1377: rlp[0].hsh |= RA_OWN; 1378: rlp[1].hsh |= RA_OWN; 1379: i = sc->RAADDR->raip; 1380: while ((rlp[1].hsh & RA_INT) == 0) 1381: /*void*/; 1382: while ((rlp[0].hsh & RA_INT) == 0) 1383: /*void*/; 1384: sc->sc_com->ra_ca.ca_rspint = 0; 1385: sc->sc_com->ra_ca.ca_cmdint = 0; 1386: if (rmp->m_opcode != (op | M_OP_END) 1387: || (rmp->m_status & M_ST_MASK) != M_ST_SUCC) { 1388: ra_error(sc->sc_unit, rmp); 1389: return(0); 1390: } 1391: return(rmp); 1392: } 1393: #endif RA_DUMP 1394: 1395: /* 1396: * Return the number of blocks in a partition. Call raopen() to online 1397: * the drive if necessary. If an open is necessary then a matching close 1398: * will be done. 1399: */ 1400: daddr_t 1401: rasize(dev) 1402: register dev_t dev; 1403: { 1404: ra_softcT *sc = &ra_sc[RACON(dev)]; 1405: register ra_infoT *disk; 1406: daddr_t psize; 1407: int didopen = 0; 1408: 1409: disk = sc->sc_drives[RAUNIT(dev)]; 1410: /* 1411: * This should never happen but if we get called early in the kernel's 1412: * life (before opening the swap or root devices) then we have to do 1413: * the open here. 1414: */ 1415: if (disk->ra_open == 0) 1416: { 1417: if (raopen(dev, FREAD|FWRITE, S_IFBLK)) 1418: return(-1); 1419: didopen = 1; 1420: } 1421: psize = disk->ra_parts[dkpart(dev)].p_size; 1422: if (didopen) 1423: raclose(dev, FREAD|FWRITE, S_IFBLK); 1424: return(psize); 1425: } 1426: #endif NRAC > 0 && NRAD > 0