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

Defined functions

mx defined in line 1192; used 3 times
raVec defined in line 281; used 1 times
ra_error defined in line 1227; used 3 times
raattach defined in line 299; used 1 times
raclose defined in line 489; used 1 times
racmd defined in line 1357; used 4 times
radfltlbl defined in line 527; used 3 times
radisksetup defined in line 1166; used 1 times
radostep defined in line 915; used 4 times
radump defined in line 1245; used 4 times
ragetcp defined in line 961; used 3 times
ragetdd defined in line 329; used 1 times
ragetinfo defined in line 566; used 2 times
rainit defined in line 600; used 2 times
raintr defined in line 812; used 1 times
raioctl defined in line 1203; never used
ramsgclear defined in line 988; used 2 times
ramsginit defined in line 933; used 3 times
raopen defined in line 347; used 1 times
raroot defined in line 265; never used
rarsp defined in line 1019; used 1 times
rarspring defined in line 998; used 2 times
rasize defined in line 1400; used 2 times
rastart defined in line 699; used 2 times
rastrategy defined in line 640; used 3 times

Defined variables

mscp_datagrams defined in line 1225; used 1 times
mscpprintf defined in line 245; used 6 times
ra_com defined in line 218; used 11 times
ra_disks defined in line 219; used 1 times
ra_dkn defined in line 224; used 6 times

Defined struct's

ra_info defined in line 188; never used
raca defined in line 167; used 4 times

Defined typedef's

ra_infoT defined in line 193; used 17 times

Defined macros

DBSIZE defined in line 1243; used 1 times
MAPSEGDESC defined in line 221; used 7 times
NCMD defined in line 157; used 4 times
NCMDL2 defined in line 155; used 3 times
NRSP defined in line 156; used 5 times
NRSPL2 defined in line 154; used 3 times
RACON defined in line 151; used 7 times
RAUNIT defined in line 152; used 7 times
RA_INT defined in line 180; used 14 times
RA_OWN defined in line 179; used 9 times
RINGBASE defined in line 177; used 2 times
STEP1GOOD defined in line 826; used 1 times
STEP1MASK defined in line 825; used 1 times
STEP2GOOD defined in line 834; used 1 times
STEP2MASK defined in line 833; used 1 times
STEP3GOOD defined in line 842; used 1 times
STEP3MASK defined in line 841; used 1 times
S_IDLE defined in line 230; used 3 times
S_RUN defined in line 235; used 4 times
S_SCHAR defined in line 234; used 1 times
S_STEP1 defined in line 231; used 1 times
S_STEP2 defined in line 232; used 1 times
S_STEP3 defined in line 233; used 1 times
b_qsize defined in line 253; used 2 times
ra_bopen defined in line 195; used 3 times
ra_copen defined in line 196; used 3 times
ra_flags defined in line 198; used 18 times
ra_label defined in line 199; used 5 times
ra_open defined in line 197; used 7 times
ra_parts defined in line 200; used 5 times
Last modified: 1998-04-04
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 7225
Valid CSS Valid XHTML 1.0 Strict