Annotation of 43BSD/sys/vaxuba/uda.c, revision 1.1.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.