Annotation of 43BSD/sys/vaxuba/uda.c, revision 1.1

1.1     ! root        1: /*
        !             2:  *     @(#)uda.c       7.1 (Berkeley) 6/5/86
        !             3:  */
        !             4: 
        !             5: /************************************************************************
        !             6:  *                                                                     *
        !             7:  *                     Copyright (c) 1983 by                           *
        !             8:  *             Digital Equipment Corporation, Maynard, MA              *
        !             9:  *                     All rights reserved.                            *
        !            10:  *                                                                     *
        !            11:  ************************************************************************/
        !            12: /* 
        !            13:  * uda.c - UDA50A Driver
        !            14:  *
        !            15:  * decvax!rich
        !            16:  */
        !            17: 
        !            18: #define        DEBUG
        !            19: #define        UDADEVNUM       (9)             /* entry in bdevsw */
        !            20: #include "ra.h"
        !            21: #if NUDA > 0
        !            22: /*
        !            23:  * UDA50/RAxx disk device driver
        !            24:  *
        !            25:  * Restrictions:
        !            26:  *      Unit numbers must be less than 8.
        !            27:  */
        !            28: #include "../machine/pte.h"
        !            29: 
        !            30: #include "param.h"
        !            31: #include "systm.h"
        !            32: #include "buf.h"
        !            33: #include "conf.h"
        !            34: #include "dir.h"
        !            35: #include "user.h"
        !            36: #include "map.h"
        !            37: #include "vm.h"
        !            38: #include "dk.h"
        !            39: #include "cmap.h"
        !            40: #include "uio.h"
        !            41: 
        !            42: #include "../vax/cpu.h"
        !            43: #include "ubareg.h"
        !            44: #include "ubavar.h"
        !            45: #include "../vax/mtpr.h"
        !            46: 
        !            47: #define TENSEC (1000)
        !            48:  
        !            49: #define NRSPL2  3               /* log2 number of response packets */
        !            50: #define NCMDL2  3               /* log2 number of command packets */
        !            51: #define NRSP    (1<<NRSPL2)
        !            52: #define NCMD    (1<<NCMDL2)
        !            53: #define        UDABURST        4       /* default for DMA burst size */
        !            54: 
        !            55: #include "../vaxuba/udareg.h"
        !            56: #include "../vax/mscp.h"
        !            57: 
        !            58: 
        !            59: struct uda_softc {
        !            60:        short   sc_state;       /* state of controller */
        !            61:        short   sc_mapped;      /* Unibus map allocated for uda struct? */
        !            62:        int     sc_ubainfo;     /* Unibus mapping info */
        !            63:        struct uda *sc_uda;     /* Unibus address of uda struct */
        !            64:        int     sc_ivec;        /* interrupt vector address */
        !            65:        short   sc_credits;     /* transfer credits */
        !            66:        short   sc_lastcmd;     /* pointer into command ring */
        !            67:        short   sc_lastrsp;     /* pointer into response ring */
        !            68: } uda_softc[NUDA];
        !            69: struct uda {
        !            70:        struct udaca    uda_ca;         /* communications area */
        !            71:        struct mscp     uda_rsp[NRSP];  /* response packets */
        !            72:        struct mscp     uda_cmd[NCMD];  /* command packets */
        !            73: } uda[NUDA];
        !            74: 
        !            75: #define udunit(dev)    (minor(dev) >> 3)
        !            76: 
        !            77: /* THIS SHOULD BE READ OFF THE PACK, PER DRIVE */
        !            78: struct size {
        !            79:        daddr_t nblocks;
        !            80:        daddr_t blkoff;
        !            81: }  ra25_sizes[8] = {
        !            82:        15884,  0,              /* A=blk 0 thru 15883 */
        !            83:        10032,  15884,          /* B=blk 15884 thru 49323 */
        !            84:        -1,     0,              /* C=blk 0 thru end */
        !            85:        0,      0,              /* D=blk 340670 thru 356553 */
        !            86:        0,      0,              /* E=blk 356554 thru 412489 */
        !            87:        0,      0,              /* F=blk 412490 thru end */
        !            88:        -1,     25916,          /* G=blk 49324 thru 131403 */
        !            89:        0,      0,              /* H=blk 131404 thru end */
        !            90: }, rd52_sizes[8] = {
        !            91:        15884,  0,              /* A=blk 0 thru 15883 */
        !            92:        9766,   15884,          /* B=blk 15884 thru 25649 */
        !            93:        -1,     0,              /* C=blk 0 thru end */
        !            94:        0,      0,              /* D=unused */
        !            95:        0,      0,              /* E=unused */
        !            96:        0,      0,              /* F=unused */
        !            97:        -1,     25650,          /* G=blk 25650 thru end */
        !            98:        0,      0,              /* H=unused */
        !            99: }, rd53_sizes[8] = {
        !           100:        15884,  0,              /* A=blk 0 thru 15883 */
        !           101:        33440,  15884,          /* B=blk 15884 thru 49323 */
        !           102:        -1,     0,              /* C=blk 0 thru end */
        !           103:        0,      0,              /* D=unused */
        !           104:        33440,  0,              /* E=blk 0 thru 33439 */
        !           105:        -1,     33440,          /* F=blk 33440 thru end */
        !           106:        -1,     49324,          /* G=blk 49324 thru end */
        !           107:        -1,     15884,          /* H=blk 15884 thru end */
        !           108: }, ra60_sizes[8] = {
        !           109:        15884,  0,              /* A=sectors 0 thru 15883 */
        !           110:        33440,  15884,          /* B=sectors 15884 thru 49323 */
        !           111:        400176, 0,              /* C=sectors 0 thru 400175 */
        !           112:        82080,  49324,          /* 4.2 G => D=sectors 49324 thru 131403 */
        !           113:        268772, 131404,         /* 4.2 H => E=sectors 131404 thru 400175 */
        !           114:        350852, 49324,          /* F=sectors 49324 thru 400175 */
        !           115:        157570, 242606,         /* UCB G => G=sectors 242606 thru 400175 */
        !           116:        193282, 49324,          /* UCB H => H=sectors 49324 thru 242605 */
        !           117: }, ra80_sizes[8] = {
        !           118:        15884,  0,              /* A=sectors 0 thru 15883 */
        !           119:        33440,  15884,          /* B=sectors 15884 thru 49323 */
        !           120:        242606, 0,              /* C=sectors 0 thru 242605 */
        !           121:        0,      0,              /* D=unused */
        !           122:        193282, 49324,          /* UCB H => E=sectors 49324 thru 242605 */
        !           123:        82080,  49324,          /* 4.2 G => F=sectors 49324 thru 131403 */
        !           124:        192696, 49910,          /* G=sectors 49910 thru 242605 */
        !           125:        111202, 131404,         /* 4.2 H => H=sectors 131404 thru 242605 */
        !           126: }, ra81_sizes[8] ={
        !           127: /*
        !           128:  * These are the new standard partition sizes for ra81's.
        !           129:  * An RA_COMPAT system is compiled with D, E, and F corresponding
        !           130:  * to the 4.2 partitions for G, H, and F respectively.
        !           131:  */
        !           132: #ifndef        UCBRA
        !           133:        15884,  0,              /* A=sectors 0 thru 15883 */
        !           134:        66880,  16422,          /* B=sectors 16422 thru 83301 */
        !           135:        891072, 0,              /* C=sectors 0 thru 891071 */
        !           136: #ifdef RA_COMPAT
        !           137:        82080,  49324,          /* 4.2 G => D=sectors 49324 thru 131403 */
        !           138:        759668, 131404,         /* 4.2 H => E=sectors 131404 thru 891071 */
        !           139:        478582, 412490,         /* 4.2 F => F=sectors 412490 thru 891071 */
        !           140: #else
        !           141:        15884,  375564,         /* D=sectors 375564 thru 391447 */
        !           142:        307200, 391986,         /* E=sectors 391986 thru 699185 */
        !           143:        191352, 699720,         /* F=sectors 699720 thru 891071 */
        !           144: #endif RA_COMPAT
        !           145:        515508, 375564,         /* G=sectors 375564 thru 891071 */
        !           146:        291346, 83538,          /* H=sectors 83538 thru 374883 */
        !           147: 
        !           148: /*
        !           149:  * These partitions correspond to the sizes used by sites at Berkeley,
        !           150:  * and by those sites that have received copies of the Berkeley driver
        !           151:  * with deltas 6.2 or greater (11/15/83).
        !           152:  */
        !           153: #else UCBRA
        !           154: 
        !           155:        15884,  0,              /* A=sectors 0 thru 15883 */
        !           156:        33440,  15884,          /* B=sectors 15884 thru 49323 */
        !           157:        891072, 0,              /* C=sectors 0 thru 891071 */
        !           158:        15884,  242606,         /* D=sectors 242606 thru 258489 */
        !           159:        307200, 258490,         /* E=sectors 258490 thru 565689 */
        !           160:        325382, 565690,         /* F=sectors 565690 thru 891071 */
        !           161:        648466, 242606,         /* G=sectors 242606 thru 891071 */
        !           162:        193282, 49324,          /* H=sectors 49324 thru 242605 */
        !           163: 
        !           164: #endif UCBRA
        !           165: };
        !           166: 
        !           167: struct ra_info {
        !           168:        struct  size    *ra_sizes;      /* Partion tables for drive */
        !           169:        daddr_t         radsize;        /* Max user size form online pkt */
        !           170:        unsigned        ratype;         /* Drive type int field  */
        !           171:        unsigned        rastatus;       /* Command status from */
        !           172:                                        /* last onlin or GTUNT */
        !           173: } ra_info[NRA];
        !           174: 
        !           175: 
        !           176: /* END OF STUFF WHICH SHOULD BE READ IN PER DISK */
        !           177: struct  uba_ctlr *udminfo[NUDA];
        !           178: struct  uba_device *uddinfo[NRA];
        !           179: struct  uba_device *udip[NUDA][8];      /* 8 == max number of drives */
        !           180: struct  buf rudbuf[NRA];
        !           181: struct  buf udutab[NRA];
        !           182: struct  buf udwtab[NUDA];               /* I/O wait queue, per controller */
        !           183: 
        !           184: 
        !           185: int     udamicro[NUDA];         /* to store microcode level */
        !           186: int     udaburst[NUDA] = { 0 };        /* DMA burst size, 0 is default */
        !           187: 
        !           188: 
        !           189: /*
        !           190:  * Controller states
        !           191:  */
        !           192: #define S_IDLE  0               /* hasn't been initialized */
        !           193: #define S_STEP1 1               /* doing step 1 init */
        !           194: #define S_STEP2 2               /* doing step 2 init */
        !           195: #define S_STEP3 3               /* doing step 3 init */
        !           196: #define S_SCHAR 4               /* doing "set controller characteristics" */
        !           197: #define S_RUN   5               /* running */
        !           198: 
        !           199: 
        !           200: int     udaerror = 0;                   /* causes hex dump of packets */
        !           201: int     udadebug = 0;
        !           202: int    uda_cp_wait = 0;                /* Something to wait on for command */
        !           203:                                        /* packets and or credits. */
        !           204: int    wakeup();
        !           205: extern int     hz;                     /* Should find the right include */
        !           206: #ifdef DEBUG
        !           207: #define printd  if (udadebug) printf
        !           208: #define        printd10        if(udadebug >= 10) printf
        !           209: #endif 
        !           210: #define mprintf printf                 /* temporary JG hack until Rich fixes*/
        !           211: 
        !           212: int     udprobe(), udslave(), udattach(), udintr();
        !           213: struct  mscp *udgetcp();
        !           214: 
        !           215: u_short udstd[] = { 0772150, 0772550, 0777550, 0 };
        !           216: struct  uba_driver udadriver =
        !           217:  { udprobe, udslave, udattach, 0, udstd, "ra", uddinfo, "uda", udminfo, 0 };
        !           218: 
        !           219: #define b_qsize         b_resid         /* queue size per drive, in udutab */
        !           220: #define b_ubinfo        b_resid         /* Unibus mapping info, per buffer */
        !           221: 
        !           222: udprobe(reg, ctlr)
        !           223:        caddr_t reg;
        !           224:        int ctlr;
        !           225: {
        !           226:        register int br, cvec;
        !           227:        register struct uda_softc *sc = &uda_softc[ctlr];
        !           228:        struct udadevice *udaddr;
        !           229: 
        !           230:        int     cur_time;
        !           231: 
        !           232: #ifdef lint
        !           233:        br = 0; cvec = br; br = cvec;
        !           234:        udreset(0); udintr(0);
        !           235: #endif
        !           236:        udaddr = (struct udadevice *) reg;
        !           237: 
        !           238:        sc->sc_ivec = (uba_hd[numuba].uh_lastiv -= 4);
        !           239: #if VAX630
        !           240:        if (cpu == VAX_630) {
        !           241:                br = 0x15;
        !           242:                cvec = sc->sc_ivec;
        !           243:                return(sizeof (struct udadevice));
        !           244:        }
        !           245: #endif
        !           246:        udaddr->udaip = 0;              /* start initialization */
        !           247: 
        !           248:        cur_time = mfpr(TODR);                  /* Time of day */
        !           249:        while(cur_time + TENSEC > mfpr(TODR)){  /* wait for at most 10 secs */
        !           250:                if((udaddr->udasa & UDA_STEP1) != 0)
        !           251:                        break;
        !           252:        }
        !           253:        if(cur_time + TENSEC <= mfpr(TODR))
        !           254:                return(0);              /* Not a uda or it won't init as it  */
        !           255:                                        /* should within ten seconds.  */
        !           256:        udaddr->udasa=UDA_ERR|(NCMDL2<<11)|(NRSPL2<<8)|UDA_IE|(sc->sc_ivec/4);
        !           257:        while((udaddr->udasa&UDA_STEP2)==0)
        !           258:                DELAY(1000);            /* intr should have */
        !           259:                                        /*   have happened by now */
        !           260:        
        !           261:        return(sizeof (struct udadevice));
        !           262: }
        !           263: 
        !           264: /* ARGSUSED */
        !           265: udslave(ui, reg)
        !           266:        struct uba_device *ui;
        !           267:        caddr_t reg;
        !           268: {
        !           269:        register struct uba_ctlr *um = udminfo[ui->ui_ctlr];
        !           270:        register struct uda_softc *sc = &uda_softc[ui->ui_ctlr];
        !           271:        struct udadevice *udaddr;
        !           272:        struct  mscp    *mp;
        !           273:        int     i;                      /* Something to write into to start */
        !           274:                                        /* the uda polling */
        !           275: 
        !           276: 
        !           277:        udaddr = (struct udadevice *)um->um_addr;
        !           278:        if(sc->sc_state != S_RUN){
        !           279:                if(!udinit(ui->ui_ctlr))
        !           280:                        return(0);
        !           281:        }
        !           282:        /* Here we will wait for the controller */
        !           283:        /* to come into the run state or go idle.  If we go idle we are in */
        !           284:        /* touble and I don't yet know what to do so I will punt */
        !           285:        while(sc->sc_state != S_RUN && sc->sc_state != S_IDLE); /* spin */
        !           286:        if(sc->sc_state == S_IDLE){     /* The Uda failed to initialize */
        !           287:                printf("UDA failed to init\n");
        !           288:                return(0);
        !           289:        }
        !           290:        /* The controller is up so let see if the drive is there! */
        !           291:        if(0 == (mp = udgetcp(um))){    /* ditto */
        !           292:                printf("UDA can't get command packet\n");
        !           293:                return(0);
        !           294:        }
        !           295:        mp->mscp_opcode = M_OP_GTUNT;   /* This should give us the drive type*/
        !           296:        mp->mscp_unit = ui->ui_slave;
        !           297:        mp->mscp_cmdref = (long) ui->ui_slave;
        !           298: #ifdef DEBUG
        !           299:        printd("uda%d Get unit status slave %d\n",ui->ui_ctlr,ui->ui_slave);
        !           300: #endif 
        !           301:        ra_info[ui->ui_unit].rastatus = 0;      /* set to zero */
        !           302:        udip[ui->ui_ctlr][ui->ui_slave] = ui;
        !           303:        *((long *) mp->mscp_dscptr ) |= UDA_OWN | UDA_INT;/* maybe we should poll*/
        !           304:        i = udaddr->udaip;
        !           305: #ifdef lint
        !           306:        i = i;
        !           307: #endif
        !           308:        while(!ra_info[ui->ui_unit].rastatus);  /* Wait for some status */
        !           309:        udip[ui->ui_ctlr][ui->ui_slave] = 0;
        !           310:        if(!ra_info[ui->ui_unit].ratype)        /* packet from a GTUNT */
        !           311:                return(0);              /* Failed No such drive */
        !           312:        else
        !           313:                return(1);              /* Got it and it is there */
        !           314: }
        !           315: 
        !           316: udattach(ui)
        !           317:        register struct uba_device *ui;
        !           318: {
        !           319:        register struct uba_ctlr *um = ui->ui_mi ;
        !           320:        struct udadevice *udaddr = (struct udadevice *) um->um_addr;
        !           321:        struct  mscp    *mp;
        !           322:        int     i;                      /* Something to write into to start */
        !           323:                                        /* the uda polling */
        !           324:        if (ui->ui_dk >= 0)
        !           325:                dk_mspw[ui->ui_dk] = 1.0 / (60 * 31 * 256);     /* approx */
        !           326:        ui->ui_flags = 0;
        !           327:        udip[ui->ui_ctlr][ui->ui_slave] = ui;
        !           328:        /* check to see if the drive is a available if it is bring it online */
        !           329:        /* if not then just return.  open will try an online later */
        !           330:        if(ra_info[ui->ui_unit].rastatus != M_ST_AVLBL)
        !           331:                return;                 /* status was set by a GTUNT */
        !           332:        if(0 == (mp = udgetcp(um))){    /* ditto */
        !           333:                printf("UDA can't get command packet\n");
        !           334:                return;
        !           335:        }
        !           336:        mp->mscp_opcode = M_OP_ONLIN;
        !           337:        mp->mscp_unit = ui->ui_slave;
        !           338:        mp->mscp_cmdref = (long) ui->ui_slave;
        !           339: #ifdef DEBUG
        !           340:        printd("uda%d ONLIN slave %d\n",ui->ui_ctlr,ui->ui_slave);
        !           341: #endif 
        !           342:        *((long *) mp->mscp_dscptr ) |= UDA_OWN | UDA_INT;
        !           343:        i = udaddr->udaip;
        !           344: #ifdef lint
        !           345:        i = i;
        !           346: #endif
        !           347:        while(ui->ui_flags == 0 && ra_info[ui->ui_unit].ratype != 0);
        !           348: }
        !           349: 
        !           350: /*
        !           351:  * Open a UDA.  Initialize the device and
        !           352:  * set the unit online.
        !           353:  */
        !           354: /* ARGSUSED */
        !           355: udopen(dev, flag)
        !           356:        dev_t dev;
        !           357:        int flag;
        !           358: {
        !           359:        register int unit;
        !           360:        register struct uba_device *ui;
        !           361:        register struct uda_softc *sc;
        !           362:        register struct mscp *mp;
        !           363:        register struct uba_ctlr *um;
        !           364:        struct udadevice *udaddr;
        !           365:        int s,i;
        !           366:        
        !           367:        unit = udunit(dev);
        !           368:        if (unit >= NRA || (ui = uddinfo[unit]) == 0 || ui->ui_alive == 0)
        !           369:                return (ENXIO);
        !           370:        sc = &uda_softc[ui->ui_ctlr];
        !           371:        s = spl5();
        !           372:        if (sc->sc_state != S_RUN) {
        !           373:                if (sc->sc_state == S_IDLE)
        !           374:                        if(!udinit(ui->ui_ctlr)){
        !           375:                                printf("uda: Controller failed to init\n");
        !           376:                                (void) splx(s);
        !           377:                                return(ENXIO);
        !           378:                        }
        !           379:                /* wait for initialization to complete */
        !           380:                timeout(wakeup,(caddr_t)ui->ui_mi,11*hz);       /* to be sure*/
        !           381:                sleep((caddr_t)ui->ui_mi, 0);
        !           382:                if (sc->sc_state != S_RUN)
        !           383:                {
        !           384:                        (void) splx(s); /* added by Rich */
        !           385:                        return (EIO);
        !           386:                }
        !           387:        }
        !           388:        /* check to see if the device is really there. */
        !           389:        /* this code was taken from Fred Canters 11 driver */
        !           390:        um = ui->ui_mi;
        !           391:        udaddr = (struct udadevice *) um->um_addr;
        !           392:        (void) splx(s);
        !           393:        if(ui->ui_flags == 0){
        !           394:                s = spl5();
        !           395:                while(0 ==(mp = udgetcp(um))){
        !           396:                        uda_cp_wait++;
        !           397:                        sleep((caddr_t)&uda_cp_wait,PSWP+1);
        !           398:                        uda_cp_wait--;
        !           399:                }
        !           400:                mp->mscp_opcode = M_OP_ONLIN;
        !           401:                mp->mscp_unit = ui->ui_slave;
        !           402:                mp->mscp_cmdref = (long) & ra_info[ui->ui_unit].ratype;
        !           403:                        /* need to sleep on something */
        !           404: #ifdef DEBUG
        !           405:                printd("uda: bring unit %d online\n",ui->ui_unit);
        !           406: #endif 
        !           407:                *((long *) mp->mscp_dscptr ) |= UDA_OWN | UDA_INT ;
        !           408:                i = udaddr->udaip;
        !           409: #ifdef lint
        !           410:                i = i;
        !           411: #endif
        !           412:                timeout(wakeup,(caddr_t) mp->mscp_cmdref,10 * hz);
        !           413:                        /* make sure we wake up */
        !           414:                sleep((caddr_t) mp->mscp_cmdref,PSWP+1); /*wakeup in udrsp() */
        !           415:                (void) splx(s);
        !           416:        }
        !           417:        if(ui->ui_flags == 0){
        !           418:                return(ENXIO);  /* Didn't go online */
        !           419:        }
        !           420:        return (0);
        !           421: }
        !           422: 
        !           423: /*
        !           424:  * Initialize a UDA.  Set up UBA mapping registers,
        !           425:  * initialize data structures, and start hardware
        !           426:  * initialization sequence.
        !           427:  */
        !           428: udinit(d)
        !           429:        int d;
        !           430: {
        !           431:        register struct uda_softc *sc;
        !           432:        register struct uda *ud;
        !           433:        struct udadevice *udaddr;
        !           434:        struct uba_ctlr *um;
        !           435: 
        !           436:        sc = &uda_softc[d];
        !           437:        um = udminfo[d];
        !           438:        um->um_tab.b_active++;
        !           439:        ud = &uda[d];
        !           440:        udaddr = (struct udadevice *)um->um_addr;
        !           441:        if (sc->sc_mapped == 0) {
        !           442:                /*
        !           443:                 * Map the communications area and command
        !           444:                 * and response packets into Unibus address
        !           445:                 * space.
        !           446:                 */
        !           447:                sc->sc_ubainfo = uballoc(um->um_ubanum, (caddr_t)ud,
        !           448:                    sizeof (struct uda), 0);
        !           449:                sc->sc_uda = (struct uda *)(sc->sc_ubainfo & 0x3ffff);
        !           450:                sc->sc_mapped = 1;
        !           451:        }
        !           452: 
        !           453:        /*
        !           454:         * Start the hardware initialization sequence.
        !           455:         */
        !           456: 
        !           457:        if (udaburst[d] == 0)
        !           458:                udaburst[d] = UDABURST;
        !           459:        udaddr->udaip = 0;              /* start initialization */
        !           460: 
        !           461:        while((udaddr->udasa & UDA_STEP1) == 0){
        !           462:                if(udaddr->udasa & UDA_ERR)
        !           463:                        return(0);      /* CHECK */
        !           464:        }
        !           465:        udaddr->udasa=UDA_ERR|(NCMDL2<<11)|(NRSPL2<<8)|UDA_IE|(sc->sc_ivec/4);
        !           466:        /*
        !           467:         * Initialization continues in interrupt routine.
        !           468:         */
        !           469:        sc->sc_state = S_STEP1;
        !           470:        sc->sc_credits = 0;
        !           471:        return(1);
        !           472: }
        !           473: 
        !           474: udstrategy(bp)
        !           475:        register struct buf *bp;
        !           476: {
        !           477:        register struct uba_device *ui;
        !           478:        register struct uba_ctlr *um;
        !           479:        register struct buf *dp;
        !           480:        register int unit;
        !           481:        register struct size    *rasizes;
        !           482:        int xunit = minor(bp->b_dev) & 07;
        !           483:        daddr_t sz, maxsz;
        !           484:        int s;
        !           485: 
        !           486:        sz = (bp->b_bcount+511) >> 9;
        !           487:        unit = udunit(bp->b_dev);
        !           488:        if (unit >= NRA) {
        !           489:                bp->b_error = ENXIO;
        !           490:                goto bad;
        !           491:        }
        !           492:        rasizes = ra_info[unit].ra_sizes;
        !           493:        ui = uddinfo[unit];
        !           494:        um = ui->ui_mi;
        !           495:        if (ui == 0 || ui->ui_alive == 0) {
        !           496:                bp->b_error = ENXIO;
        !           497:                goto bad;
        !           498:        }
        !           499:        if ((maxsz = rasizes[xunit].nblocks) < 0)
        !           500:                maxsz = ra_info[unit].radsize - rasizes[xunit].blkoff;
        !           501:        if (bp->b_blkno < 0 || bp->b_blkno+sz > maxsz ||
        !           502:            rasizes[xunit].blkoff >= ra_info[unit].radsize) {
        !           503:                if (bp->b_blkno == maxsz) {
        !           504:                        bp->b_resid = bp->b_bcount;
        !           505:                        goto done;
        !           506:                }
        !           507:                bp->b_error = EINVAL;
        !           508:                goto bad;
        !           509:        }
        !           510:        s = spl5();
        !           511:        /*
        !           512:         * Link the buffer onto the drive queue
        !           513:         */
        !           514:        dp = &udutab[ui->ui_unit];
        !           515:        if (dp->b_actf == 0)
        !           516:                dp->b_actf = bp;
        !           517:        else
        !           518:                dp->b_actl->av_forw = bp;
        !           519:        dp->b_actl = bp;
        !           520:        bp->av_forw = 0;
        !           521:        /*
        !           522:         * Link the drive onto the controller queue
        !           523:         */
        !           524:        if (dp->b_active == 0) {
        !           525:                dp->b_forw = NULL;
        !           526:                if (um->um_tab.b_actf == NULL)
        !           527:                        um->um_tab.b_actf = dp;
        !           528:                else
        !           529:                        um->um_tab.b_actl->b_forw = dp;
        !           530:                um->um_tab.b_actl = dp;
        !           531:                dp->b_active = 1;
        !           532:        }
        !           533:        if (um->um_tab.b_active == 0) {
        !           534: #if defined(VAX750)
        !           535:                if (cpu == VAX_750
        !           536:                    && udwtab[um->um_ctlr].av_forw == &udwtab[um->um_ctlr]) {
        !           537:                        if (um->um_ubinfo != 0) {
        !           538:                                printd("udastrat: ubinfo 0x%x\n",um->um_ubinfo);
        !           539:                        } else
        !           540:                                um->um_ubinfo =
        !           541:                                   uballoc(um->um_ubanum, (caddr_t)0, 0,
        !           542:                                        UBA_NEEDBDP);
        !           543:                }
        !           544: #endif
        !           545:                (void) udstart(um);
        !           546:        }
        !           547:        splx(s);
        !           548:        return;
        !           549: 
        !           550: bad:
        !           551:        bp->b_flags |= B_ERROR;
        !           552: done:
        !           553:        iodone(bp);
        !           554:        return;
        !           555: }
        !           556: 
        !           557: udstart(um)
        !           558:        register struct uba_ctlr *um;
        !           559: {
        !           560:        register struct buf *bp, *dp;
        !           561:        register struct mscp *mp;
        !           562:        register struct uda_softc *sc;
        !           563:        register struct uba_device *ui;
        !           564:        struct  size    *rasizes;
        !           565:        struct udadevice *udaddr;
        !           566:        struct  uda     *ud = &uda[um->um_ctlr];
        !           567:        int i;
        !           568: 
        !           569:        sc = &uda_softc[um->um_ctlr];
        !           570:        
        !           571: loop:
        !           572:        if ((dp = um->um_tab.b_actf) == NULL) {
        !           573:                /*
        !           574:                 * Release uneeded UBA resources and return
        !           575:                 */
        !           576:                um->um_tab.b_active = 0;
        !           577:                /* Check for response ring transitions lost in the
        !           578:                 * Race condition
        !           579:                 */
        !           580:                for (i = sc->sc_lastrsp;; i++) {
        !           581:                        i %= NRSP;
        !           582:                        if (ud->uda_ca.ca_rspdsc[i]&UDA_OWN)
        !           583:                                break;
        !           584:                        udrsp(um, ud, sc, i);
        !           585:                        ud->uda_ca.ca_rspdsc[i] |= UDA_OWN;
        !           586:                }
        !           587:                sc->sc_lastrsp = i;
        !           588:                return (0);
        !           589:        }
        !           590:        if ((bp = dp->b_actf) == NULL) {
        !           591:                /*
        !           592:                 * No more requests for this drive, remove
        !           593:                 * from controller queue and look at next drive.
        !           594:                 * We know we're at the head of the controller queue.
        !           595:                 */
        !           596:                dp->b_active = 0;
        !           597:                um->um_tab.b_actf = dp->b_forw;
        !           598:                goto loop;              /* Need to check for loop */
        !           599:        }
        !           600:        um->um_tab.b_active++;
        !           601:        udaddr = (struct udadevice *)um->um_addr;
        !           602:        if ((udaddr->udasa&UDA_ERR) || sc->sc_state != S_RUN) {
        !           603:                harderr(bp, "ra");
        !           604:                mprintf("Uda%d udasa %o, state %d\n",um->um_ctlr , udaddr->udasa&0xffff, sc->sc_state);
        !           605:                (void)udinit(um->um_ctlr);
        !           606:                /* SHOULD REQUEUE OUTSTANDING REQUESTS, LIKE UDRESET */
        !           607:                return (0);
        !           608:        }
        !           609:        ui = uddinfo[udunit(bp->b_dev)];
        !           610:        rasizes = ra_info[ui->ui_unit].ra_sizes;
        !           611:        if (ui->ui_flags == 0) {        /* not online */
        !           612:                if ((mp = udgetcp(um)) == NULL){
        !           613:                        return (0);
        !           614:                }
        !           615:                mp->mscp_opcode = M_OP_ONLIN;
        !           616:                mp->mscp_unit = ui->ui_slave;
        !           617:                dp->b_active = 2;
        !           618:                um->um_tab.b_actf = dp->b_forw; /* remove from controller q */
        !           619: #ifdef DEBUG
        !           620:                printd("uda: bring unit %d online\n", ui->ui_slave);
        !           621: #endif         
        !           622:                *((long *)mp->mscp_dscptr) |= UDA_OWN|UDA_INT;
        !           623:                if (udaddr->udasa&UDA_ERR)
        !           624:                        printf("Uda (%d) Error (%x)\n",um->um_ctlr , udaddr->udasa&0xffff);
        !           625:                i = udaddr->udaip;
        !           626:                goto loop;
        !           627:        }
        !           628:        switch (cpu) {
        !           629:        case VAX_8600:
        !           630:        case VAX_780:
        !           631:                i = UBA_NEEDBDP|UBA_CANTWAIT;
        !           632:                break;
        !           633: 
        !           634:        case VAX_750:
        !           635:                i = um->um_ubinfo|UBA_HAVEBDP|UBA_CANTWAIT;
        !           636:                break;
        !           637: 
        !           638:        case VAX_730:
        !           639:        case VAX_630:
        !           640:                i = UBA_CANTWAIT;
        !           641:                break;
        !           642:        }
        !           643:        if ((i = ubasetup(um->um_ubanum, bp, i)) == 0)
        !           644:                return(1);
        !           645:        if ((mp = udgetcp(um)) == NULL) {
        !           646: #if defined(VAX750)
        !           647:                if (cpu == VAX_750)
        !           648:                        i &= 0xfffffff;         /* mask off bdp */
        !           649: #endif
        !           650:                ubarelse(um->um_ubanum,&i);
        !           651:                return(0);
        !           652:        }
        !           653:        mp->mscp_cmdref = (long)bp;     /* pointer to get back */
        !           654:        mp->mscp_opcode = bp->b_flags&B_READ ? M_OP_READ : M_OP_WRITE;
        !           655:        mp->mscp_unit = ui->ui_slave;
        !           656:        mp->mscp_lbn = bp->b_blkno + rasizes[minor(bp->b_dev)&7].blkoff;
        !           657:        mp->mscp_bytecnt = bp->b_bcount;
        !           658:        mp->mscp_buffer = (i & 0x3ffff) | (((i>>28)&0xf)<<24);
        !           659: #if defined(VAX750)
        !           660:        if (cpu == VAX_750)
        !           661:                i &= 0xfffffff;         /* mask off bdp */
        !           662: #endif
        !           663:        bp->b_ubinfo = i;               /* save mapping info */
        !           664:        *((long *)mp->mscp_dscptr) |= UDA_OWN|UDA_INT;
        !           665:        if (udaddr->udasa&UDA_ERR) 
        !           666:                printf("Uda(%d) udasa (%x)\n",um->um_ctlr , udaddr->udasa&0xffff);
        !           667:        i = udaddr->udaip;              /* initiate polling */
        !           668:        dp->b_qsize++;
        !           669:        if (ui->ui_dk >= 0) {
        !           670:                dk_busy |= 1<<ui->ui_dk;
        !           671:                dk_xfer[ui->ui_dk]++;
        !           672:                dk_wds[ui->ui_dk] += bp->b_bcount>>6;
        !           673:        }
        !           674: 
        !           675:        /*
        !           676:         * Move drive to the end of the controller queue
        !           677:         */
        !           678:        if (dp->b_forw != NULL) {
        !           679:                um->um_tab.b_actf = dp->b_forw;
        !           680:                um->um_tab.b_actl->b_forw = dp;
        !           681:                um->um_tab.b_actl = dp;
        !           682:                dp->b_forw = NULL;
        !           683:        }
        !           684:        /*
        !           685:         * Move buffer to I/O wait queue
        !           686:         */
        !           687:        dp->b_actf = bp->av_forw;
        !           688:        dp = &udwtab[um->um_ctlr];
        !           689:        bp->av_forw = dp;
        !           690:        bp->av_back = dp->av_back;
        !           691:        dp->av_back->av_forw = bp;
        !           692:        dp->av_back = bp;
        !           693:        goto loop;
        !           694: }
        !           695: 
        !           696: /*
        !           697:  * UDA interrupt routine.
        !           698:  */
        !           699: udintr(d)
        !           700:        int d;
        !           701: {
        !           702:        register struct uba_ctlr *um = udminfo[d];
        !           703:        register struct udadevice *udaddr = (struct udadevice *)um->um_addr;
        !           704:        struct buf *bp;
        !           705:        register int i;
        !           706:        register struct uda_softc *sc = &uda_softc[d];
        !           707:        register struct uda *ud = &uda[d];
        !           708:        struct uda *uud;
        !           709:        struct mscp *mp;
        !           710: 
        !           711: #ifdef DEBUG
        !           712:        printd10("udintr: state %d, udasa %o\n", sc->sc_state, udaddr->udasa);
        !           713: #endif 
        !           714: #ifdef VAX630
        !           715:        (void) spl5();
        !           716: #endif
        !           717:        switch (sc->sc_state) {
        !           718:        case S_IDLE:
        !           719:                printf("uda%d: random interrupt ignored\n", d);
        !           720:                return;
        !           721: 
        !           722:        case S_STEP1:
        !           723: #define STEP1MASK       0174377
        !           724: #define STEP1GOOD       (UDA_STEP2|UDA_IE|(NCMDL2<<3)|NRSPL2)
        !           725:                if ((udaddr->udasa&STEP1MASK) != STEP1GOOD) {
        !           726:                        sc->sc_state = S_IDLE;
        !           727:                        wakeup((caddr_t)um);
        !           728:                        return;
        !           729:                }
        !           730:                udaddr->udasa = ((int)&sc->sc_uda->uda_ca.ca_ringbase)|
        !           731:                    ((cpu == VAX_780) || (cpu == VAX_8600) ? UDA_PI : 0);
        !           732:                sc->sc_state = S_STEP2;
        !           733:                return;
        !           734: 
        !           735:        case S_STEP2:
        !           736: #define STEP2MASK       0174377
        !           737: #define STEP2GOOD       (UDA_STEP3|UDA_IE|(sc->sc_ivec/4))
        !           738:                if ((udaddr->udasa&STEP2MASK) != STEP2GOOD) {
        !           739:                        sc->sc_state = S_IDLE;
        !           740:                        wakeup((caddr_t)um);
        !           741:                        return;
        !           742:                }
        !           743:                udaddr->udasa = ((int)&sc->sc_uda->uda_ca.ca_ringbase)>>16;
        !           744:                sc->sc_state = S_STEP3;
        !           745:                return;
        !           746: 
        !           747:        case S_STEP3:
        !           748: #define STEP3MASK       0174000
        !           749: #define STEP3GOOD       UDA_STEP4
        !           750:                if ((udaddr->udasa&STEP3MASK) != STEP3GOOD) {
        !           751:                        sc->sc_state = S_IDLE;
        !           752:                        wakeup((caddr_t)um);
        !           753:                        return;
        !           754:                }
        !           755:                udamicro[d] = udaddr->udasa;
        !           756: #ifdef DEBUG
        !           757:                printd("Uda%d Version %d model %d\n",d,udamicro[d]&0xF,
        !           758:                        (udamicro[d]>>4) & 0xF);
        !           759: #endif
        !           760:                /*
        !           761:                 * Requesting the error status (|= 2)
        !           762:                 * may hang older controllers.
        !           763:                 */
        !           764:                i = UDA_GO | (udaerror? 2 : 0);
        !           765:                if (udaburst[d])
        !           766:                        i |= (udaburst[d] - 1) << 2;
        !           767:                udaddr->udasa = i;
        !           768:                udaddr->udasa = UDA_GO;
        !           769:                sc->sc_state = S_SCHAR;
        !           770: 
        !           771:                /*
        !           772:                 * Initialize the data structures.
        !           773:                 */
        !           774:                uud = sc->sc_uda;
        !           775:                for (i = 0; i < NRSP; i++) {
        !           776:                        ud->uda_ca.ca_rspdsc[i] = UDA_OWN|UDA_INT|
        !           777:                                (long)&uud->uda_rsp[i].mscp_cmdref;
        !           778:                        ud->uda_rsp[i].mscp_dscptr = &ud->uda_ca.ca_rspdsc[i];
        !           779:                        ud->uda_rsp[i].mscp_header.uda_msglen = mscp_msglen;
        !           780:                }
        !           781:                for (i = 0; i < NCMD; i++) {
        !           782:                        ud->uda_ca.ca_cmddsc[i] = UDA_INT|
        !           783:                                (long)&uud->uda_cmd[i].mscp_cmdref;
        !           784:                        ud->uda_cmd[i].mscp_dscptr = &ud->uda_ca.ca_cmddsc[i];
        !           785:                        ud->uda_cmd[i].mscp_header.uda_msglen = mscp_msglen;
        !           786:                }
        !           787:                bp = &udwtab[d];
        !           788:                bp->av_forw = bp->av_back = bp;
        !           789:                sc->sc_lastcmd = 1;
        !           790:                sc->sc_lastrsp = 0;
        !           791:                mp = &uda[um->um_ctlr].uda_cmd[0];
        !           792:                mp->mscp_unit = mp->mscp_modifier = 0;
        !           793:                mp->mscp_flags = 0;
        !           794:                mp->mscp_bytecnt = mp->mscp_buffer = 0;
        !           795:                mp->mscp_errlgfl = mp->mscp_copyspd = 0;
        !           796:                mp->mscp_opcode = M_OP_STCON;
        !           797:                mp->mscp_cntflgs = M_CF_ATTN|M_CF_MISC|M_CF_THIS;
        !           798:                *((long *)mp->mscp_dscptr) |= UDA_OWN|UDA_INT;
        !           799:                i = udaddr->udaip;      /* initiate polling */
        !           800:                return;
        !           801: 
        !           802:        case S_SCHAR:
        !           803:        case S_RUN:
        !           804:                break;
        !           805: 
        !           806:        default:
        !           807:                printf("uda%d: interrupt in unknown state %d ignored\n",
        !           808:                        d, sc->sc_state);
        !           809:                return;
        !           810:        }
        !           811: 
        !           812:        if (udaddr->udasa&UDA_ERR) {
        !           813:                printf("uda(%d): fatal error (%o)\n", d, udaddr->udasa&0xffff);
        !           814:                udaddr->udaip = 0;
        !           815:                wakeup((caddr_t)um);
        !           816:        }
        !           817: 
        !           818:        /*
        !           819:         * Check for a buffer purge request.
        !           820:         */
        !           821:        if (ud->uda_ca.ca_bdp) {
        !           822: #ifdef DEBUG
        !           823:                printd("uda: purge bdp %d\n", ud->uda_ca.ca_bdp);
        !           824: #endif         
        !           825:                UBAPURGE(um->um_hd->uh_uba, ud->uda_ca.ca_bdp);
        !           826:                ud->uda_ca.ca_bdp = 0;
        !           827:                udaddr->udasa = 0;      /* signal purge complete */
        !           828:        }
        !           829: 
        !           830:        /*
        !           831:         * Check for response ring transition.
        !           832:         */
        !           833:        if (ud->uda_ca.ca_rspint) {
        !           834:                ud->uda_ca.ca_rspint = 0;
        !           835:                for (i = sc->sc_lastrsp;; i++) {
        !           836:                        i %= NRSP;
        !           837:                        if (ud->uda_ca.ca_rspdsc[i]&UDA_OWN)
        !           838:                                break;
        !           839:                        udrsp(um, ud, sc, i);
        !           840:                        ud->uda_ca.ca_rspdsc[i] |= UDA_OWN;
        !           841:                }
        !           842:                sc->sc_lastrsp = i;
        !           843:        }
        !           844: 
        !           845:        /*
        !           846:         * Check for command ring transition.
        !           847:         */
        !           848:        if (ud->uda_ca.ca_cmdint) {
        !           849: #ifdef DEBUG
        !           850:                printd("uda: command ring transition\n");
        !           851: #endif         
        !           852:                ud->uda_ca.ca_cmdint = 0;
        !           853:        }
        !           854:        if(uda_cp_wait)
        !           855:                wakeup((caddr_t)&uda_cp_wait);
        !           856:        (void) udstart(um);
        !           857: }
        !           858: 
        !           859: /*
        !           860:  * Process a response packet
        !           861:  */
        !           862: udrsp(um, ud, sc, i)
        !           863:        register struct uba_ctlr *um;
        !           864:        register struct uda *ud;
        !           865:        register struct uda_softc *sc;
        !           866:        int i;
        !           867: {
        !           868:        register struct mscp *mp;
        !           869:        struct uba_device *ui;
        !           870:        struct buf *dp, *bp,nullbp;
        !           871:        int st;
        !           872: 
        !           873:        mp = &ud->uda_rsp[i];
        !           874:        mp->mscp_header.uda_msglen = mscp_msglen;
        !           875:        sc->sc_credits += mp->mscp_header.uda_credits & 0xf;  /* just 4 bits?*/
        !           876:        if ((mp->mscp_header.uda_credits & 0xf0) > 0x10)        /* Check */
        !           877:                return;
        !           878: #ifdef DEBUG
        !           879:        printd10("udarsp, opcode 0x%x status 0x%x\n",mp->mscp_opcode,mp->mscp_status);
        !           880: #endif 
        !           881:        /*
        !           882:         * If it's an error log message (datagram),
        !           883:         * pass it on for more extensive processing.
        !           884:         */
        !           885:        if ((mp->mscp_header.uda_credits & 0xf0) == 0x10) {     /* check */
        !           886:                uderror(um, (struct mslg *)mp);
        !           887:                return;
        !           888:        }
        !           889:        st = mp->mscp_status&M_ST_MASK;
        !           890:        /* The controller interrupts as drive 0 */
        !           891:        /* this means that you must check for controller interrupts */
        !           892:        /* before you check to see if there is a drive 0 */
        !           893:        if((M_OP_STCON|M_OP_END) == mp->mscp_opcode){
        !           894:                if (st == M_ST_SUCC)
        !           895:                        sc->sc_state = S_RUN;
        !           896:                else
        !           897:                        sc->sc_state = S_IDLE;
        !           898:                um->um_tab.b_active = 0;
        !           899:                wakeup((caddr_t)um);
        !           900:                return;
        !           901:        }
        !           902:        if (mp->mscp_unit >= 8)
        !           903:                return;
        !           904:        if ((ui = udip[um->um_ctlr][mp->mscp_unit]) == 0)
        !           905:                return;
        !           906:        switch (mp->mscp_opcode) {
        !           907: 
        !           908:        case M_OP_ONLIN|M_OP_END:
        !           909:                ra_info[ui->ui_unit].rastatus = st;
        !           910:                ra_info[ui->ui_unit].ratype =  mp->mscp_mediaid;
        !           911:                dp = &udutab[ui->ui_unit];
        !           912:                if (st == M_ST_SUCC) {
        !           913:                        /*
        !           914:                         * Link the drive onto the controller queue
        !           915:                         */
        !           916:                        dp->b_forw = NULL;
        !           917:                        if (um->um_tab.b_actf == NULL)
        !           918:                                um->um_tab.b_actf = dp;
        !           919:                        else
        !           920:                                um->um_tab.b_actl->b_forw = dp;
        !           921:                        um->um_tab.b_actl = dp;
        !           922:                        ui->ui_flags = 1;       /* mark it online */
        !           923:                        ra_info[ui->ui_unit].radsize=(daddr_t)mp->mscp_untsize;
        !           924: #ifdef DEBUG
        !           925:                        printd("uda: unit %d online\n", mp->mscp_unit);
        !           926: #endif                 
        !           927: #define F_to_C(x,i)     ( ((x)->mscp_mediaid) >> (i*5+7) & 0x1f ? ( ( (((x)->mscp_mediaid) >>( i*5 + 7)) & 0x1f) + 'A' - 1): ' ')
        !           928:                /* this mess decodes the Media type identifier */
        !           929: #ifdef DEBUG
        !           930:                        printd("uda: unit %d online %x %c%c %c%c%c%d\n"
        !           931:                                ,mp->mscp_unit, mp->mscp_mediaid
        !           932:                                ,F_to_C(mp,4),F_to_C(mp,3),F_to_C(mp,2)
        !           933:                                ,F_to_C(mp,1),F_to_C(mp,0)
        !           934:                                ,mp->mscp_mediaid & 0x7f);
        !           935: #endif                         
        !           936:                        switch((int)(mp->mscp_mediaid & 0x7f)){
        !           937:                        case    25:
        !           938:                                ra_info[ui->ui_unit].ra_sizes = ra25_sizes;
        !           939:                                break;
        !           940:                        case    52:
        !           941:                                ra_info[ui->ui_unit].ra_sizes = rd52_sizes;
        !           942:                                break;
        !           943:                        case    53:
        !           944:                                ra_info[ui->ui_unit].ra_sizes = rd53_sizes;
        !           945:                                break;
        !           946:                        case    60:
        !           947:                                ra_info[ui->ui_unit].ra_sizes = ra60_sizes;
        !           948:                                break;
        !           949:                        case    80:
        !           950:                                ra_info[ui->ui_unit].ra_sizes = ra80_sizes;
        !           951:                                break;
        !           952:                        case    81:
        !           953:                                ra_info[ui->ui_unit].ra_sizes = ra81_sizes;
        !           954:                                break;
        !           955:                        default:
        !           956:                                ui->ui_flags = 0;       /* mark it offline */
        !           957:                                ra_info[ui->ui_unit].ratype = 0;
        !           958:                                printf("Don't have a parition table for ");
        !           959:                                printf("a %c%c %c%c%c%d\n"
        !           960:                                ,F_to_C(mp,4),F_to_C(mp,3),F_to_C(mp,2)
        !           961:                                ,F_to_C(mp,1),F_to_C(mp,0)
        !           962:                                ,mp->mscp_mediaid & 0x7f);
        !           963:                                while (bp = dp->b_actf) {
        !           964:                                        dp->b_actf = bp->av_forw;
        !           965:                                        bp->b_flags |= B_ERROR;
        !           966:                                        iodone(bp);
        !           967:                                }
        !           968:                        }
        !           969:                        dp->b_active = 1;
        !           970:                } else {
        !           971:                        if(dp->b_actf){
        !           972:                                harderr(dp->b_actf,"ra");
        !           973:                        } else {
        !           974:                                nullbp.b_blkno = 0;
        !           975:                                nullbp.b_dev = makedev(UDADEVNUM,ui->ui_unit);
        !           976:                                harderr(&nullbp, "ra");
        !           977:                        }
        !           978:                        printf("OFFLINE\n");
        !           979:                        while (bp = dp->b_actf) {
        !           980:                                dp->b_actf = bp->av_forw;
        !           981:                                bp->b_flags |= B_ERROR;
        !           982:                                iodone(bp);
        !           983:                        }
        !           984:                }
        !           985:                if(mp->mscp_cmdref!=NULL){/* Seems to get lost sometimes */
        !           986:                        wakeup((caddr_t)mp->mscp_cmdref);
        !           987:                }
        !           988:                break;
        !           989: 
        !           990: /*
        !           991:  * The AVAILABLE ATTENTION messages occurs when the
        !           992:  * unit becomes available after spinup,
        !           993:  * marking the unit offline will force an online command
        !           994:  * prior to using the unit.
        !           995:  */
        !           996:        case M_OP_AVATN:
        !           997: #ifdef DEBUG
        !           998:                printd("uda: unit %d attention\n", mp->mscp_unit);
        !           999: #endif         
        !          1000:                ui->ui_flags = 0;       /* it went offline and we didn't notice */
        !          1001:                ra_info[ui->ui_unit].ratype =  mp->mscp_mediaid;
        !          1002:                break;
        !          1003: 
        !          1004:        case M_OP_END:
        !          1005: /*
        !          1006:  * An endcode without an opcode (0200) is an invalid command.
        !          1007:  * The mscp specification states that this would be a protocol
        !          1008:  * type error, such as illegal opcodes. The mscp spec. also
        !          1009:  * states that parameter error type of invalid commands should
        !          1010:  * return the normal end message for the command. This does not appear
        !          1011:  * to be the case. An invalid logical block number returned an endcode
        !          1012:  * of 0200 instead of the 0241 (read) that was expected.
        !          1013:  */
        !          1014:        
        !          1015:                printf("endcd=%o, stat=%o\n", mp->mscp_opcode, mp->mscp_status);
        !          1016:                break;
        !          1017:        case M_OP_READ|M_OP_END:
        !          1018:        case M_OP_WRITE|M_OP_END:
        !          1019:                bp = (struct buf *)mp->mscp_cmdref;
        !          1020:                ubarelse(um->um_ubanum, (int *)&bp->b_ubinfo);
        !          1021:                /*
        !          1022:                 * Unlink buffer from I/O wait queue.
        !          1023:                 */
        !          1024:                bp->av_back->av_forw = bp->av_forw;
        !          1025:                bp->av_forw->av_back = bp->av_back;
        !          1026: #if defined(VAX750)
        !          1027:                if (cpu == VAX_750 && um->um_tab.b_active == 0
        !          1028:                    && udwtab[um->um_ctlr].av_forw == &udwtab[um->um_ctlr]) {
        !          1029:                        if (um->um_ubinfo == 0)
        !          1030:                                printf("udintr: um_ubinfo == 0\n");
        !          1031:                        else
        !          1032:                                ubarelse(um->um_ubanum, &um->um_ubinfo);
        !          1033:                }
        !          1034: #endif
        !          1035:                dp = &udutab[ui->ui_unit];
        !          1036:                dp->b_qsize--;
        !          1037:                if (ui->ui_dk >= 0)
        !          1038:                        if (dp->b_qsize == 0)
        !          1039:                                dk_busy &= ~(1<<ui->ui_dk);
        !          1040:                if (st == M_ST_OFFLN || st == M_ST_AVLBL) {
        !          1041:                        ui->ui_flags = 0;       /* mark unit offline */
        !          1042:                        /*
        !          1043:                         * Link the buffer onto the front of the drive queue
        !          1044:                         */
        !          1045:                        if ((bp->av_forw = dp->b_actf) == 0)
        !          1046:                                dp->b_actl = bp;
        !          1047:                        dp->b_actf = bp;
        !          1048:                        /*
        !          1049:                         * Link the drive onto the controller queue
        !          1050:                         */
        !          1051:                        if (dp->b_active == 0) {
        !          1052:                                dp->b_forw = NULL;
        !          1053:                                if (um->um_tab.b_actf == NULL)
        !          1054:                                        um->um_tab.b_actf = dp;
        !          1055:                                else
        !          1056:                                        um->um_tab.b_actl->b_forw = dp;
        !          1057:                                um->um_tab.b_actl = dp;
        !          1058:                                dp->b_active = 1;
        !          1059:                        }
        !          1060: #if defined(VAX750)
        !          1061:                        if (cpu == VAX750 && um->um_ubinfo == 0)
        !          1062:                                um->um_ubinfo =
        !          1063:                                   uballoc(um->um_ubanum, (caddr_t)0, 0,
        !          1064:                                        UBA_NEEDBDP);
        !          1065: #endif
        !          1066:                        return;
        !          1067:                }
        !          1068:                if (st != M_ST_SUCC) {
        !          1069:                        harderr(bp, "ra");
        !          1070: #ifdef DEBUG
        !          1071:                        printd("status %o\n", mp->mscp_status);
        !          1072: #endif
        !          1073:                        bp->b_flags |= B_ERROR;
        !          1074:                }
        !          1075:                bp->b_resid = bp->b_bcount - mp->mscp_bytecnt;
        !          1076:                iodone(bp);
        !          1077:                break;
        !          1078: 
        !          1079:        case M_OP_GTUNT|M_OP_END:
        !          1080: #ifdef DEBUG
        !          1081:                printd("GTUNT end packet status = 0x%x media id 0x%x\n"
        !          1082:                        ,st,mp->mscp_mediaid);
        !          1083: #endif         
        !          1084:                ra_info[ui->ui_unit].rastatus = st;
        !          1085:                ra_info[ui->ui_unit].ratype =  mp->mscp_mediaid;
        !          1086:                break;
        !          1087: 
        !          1088:        default:
        !          1089:                printf("uda: unknown packet\n");
        !          1090:                uderror(um, (struct mslg *)mp);
        !          1091:        }
        !          1092: }
        !          1093: 
        !          1094: 
        !          1095: /*
        !          1096:  * Process an error log message
        !          1097:  *
        !          1098:  * For now, just log the error on the console.
        !          1099:  * Only minimal decoding is done, only "useful"
        !          1100:  * information is printed.  Eventually should
        !          1101:  * send message to an error logger.
        !          1102:  */
        !          1103: uderror(um, mp)
        !          1104:        register struct uba_ctlr *um;
        !          1105:        register struct mslg *mp;
        !          1106: {
        !          1107:        register        i;
        !          1108: 
        !          1109: 
        !          1110:        if(!(mp->mslg_flags & (M_LF_SUCC | M_LF_CONT)))
        !          1111:                printf("uda%d: hard error\n");
        !          1112: 
        !          1113:        mprintf("uda%d: %s error, ", um->um_ctlr,
        !          1114:                mp->mslg_flags & ( M_LF_SUCC | M_LF_CONT ) ? "soft" : "hard");
        !          1115:        switch (mp->mslg_format) {
        !          1116:        case M_FM_CNTERR:
        !          1117:                mprintf("controller error, event 0%o\n", mp->mslg_event);
        !          1118:                break;
        !          1119: 
        !          1120:        case M_FM_BUSADDR:
        !          1121:                mprintf("host memory access error, event 0%o, addr 0%o\n",
        !          1122:                        mp->mslg_event, mp->mslg_busaddr);
        !          1123:                break;
        !          1124: 
        !          1125:        case M_FM_DISKTRN:
        !          1126:                mprintf("disk transfer error, unit %d, grp 0x%x, hdr 0x%x, event 0%o\n",
        !          1127:                        mp->mslg_unit, mp->mslg_group, mp->mslg_hdr,
        !          1128: mp->mslg_event);
        !          1129:                break;
        !          1130: 
        !          1131:        case M_FM_SDI:
        !          1132:                mprintf("SDI error, unit %d, event 0%o, hdr 0x%x\n",
        !          1133:                        mp->mslg_unit, mp->mslg_event, mp->mslg_hdr);
        !          1134:                for(i = 0; i < 12;i++)
        !          1135:                        mprintf("\t0x%x",mp->mslg_sdistat[i] & 0xff);
        !          1136:                mprintf("\n");
        !          1137:                break;
        !          1138: 
        !          1139:        case M_FM_SMLDSK:
        !          1140:                mprintf("small disk error, unit %d, event 0%o, cyl %d\n",
        !          1141:                        mp->mslg_unit, mp->mslg_event, mp->mslg_sdecyl);
        !          1142:                break;
        !          1143: 
        !          1144:        default:
        !          1145:                mprintf("unknown error, unit %d, format 0%o, event 0%o\n",
        !          1146:                        mp->mslg_unit, mp->mslg_format, mp->mslg_event);
        !          1147:        }
        !          1148: 
        !          1149:        if (udaerror) {
        !          1150:                register long *p = (long *)mp;
        !          1151: 
        !          1152:                for (i = 0; i < mp->mslg_header.uda_msglen; i += sizeof(*p))
        !          1153:                        printf("%x ", *p++);
        !          1154:                printf("\n");
        !          1155:        }
        !          1156: }
        !          1157: 
        !          1158: 
        !          1159: /*
        !          1160:  * Find an unused command packet
        !          1161:  */
        !          1162: struct mscp *
        !          1163: udgetcp(um)
        !          1164:        struct uba_ctlr *um;
        !          1165: {
        !          1166:        register struct mscp *mp;
        !          1167:        register struct udaca *cp;
        !          1168:        register struct uda_softc *sc;
        !          1169:        register int i;
        !          1170:        int     s;
        !          1171: 
        !          1172:        s = spl5();
        !          1173:        cp = &uda[um->um_ctlr].uda_ca;
        !          1174:        sc = &uda_softc[um->um_ctlr];
        !          1175:        /*
        !          1176:         * If no credits, can't issue any commands
        !          1177:         * until some outstanding commands complete.
        !          1178:         */
        !          1179:        i = sc->sc_lastcmd;
        !          1180:        if(((cp->ca_cmddsc[i]&(UDA_OWN|UDA_INT))==UDA_INT)&&
        !          1181:            (sc->sc_credits >= 2)) {
        !          1182:                sc->sc_credits--;       /* committed to issuing a command */
        !          1183:                cp->ca_cmddsc[i] &= ~UDA_INT;
        !          1184:                mp = &uda[um->um_ctlr].uda_cmd[i];
        !          1185:                mp->mscp_unit = mp->mscp_modifier = 0;
        !          1186:                mp->mscp_opcode = mp->mscp_flags = 0;
        !          1187:                mp->mscp_bytecnt = mp->mscp_buffer = 0;
        !          1188:                mp->mscp_errlgfl = mp->mscp_copyspd = 0;
        !          1189:                sc->sc_lastcmd = (i + 1) % NCMD;
        !          1190:                (void) splx(s);
        !          1191:                return(mp);
        !          1192:        }
        !          1193:        (void) splx(s);
        !          1194:        return(NULL);
        !          1195: }
        !          1196: 
        !          1197: udread(dev, uio)
        !          1198:        dev_t dev;
        !          1199:        struct uio *uio;
        !          1200: {
        !          1201:        register int unit = udunit(dev);
        !          1202: 
        !          1203:        if (unit >= NRA)
        !          1204:                return (ENXIO);
        !          1205:        return (physio(udstrategy, &rudbuf[unit], dev, B_READ, minphys, uio));
        !          1206: }
        !          1207: 
        !          1208: udwrite(dev, uio)
        !          1209:        dev_t dev;
        !          1210:        struct uio *uio;
        !          1211: {
        !          1212:        register int unit = udunit(dev);
        !          1213: 
        !          1214:        if (unit >= NRA)
        !          1215:                return (ENXIO);
        !          1216:        return (physio(udstrategy, &rudbuf[unit], dev, B_WRITE, minphys, uio));
        !          1217: }
        !          1218: 
        !          1219: udreset(uban)
        !          1220:        int uban;
        !          1221: {
        !          1222:        register struct uba_ctlr *um;
        !          1223:        register struct uba_device *ui;
        !          1224:        register struct buf *bp, *dp;
        !          1225:        register int unit;
        !          1226:        struct buf *nbp;
        !          1227:        int d;
        !          1228: 
        !          1229:        for (d = 0; d < NUDA; d++) {
        !          1230:                if ((um = udminfo[d]) == 0 || um->um_ubanum != uban ||
        !          1231:                    um->um_alive == 0)
        !          1232:                        continue;
        !          1233:                printf(" uda%d", d);
        !          1234:                um->um_tab.b_active = 0;
        !          1235:                um->um_tab.b_actf = um->um_tab.b_actl = 0;
        !          1236:                uda_softc[d].sc_state = S_IDLE;
        !          1237:                uda_softc[d].sc_mapped = 0;     /* Rich */
        !          1238:                for (unit = 0; unit < NRA; unit++) {
        !          1239:                        if ((ui = uddinfo[unit]) == 0)
        !          1240:                                continue;
        !          1241:                        if (ui->ui_alive == 0 || ui->ui_mi != um)
        !          1242:                                continue;
        !          1243:                        udutab[unit].b_active = 0;
        !          1244:                        udutab[unit].b_qsize = 0;
        !          1245:                }
        !          1246:                for (bp = udwtab[d].av_forw; bp != &udwtab[d]; bp = nbp) {
        !          1247:                        nbp = bp->av_forw;
        !          1248:                        bp->b_ubinfo = 0;
        !          1249:                        /*
        !          1250:                         * Link the buffer onto the drive queue
        !          1251:                         */
        !          1252:                        dp = &udutab[udunit(bp->b_dev)];
        !          1253:                        if (dp->b_actf == 0)
        !          1254:                                dp->b_actf = bp;
        !          1255:                        else
        !          1256:                                dp->b_actl->av_forw = bp;
        !          1257:                        dp->b_actl = bp;
        !          1258:                        bp->av_forw = 0;
        !          1259:                        /*
        !          1260:                         * Link the drive onto the controller queue
        !          1261:                         */
        !          1262:                        if (dp->b_active == 0) {
        !          1263:                                dp->b_forw = NULL;
        !          1264:                                if (um->um_tab.b_actf == NULL)
        !          1265:                                        um->um_tab.b_actf = dp;
        !          1266:                                else
        !          1267:                                        um->um_tab.b_actl->b_forw = dp;
        !          1268:                                um->um_tab.b_actl = dp;
        !          1269:                                dp->b_active = 1;
        !          1270:                        }
        !          1271:                }
        !          1272:                (void)udinit(d);
        !          1273:        }
        !          1274: }
        !          1275: 
        !          1276: #define DBSIZE 32
        !          1277: 
        !          1278: #define ca_Rspdsc       ca_rspdsc[0]
        !          1279: #define ca_Cmddsc       ca_rspdsc[1]
        !          1280: #define uda_Rsp         uda_rsp[0]
        !          1281: #define uda_Cmd         uda_cmd[0]
        !          1282: 
        !          1283: struct  uda     udad[NUDA];
        !          1284: 
        !          1285: uddump(dev)
        !          1286:        dev_t dev;
        !          1287: {
        !          1288:        struct udadevice *udaddr;
        !          1289:        struct uda *ud_ubaddr;
        !          1290:        char *start;
        !          1291:        int num, blk, unit;
        !          1292:        int maxsz;
        !          1293:        int blkoff;
        !          1294:        register struct uba_regs *uba;
        !          1295:        register struct uba_device *ui;
        !          1296:        register struct uda *udp;
        !          1297:        register struct pte *io;
        !          1298:        register int i;
        !          1299:        struct  size    *rasizes;
        !          1300:        unit = udunit(dev);
        !          1301:        if (unit >= NRA)
        !          1302:                return (ENXIO);
        !          1303: #define phys(cast, addr) ((cast)((int)addr & 0x7fffffff))
        !          1304:        ui = phys(struct uba_device *, uddinfo[unit]);
        !          1305:        if (ui->ui_alive == 0)
        !          1306:                return (ENXIO);
        !          1307:        uba = phys(struct uba_hd *, ui->ui_hd)->uh_physuba;
        !          1308:        ubainit(uba);
        !          1309:        udaddr = (struct udadevice *)ui->ui_physaddr;
        !          1310:        DELAY(2000000);
        !          1311:        udp = phys(struct uda *, &udad[ui->ui_ctlr]);
        !          1312: 
        !          1313:        num = btoc(sizeof(struct uda)) + 1;
        !          1314:        io = &uba->uba_map[NUBMREG-num];
        !          1315:        for(i = 0; i<num; i++)
        !          1316:                *(int *)io++ = UBAMR_MRV|(btop(udp)+i);
        !          1317:        ud_ubaddr = (struct uda *)(((int)udp & PGOFSET)|((NUBMREG-num)<<9));
        !          1318: 
        !          1319:        udaddr->udaip = 0;
        !          1320:        while ((udaddr->udasa & UDA_STEP1) == 0)
        !          1321:                if(udaddr->udasa & UDA_ERR) return(EFAULT);
        !          1322:        udaddr->udasa = UDA_ERR;
        !          1323:        while ((udaddr->udasa & UDA_STEP2) == 0)
        !          1324:                if(udaddr->udasa & UDA_ERR) return(EFAULT);
        !          1325:        udaddr->udasa = (short)&ud_ubaddr->uda_ca.ca_ringbase;
        !          1326:        while ((udaddr->udasa & UDA_STEP3) == 0)
        !          1327:                if(udaddr->udasa & UDA_ERR) return(EFAULT);
        !          1328:        udaddr->udasa = (short)(((int)&ud_ubaddr->uda_ca.ca_ringbase) >> 16);
        !          1329:        while ((udaddr->udasa & UDA_STEP4) == 0)
        !          1330:                if(udaddr->udasa & UDA_ERR) return(EFAULT);
        !          1331:        udaddr->udasa = UDA_GO;
        !          1332:        udp->uda_ca.ca_Rspdsc = (long)&ud_ubaddr->uda_Rsp.mscp_cmdref;
        !          1333:        udp->uda_ca.ca_Cmddsc = (long)&ud_ubaddr->uda_Cmd.mscp_cmdref;
        !          1334:        udp->uda_Cmd.mscp_cntflgs = 0;
        !          1335:        udp->uda_Cmd.mscp_version = 0;
        !          1336:        if (udcmd(M_OP_STCON, udp, udaddr) == 0) {
        !          1337:                return(EFAULT);
        !          1338:        }
        !          1339:        udp->uda_Cmd.mscp_unit = ui->ui_slave;
        !          1340:        if (udcmd(M_OP_ONLIN, udp, udaddr) == 0) {
        !          1341:                return(EFAULT);
        !          1342:        }
        !          1343: 
        !          1344:        num = maxfree;
        !          1345:        start = 0;
        !          1346:        rasizes = ra_info[ui->ui_unit].ra_sizes;
        !          1347:        maxsz = rasizes[minor(dev)&07].nblocks;
        !          1348:        blkoff = rasizes[minor(dev)&07].blkoff;
        !          1349:        if(maxsz < 0)
        !          1350:                maxsz = ra_info[unit].radsize-blkoff;
        !          1351:        if (dumplo < 0)
        !          1352:                return (EINVAL);
        !          1353:        if (dumplo + num >= maxsz)
        !          1354:                num = maxsz - dumplo;
        !          1355:        blkoff += dumplo;
        !          1356:        while (num > 0) {
        !          1357:                blk = num > DBSIZE ? DBSIZE : num;
        !          1358:                io = uba->uba_map;
        !          1359:                for (i = 0; i < blk; i++)
        !          1360:                        *(int *)io++ = (btop(start)+i) | UBAMR_MRV;
        !          1361:                *(int *)io = 0;
        !          1362:                udp->uda_Cmd.mscp_lbn = btop(start) + blkoff;
        !          1363:                udp->uda_Cmd.mscp_unit = ui->ui_slave;
        !          1364:                udp->uda_Cmd.mscp_bytecnt = blk*NBPG;
        !          1365:                udp->uda_Cmd.mscp_buffer = 0;
        !          1366:                if (udcmd(M_OP_WRITE, udp, udaddr) == 0) {
        !          1367:                        return(EIO);
        !          1368:                }
        !          1369:                start += blk*NBPG;
        !          1370:                num -= blk;
        !          1371:        }
        !          1372:        return (0);
        !          1373: }
        !          1374: 
        !          1375: 
        !          1376: udcmd(op, udp, udaddr)
        !          1377:        int op;
        !          1378:        register struct uda *udp;
        !          1379:        struct udadevice *udaddr;
        !          1380: {
        !          1381:        int i;
        !          1382: 
        !          1383:        udp->uda_Cmd.mscp_opcode = op;
        !          1384:        udp->uda_Rsp.mscp_header.uda_msglen = mscp_msglen;
        !          1385:        udp->uda_Cmd.mscp_header.uda_msglen = mscp_msglen;
        !          1386:        udp->uda_ca.ca_Rspdsc |= UDA_OWN|UDA_INT;
        !          1387:        udp->uda_ca.ca_Cmddsc |= UDA_OWN|UDA_INT;
        !          1388:        if (udaddr->udasa&UDA_ERR)
        !          1389:                printf("Udaerror udasa (%x)\n", udaddr->udasa&0xffff);
        !          1390:        i = udaddr->udaip;
        !          1391: #ifdef lint
        !          1392:        i = i;
        !          1393: #endif
        !          1394:        for (;;) {
        !          1395:                if (udp->uda_ca.ca_cmdint)
        !          1396:                        udp->uda_ca.ca_cmdint = 0;
        !          1397:                if (udp->uda_ca.ca_rspint)
        !          1398:                        break;
        !          1399:        }
        !          1400:        udp->uda_ca.ca_rspint = 0;
        !          1401:        if (udp->uda_Rsp.mscp_opcode != (op|M_OP_END) ||
        !          1402:            (udp->uda_Rsp.mscp_status&M_ST_MASK) != M_ST_SUCC) {
        !          1403:                printf("error: com %d opc 0x%x stat 0x%x\ndump ",
        !          1404:                        op,
        !          1405:                        udp->uda_Rsp.mscp_opcode,
        !          1406:                        udp->uda_Rsp.mscp_status);
        !          1407:                return(0);
        !          1408:        }
        !          1409:        return(1);
        !          1410: }
        !          1411: 
        !          1412: udsize(dev)
        !          1413:        dev_t dev;
        !          1414: {
        !          1415:        int unit = udunit(dev);
        !          1416:        struct uba_device *ui;
        !          1417:        struct  size    *rasizes;
        !          1418: 
        !          1419:        if (unit >= NRA || (ui = uddinfo[unit]) == 0 || ui->ui_alive == 0
        !          1420:                 || ui->ui_flags == 0)
        !          1421:                return (-1);
        !          1422:        rasizes = ra_info[ui->ui_unit].ra_sizes;
        !          1423:        return (rasizes[minor(dev) & 07].nblocks);
        !          1424: }
        !          1425: 
        !          1426: #endif

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.