# 2.11BSD#431 - /usr/src/sys/pdpuba/ra.c

##### Functions

    mx                X
    raVec             X
    ra_error          X
    raattach          X
    raclose           X
    racmd             X
    radfltlbl         X
    radisksetup       X
    radostep          X
    radump            X
    ragetcp           X
    ragetdd           X
    ragetinfo         X
    rainit            X
    raintr            X
    raioctl           X
    ramsgclear        X
    ramsginit         X
    raopen            X
    raroot            X
    rarsp             X
    rarspring         X
    rasize            X
    rastart           X
    rastrategy        X

##### Variables

    mscp_datagrams    X
    mscpprintf        X
    ra_com            X
    ra_disks          X

##### Macros

    DBSIZE            X
    MAPSEGDESC        X
    NCMD              X
    NCMDL2            X
    NRSP              X
    NRSPL2            X
    RACON             X
    RAUNIT            X
    RA_INT            X
    RA_OWN            X
    RINGBASE          X
    STEP1GOOD         X
    STEP1MASK         X
    STEP2GOOD         X
    STEP2MASK         X
    STEP3GOOD         X
    STEP3MASK         X
    S_IDLE            X
    S_RUN             X
    S_SCHAR           X
    S_STEP1           X
    S_STEP2           X
    S_STEP3           X
    b_qsize           X
    ra_bopen          X
    ra_copen          X
    ra_flags          X
    ra_label          X
    ra_open           X
    ra_parts          X

##### struct's

    ra_info           X
    raca              X

##### typedef's

    ra_infoT          X

       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

- in line 1182(3)

raVec defined in line 281; used 1 times

- in line 271

ra_error defined in line 1227; used 3 times

- in line 1041, 1159, 1388

raattach defined in line 299; used 1 times

- in line 270

raclose defined in line 489; used 1 times

- in line 1423

racmd defined in line 1357; used 4 times

- in line 1251, 1311-1315(2), 1347

radfltlbl defined in line 527; used 3 times

- in line 250, 580, 587

radisksetup defined in line 1166; used 1 times

- in line 1083

radostep defined in line 915; used 4 times

- in line 827, 835, 843, 882

radump defined in line 1245; used 4 times

- in /usr/src/sys/CURLY/ioconf.c line 18-19(2)
- in /usr/src/sys/QT/ioconf.c line 18-19(2)

ragetcp defined in line 961; used 3 times

- in line 251, 407, 759

ragetdd defined in line 329; used 1 times

- in line 394

ragetinfo defined in line 566; used 2 times

- in line 250, 458

rainit defined in line 600; used 2 times

- in line 370, 751

raintr defined in line 812; used 1 times

- in /usr/src/sys/pdp/scb.s line 332

raioctl defined in line 1203; never used
ramsgclear defined in line 988; used 2 times

- in line 864, 979

ramsginit defined in line 933; used 3 times

- in line 855-857(2), 1310

raopen defined in line 347; used 1 times

- in line 1417

raroot defined in line 265; never used
rarsp defined in line 1019; used 1 times

- in line 1009

rarspring defined in line 998; used 2 times

- in line 724, 899

rasize defined in line 1400; used 2 times

- in line 238, 1318

rastart defined in line 699; used 2 times

- in line 688, 912

rastrategy defined in line 640; used 3 times

- in line 237, 581, 1213

#### Defined variables

mscp_datagrams defined in line 1225; used 1 times

- in line 1232

mscpprintf defined in line 245; used 6 times

- in line 398, 584, 1049(2), 1233
- in /usr/src/sys/pdp/kern_pdp.c line 254

ra_com defined in line 218; used 11 times

- in line 315, 412, 614, 723, 758, 854, 885, 945, 972, 1281, 1291

ra_disks defined in line 219; used 1 times

- in line 335

ra_dkn defined in line 224; used 6 times

- in line 306-307(2), 776-777(2), 1121-1124(2)

#### Defined struct's

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

- in line 183(2), 946(2)

#### Defined typedef's

ra_infoT defined in line 193; used 17 times

- in line 219, 329, 529, 568, 1167-214(2), 333, 352, 495, 643, 706, 740-741(2), 1025, 1210, 1249, 1405

#### Defined macros

DBSIZE defined in line 1243; used 1 times

- in line 1331

MAPSEGDESC defined in line 221; used 7 times

- in line 412, 723, 758, 854, 885, 972, 1291

NCMD defined in line 157; used 4 times

- in line 174, 185, 858, 980

NCMDL2 defined in line 155; used 3 times

- in line 157, 629, 826

NRSP defined in line 156; used 5 times

- in line 173, 184, 856-858(2), 1006

NRSPL2 defined in line 154; used 3 times

- in line 156, 629, 826

RACON defined in line 151; used 7 times

- in line 354-356(2), 496, 645, 1209, 1262, 1404

RAUNIT defined in line 152; used 7 times

- in line 355, 493, 649, 763, 1210, 1261, 1409

RA_INT defined in line 180; used 14 times

- in line 416, 772, 856-858(2), 867, 974-977(3), 1373-1382(6)

RA_OWN defined in line 179; used 9 times

- in line 416, 772, 856, 867, 974, 1007-1010(2), 1377-1378(2)

RINGBASE defined in line 177; used 2 times

- in line 614, 1289

STEP1GOOD defined in line 826; used 1 times

- in line 827

STEP1MASK defined in line 825; used 1 times

- in line 827

STEP2GOOD defined in line 834; used 1 times

- in line 835

STEP2MASK defined in line 833; used 1 times

- in line 835

STEP3GOOD defined in line 842; used 1 times

- in line 843

STEP3MASK defined in line 841; used 1 times

- in line 843

S_IDLE defined in line 230; used 3 times

- in line 369, 922, 1058

S_RUN defined in line 235; used 4 times

- in line 365, 379, 748, 1056

S_SCHAR defined in line 234; used 1 times

- in line 849

S_STEP1 defined in line 231; used 1 times

- in line 635

S_STEP2 defined in line 232; used 1 times

- in line 830

S_STEP3 defined in line 233; used 1 times

- in line 838

b_qsize defined in line 253; used 2 times

- in line 780, 1123

ra_bopen defined in line 195; used 3 times

- in line 478, 503-506(2)

ra_copen defined in line 196; used 3 times

- in line 476, 501-506(2)

ra_flags defined in line 198; used 18 times

- in line 336-338(2), 405, 415-427(5), 438, 457-459(2), 509-514(2), 650, 1100, 1129, 1184, 1270

ra_label defined in line 199; used 5 times

- in line 448-449(2), 467, 474, 589

ra_open defined in line 197; used 7 times

- in line 455, 474, 481, 506-507(2), 742, 1415

ra_parts defined in line 200; used 5 times

- in line 548, 592, 765, 1272, 1421

Last modified: 1998-04-04 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 3362 |