Annotation of 41BSD/4.0.upgrade/sys/dev/uda.c, revision 1.1.1.1

1.1       root        1: /*     uda.c   1.2     81/10/27        */
                      2: 
                      3: #include "ra.h"
                      4: #if NUDA > 0
                      5: /*
                      6:  * UDA50/RAxx disk device driver
                      7:  *
                      8:  * Restrictions:
                      9:  *     Unit numbers must be less than 8.
                     10:  *
                     11:  * TO DO:
                     12:  *     write dump code
                     13:  *     test on 750
                     14:  */
                     15: 
                     16: #include "../h/param.h"
                     17: #include "../h/systm.h"
                     18: #include "../h/buf.h"
                     19: #include "../h/conf.h"
                     20: #include "../h/dir.h"
                     21: #include "../h/user.h"
                     22: #include "../h/pte.h"
                     23: #include "../h/map.h"
                     24: #include "../h/vm.h"
                     25: #include "../h/ubareg.h"
                     26: #include "../h/ubavar.h"
                     27: #include "../h/dk.h"
                     28: #include "../h/cpu.h"
                     29: #include "../h/cmap.h"
                     30: 
                     31: int udadebug;
                     32: #define        printd  if(udadebug&1)printf
                     33: 
                     34: /*
                     35:  * Parameters for the communications area
                     36:  */
                     37: 
                     38: #define        NRSPL2  3
                     39: #define        NCMDL2  3
                     40: #define        NRSP    (1<<NRSPL2)
                     41: #define        NCMD    (1<<NCMDL2)
                     42: 
                     43: #include "../h/udareg.h"
                     44: #include "../h/mscp.h"
                     45: 
                     46: struct uda_softc {
                     47:        short   sc_state;       /* state of controller */
                     48:        short   sc_mapped;      /* Unibus map allocated for uda struct? */
                     49:        int     sc_ubainfo;     /* Unibus mapping info */
                     50:        struct uda *sc_uda;     /* Unibus address of uda struct */
                     51:        int     sc_ivec;        /* interrupt vector address */
                     52:        short   sc_credits;     /* transfer credits */
                     53:        short   sc_lastcmd;     /* pointer into command ring */
                     54:        short   sc_lastrsp;     /* pointer into response ring */
                     55: } uda_softc[NUDA];
                     56: 
                     57: /*
                     58:  * Controller states
                     59:  */
                     60: #define        S_IDLE  0               /* hasn't been initialized */
                     61: #define        S_STEP1 1               /* doing step 1 init */
                     62: #define        S_STEP2 2               /* doing step 2 init */
                     63: #define        S_STEP3 3               /* doing step 3 init */
                     64: #define        S_SCHAR 4               /* doing "set controller characteristics" */
                     65: #define        S_RUN   5               /* running */
                     66: 
                     67: struct uda {
                     68:        struct udaca    uda_ca;         /* communications area */
                     69:        struct mscp     uda_rsp[NRSP];  /* response packets */
                     70:        struct mscp     uda_cmd[NCMD];  /* command packets */
                     71: } uda[NUDA];
                     72: 
                     73: /* THIS SHOULD BE READ OFF THE PACK, PER DRIVE */
                     74: struct size {
                     75:        daddr_t nblocks;
                     76:        daddr_t blkoff;
                     77: } ra_sizes[8] ={
                     78:        15884,  0,              /* A=blk 0 thru 15883 */
                     79:        33440,  15884,          /* B=blk 15884 thru 49323 */
                     80:        -1,     0,              /* C=blk 0 thru end */
                     81:        0,      0,              /* D reserved for RA81 */
                     82:        0,      0,              /* E reserved for RA81 */
                     83:        0,      0,              /* F reserved for RA81 */
                     84:        82080,  49324,          /* G=blk 49324 thru 131403 */
                     85:        -1,     131404,         /* H=blk 131404 thru end */
                     86: };
                     87: /* END OF STUFF WHICH SHOULD BE READ IN PER DISK */
                     88: 
                     89: daddr_t        radsize[NRA];                   /* disk size, from ONLINE end packet */
                     90: 
                     91: int    udprobe(), udslave(), udattach(), udintr();
                     92: struct mscp *udgetcp();
                     93: struct uba_ctlr *udminfo[NUDA];
                     94: struct uba_device *uddinfo[NRA];
                     95: struct uba_device *udip[NUDA][8];      /* 8 == max number of drives */
                     96: 
                     97: u_short        udstd[] = { 0777550, 0 };
                     98: struct uba_driver udadriver =
                     99:  { udprobe, udslave, udattach, 0, udstd, "ra", uddinfo, "uda", udminfo, 0 };
                    100: struct buf rudbuf[NRA];
                    101: struct buf udutab[NRA];
                    102: struct buf udwtab[NUDA];               /* I/O wait queue, per controller */
                    103: 
                    104: #define        b_qsize         b_resid         /* queue size per drive, in udutab */
                    105: #define        b_ubinfo        b_resid         /* Unibus mapping info, per buffer */
                    106: 
                    107: udprobe(reg, ctlr)
                    108:        caddr_t reg;
                    109:        int ctlr;
                    110: {
                    111:        register int br, cvec;
                    112:        register struct uda_softc *sc = &uda_softc[ctlr];
                    113: 
                    114: #ifdef lint
                    115:        br = 0; cvec = br; br = cvec;
                    116: #endif
                    117:        /* SHOULD CHECK THAT IT REALLY IS A UDA */
                    118:        br = 0x15;
                    119:        cvec = sc->sc_ivec = (uba_hd[numuba].uh_lastiv -= 4);
                    120:        return(1);
                    121: }
                    122: 
                    123: udslave(ui, reg)
                    124:        struct uba_device *ui;
                    125:        caddr_t reg;
                    126: {
                    127:        /*
                    128:         * TOO HARD TO FIND OUT IF DISK IS THERE UNTIL
                    129:         * INITIALIZED.  WE'LL FIND OUT WHEN WE FIRST
                    130:         * TRY TO ACCESS IT.
                    131:         */
                    132:        return(1);
                    133: }
                    134: 
                    135: udattach(ui)
                    136:        register struct uba_device *ui;
                    137: {
                    138: 
                    139:        if (ui->ui_dk > 0)
                    140:                dk_mspw[ui->ui_dk] = 1.0 / (60 * 31 * 256);     /* approx */
                    141:        ui->ui_flags = 0;
                    142:        udip[ui->ui_ctlr][ui->ui_slave] = ui;
                    143:        radsize[ui->ui_unit] = (daddr_t)0xffffff;       /* max possible size */
                    144: }
                    145: 
                    146: /*
                    147:  * Open a UDA.  Initialize the device and
                    148:  * set the unit online.
                    149:  */
                    150: udopen(dev, flag)
                    151:        dev_t dev;
                    152:        int flag;
                    153: {
                    154:        register int unit;
                    155:        register struct uba_device *ui;
                    156:        register struct uda_softc *sc;
                    157: 
                    158:        unit = minor(dev) >> 3;
                    159:        if (unit >= NRA || (ui = uddinfo[unit]) == 0 || ui->ui_alive == 0) {
                    160:                u.u_error = ENXIO;
                    161:                return;
                    162:        }
                    163:        sc = &uda_softc[ui->ui_ctlr];
                    164:        (void) spl5();
                    165:        if (sc->sc_state != S_RUN) {
                    166:                if (sc->sc_state == S_IDLE)
                    167:                        udinit(ui->ui_ctlr);
                    168:                sleep(ui->ui_mi, 0); /* wait for initialization to complete */
                    169:                if (sc->sc_state != S_RUN) {
                    170:                        u.u_error = EIO;
                    171:                        return;
                    172:                }
                    173:        }
                    174:        (void) spl0();
                    175:        /* SHOULD PROBABLY FORCE AN ONLINE ATTEMPT
                    176:           TO SEE IF DISK IS REALLY THERE */
                    177: }
                    178: 
                    179: /*
                    180:  * Initialize a UDA.  Set up UBA mapping registers,
                    181:  * initialize data structures, and start hardware
                    182:  * initialization sequence.
                    183:  */
                    184: udinit(d)
                    185:        int d;
                    186: {
                    187:        register struct uda_softc *sc;
                    188:        register struct uda *ud;
                    189:        struct udadevice *udaddr;
                    190:        struct uba_ctlr *um;
                    191: 
                    192:        sc = &uda_softc[d];
                    193:        um = udminfo[d];
                    194:        um->um_tab.b_active++;
                    195:        ud = &uda[d];
                    196:        udaddr = (struct udadevice *)um->um_addr;
                    197:        if (sc->sc_mapped == 0) {
                    198:                /*
                    199:                 * Map the communications area and command
                    200:                 * and response packets into Unibus address
                    201:                 * space.
                    202:                 */
                    203:                sc->sc_ubainfo = uballoc(um->um_ubanum, (caddr_t)ud,
                    204:                    sizeof (struct uda), 0);
                    205:                sc->sc_uda = (struct uda *)(sc->sc_ubainfo & 0x3ffff);
                    206:                sc->sc_mapped = 1;
                    207:        }
                    208: 
                    209:        /*
                    210:         * Start the hardware initialization sequence.
                    211:         */
                    212:        udaddr->udaip = 0;              /* start initialization */
                    213:        while ((udaddr->udasa & UDA_STEP1) == 0)
                    214:                ;
                    215:        udaddr->udasa = UDA_ERR|(NCMDL2<<11)|(NRSPL2<<8)|UDA_IE|(sc->sc_ivec/4);
                    216:        /*
                    217:         * Initialization continues in interrupt routine.
                    218:         */
                    219:        sc->sc_state = S_STEP1;
                    220:        sc->sc_credits = 0;
                    221: }
                    222: 
                    223: udstrategy(bp)
                    224:        register struct buf *bp;
                    225: {
                    226:        register struct uba_device *ui;
                    227:        register struct uba_ctlr *um;
                    228:        register struct buf *dp;
                    229:        register int unit;
                    230:        int xunit = minor(bp->b_dev) & 07;
                    231:        daddr_t sz, maxsz;
                    232: 
                    233:        sz = (bp->b_bcount+511) >> 9;
                    234:        unit = dkunit(bp);
                    235:        if (unit >= NRA)
                    236:                goto bad;
                    237:        ui = uddinfo[unit];
                    238:        um = ui->ui_mi;
                    239:        if (ui == 0 || ui->ui_alive == 0)
                    240:                goto bad;
                    241:        if ((maxsz = ra_sizes[xunit].nblocks) < 0)
                    242:                maxsz = radsize[unit] - ra_sizes[xunit].blkoff;
                    243:        if (bp->b_blkno < 0 || bp->b_blkno+sz > maxsz ||
                    244:            ra_sizes[xunit].blkoff >= radsize[unit])
                    245:                goto bad;
                    246:        (void) spl5();
                    247:        /*
                    248:         * Link the buffer onto the drive queue
                    249:         */
                    250:        dp = &udutab[ui->ui_unit];
                    251:        if (dp->b_actf == 0)
                    252:                dp->b_actf = bp;
                    253:        else
                    254:                dp->b_actl->av_forw = bp;
                    255:        dp->b_actl = bp;
                    256:        bp->av_forw = 0;
                    257:        /*
                    258:         * Link the drive onto the controller queue
                    259:         */
                    260:        if (dp->b_active == 0) {
                    261:                dp->b_forw = NULL;
                    262:                if (um->um_tab.b_actf == NULL)
                    263:                        um->um_tab.b_actf = dp;
                    264:                else
                    265:                        um->um_tab.b_actl->b_forw = dp;
                    266:                um->um_tab.b_actl = dp;
                    267:                dp->b_active = 1;
                    268:        }
                    269:        if (um->um_tab.b_active == 0) {
                    270: #if defined(VAX750)
                    271:                if (cpu == VAX_750) {
                    272:                        if (um->um_ubinfo != 0)
                    273:                                printf("uda: ubinfo %x\n",um->um_ubinfo);
                    274:                        else
                    275:                                um->um_ubinfo =
                    276:                                uballoc(um->um_ubanum, 0, 0, UBA_NEEDBDP);
                    277:                }
                    278: #endif
                    279:                (void) udstart(um);
                    280:        }
                    281:        (void) spl0();
                    282:        return;
                    283: 
                    284: bad:
                    285:        bp->b_flags |= B_ERROR;
                    286:        iodone(bp);
                    287:        return;
                    288: }
                    289: 
                    290: udstart(um)
                    291:        register struct uba_ctlr *um;
                    292: {
                    293:        register struct buf *bp, *dp;
                    294:        register struct mscp *mp;
                    295:        register struct uda_softc *sc;
                    296:        register struct uba_device *ui;
                    297:        struct udadevice *udaddr;
                    298:        int i;
                    299: 
                    300:        sc = &uda_softc[um->um_ctlr];
                    301:        
                    302: loop:
                    303:        if ((dp = um->um_tab.b_actf) == NULL) {
                    304:                /*
                    305:                 * Release uneeded UBA resources and return
                    306:                 */
                    307:                um->um_tab.b_active = 0;
                    308: #if defined(VAX750)
                    309:                if (cpu == VAX_750) {
                    310:                        if (um->um_ubinfo == 0)
                    311:                                printf("uda: um_ubinfo == 0\n");
                    312:                        else
                    313:                                ubarelse(um->um_ubanum, &um->um_ubinfo);
                    314:                }
                    315: #endif
                    316:                return(0);
                    317:        }
                    318:        if ((bp = dp->b_actf) == NULL) {
                    319:                /*
                    320:                 * No more requests for this drive, remove
                    321:                 * from controller queue and look at next drive.
                    322:                 * We know we're at the head of the controller queue.
                    323:                 */
                    324:                dp->b_active = 0;
                    325:                um->um_tab.b_actf = dp->b_forw;
                    326:                goto loop;
                    327:        }
                    328:        um->um_tab.b_active++;
                    329:        udaddr = (struct udadevice *)um->um_addr;
                    330:        if ((udaddr->udasa&UDA_ERR) || sc->sc_state != S_RUN) {
                    331:                harderr(bp, "ra");
                    332:                printf("udasa %o, state %d\n", udaddr->udasa&0xffff, sc->sc_state);
                    333:                udinit(um->um_ctlr);
                    334:                /* SHOULD REQUEUE OUTSTANDING REQUESTS, LIKE UDRESET */
                    335:                return;
                    336:        }
                    337:        ui = uddinfo[dkunit(bp)];
                    338:        /*
                    339:         * If no credits, can't issue any commands
                    340:         * until some outstanding commands complete.
                    341:         */
                    342:        if (sc->sc_credits < 2)
                    343:                return(0);
                    344:        if ((mp = udgetcp(um)) == NULL)
                    345:                return(0);
                    346:        sc->sc_credits--;       /* committed to issuing a command */
                    347:        if (ui->ui_flags == 0) {        /* not online */
                    348:                mp->mscp_opcode = M_OP_ONLIN;
                    349:                mp->mscp_unit = ui->ui_slave;
                    350:                dp->b_active = 2;
                    351:                um->um_tab.b_actf = dp->b_forw; /* remove from controller q */
                    352:                printd("uda: bring unit %d online\n", ui->ui_slave);
                    353:                *((long *)mp->mscp_dscptr) |= UDA_OWN|UDA_INT;
                    354:                i = udaddr->udaip;
                    355:                goto loop;
                    356:        }
                    357:        switch (cpu) {
                    358:        case VAX_780:
                    359:                i = UBA_NEEDBDP|UBA_CANTWAIT;
                    360:                break;
                    361: 
                    362:        case VAX_750:
                    363:                i = um->um_ubinfo|UBA_HAVEBDP|UBA_CANTWAIT;
                    364:                break;
                    365: 
                    366:        case VAX_7ZZ:
                    367:                i = UBA_CANTWAIT;
                    368:                break;
                    369:        }
                    370:        if ((i = ubasetup(um->um_ubanum, bp, i)) == 0) {
                    371:                mp->mscp_opcode = M_OP_GTUNT;
                    372:                mp->mscp_unit = ui->ui_slave;
                    373:                *((long *)mp->mscp_dscptr) |= UDA_OWN|UDA_INT;
                    374:                i = udaddr->udaip;      /* initiate polling */
                    375:                return(1);              /* wait for interrupt */
                    376:        }
                    377:        mp->mscp_cmdref = (long)bp;     /* pointer to get back */
                    378:        mp->mscp_opcode = bp->b_flags&B_READ ? M_OP_READ : M_OP_WRITE;
                    379:        mp->mscp_unit = ui->ui_slave;
                    380:        mp->mscp_lbn = bp->b_blkno + ra_sizes[minor(bp->b_dev)&7].blkoff;
                    381:        mp->mscp_bytecnt = bp->b_bcount;
                    382:        mp->mscp_buffer = (i & 0x3ffff) | (((i>>28)&0xf)<<24);
                    383: #if defined(VAX750)
                    384:        if (cpu == VAX_750)
                    385:                i &= 0xfffffff;         /* mask off bdp */
                    386: #endif
                    387:        bp->b_ubinfo = i;               /* save mapping info */
                    388:        *((long *)mp->mscp_dscptr) |= UDA_OWN|UDA_INT;
                    389:        i = udaddr->udaip;              /* initiate polling */
                    390:        if (ui->ui_dk >= 0) {
                    391:                dk_busy |= 1<<ui->ui_dk;
                    392:                dp->b_qsize++;
                    393:                dk_xfer[ui->ui_dk]++;
                    394:                dk_wds[ui->ui_dk] += bp->b_bcount>>6;
                    395:        }
                    396: 
                    397:        /*
                    398:         * Move drive to the end of the controller queue
                    399:         */
                    400:        if (dp->b_forw != NULL) {
                    401:                um->um_tab.b_actf = dp->b_forw;
                    402:                um->um_tab.b_actl->b_forw = dp;
                    403:                um->um_tab.b_actl = dp;
                    404:                dp->b_forw = NULL;
                    405:        }
                    406:        /*
                    407:         * Move buffer to I/O wait queue
                    408:         */
                    409:        dp->b_actf = bp->av_forw;
                    410:        dp = &udwtab[um->um_ctlr];
                    411:        bp->av_forw = dp;
                    412:        bp->av_back = dp->av_back;
                    413:        dp->av_back->av_forw = bp;
                    414:        dp->av_back = bp;
                    415:        goto loop;
                    416: }
                    417: 
                    418: /*
                    419:  * UDA interrupt routine.
                    420:  */
                    421: udintr(d)
                    422:        int d;
                    423: {
                    424:        register struct uba_ctlr *um = udminfo[d];
                    425:        register struct udadevice *udaddr = (struct udadevice *)um->um_addr;
                    426:        struct buf *bp;
                    427:        register int i;
                    428:        register struct uda_softc *sc = &uda_softc[d];
                    429:        register struct uda *ud = &uda[d];
                    430:        struct uda *uud;
                    431:        struct mscp *mp;
                    432: 
                    433:        printd("udintr: state %d, udasa %o\n", sc->sc_state, udaddr->udasa);
                    434:        switch (sc->sc_state) {
                    435:        case S_IDLE:
                    436:                printf("uda%d: random interrupt ignored\n", d);
                    437:                return;
                    438: 
                    439:        case S_STEP1:
                    440: #define        STEP1GOOD       (UDA_STEP2|UDA_IE|(NCMDL2<<3)|NRSPL2)
                    441:                if ((udaddr->udasa&(UDA_ERR|STEP1GOOD)) != STEP1GOOD) {
                    442:                        sc->sc_state = S_IDLE;
                    443:                        wakeup(um);
                    444:                        return;
                    445:                }
                    446:                udaddr->udasa = ((int)&sc->sc_uda->uda_ca.ca_ringbase)|
                    447:                    (cpu == VAX_780 ? UDA_PI : 0);
                    448:                sc->sc_state = S_STEP2;
                    449:                return;
                    450: 
                    451:        case S_STEP2:
                    452: #define        STEP2GOOD       (UDA_STEP3|UDA_IE|(sc->sc_ivec/4))
                    453:                if ((udaddr->udasa&(UDA_ERR|STEP2GOOD)) != STEP2GOOD) {
                    454:                        sc->sc_state = S_IDLE;
                    455:                        wakeup(um);
                    456:                        return;
                    457:                }
                    458:                udaddr->udasa = ((int)&sc->sc_uda->uda_ca.ca_ringbase)>>16;
                    459:                sc->sc_state = S_STEP3;
                    460:                return;
                    461: 
                    462:        case S_STEP3:
                    463: #define        STEP3GOOD       UDA_STEP4
                    464:                if ((udaddr->udasa&(UDA_ERR|STEP3GOOD)) != STEP3GOOD) {
                    465:                        sc->sc_state = S_IDLE;
                    466:                        wakeup(um);
                    467:                        return;
                    468:                }
                    469:                udaddr->udasa = UDA_GO;
                    470:                sc->sc_state = S_SCHAR;
                    471: 
                    472:                /*
                    473:                 * Initialize the data structures.
                    474:                 */
                    475:                uud = sc->sc_uda;
                    476:                for (i = 0; i < NRSP; i++) {
                    477:                        ud->uda_ca.ca_rspdsc[i] = UDA_OWN|UDA_INT|
                    478:                                (long)&uud->uda_rsp[i].mscp_cmdref;
                    479:                        ud->uda_rsp[i].mscp_dscptr = &ud->uda_ca.ca_rspdsc[i];
                    480:                        ud->uda_rsp[i].mscp_header.uda_msglen = sizeof (struct mscp);
                    481:                }
                    482:                for (i = 0; i < NCMD; i++) {
                    483:                        ud->uda_ca.ca_cmddsc[i] = UDA_INT|
                    484:                                (long)&uud->uda_cmd[i].mscp_cmdref;
                    485:                        ud->uda_cmd[i].mscp_dscptr = &ud->uda_ca.ca_cmddsc[i];
                    486:                        ud->uda_cmd[i].mscp_header.uda_msglen = sizeof (struct mscp);
                    487:                }
                    488:                bp = &udwtab[d];
                    489:                bp->av_forw = bp->av_back = bp;
                    490:                sc->sc_lastcmd = 0;
                    491:                sc->sc_lastrsp = 0;
                    492:                if ((mp = udgetcp(um)) == NULL) {
                    493:                        sc->sc_state = S_IDLE;
                    494:                        wakeup(um);
                    495:                        return;
                    496:                }
                    497:                mp->mscp_opcode = M_OP_STCON;
                    498:                mp->mscp_cntflgs = M_CF_ATTN|M_CF_MISC|M_CF_THIS;
                    499:                *((long *)mp->mscp_dscptr) |= UDA_OWN|UDA_INT;
                    500:                i = udaddr->udaip;      /* initiate polling */
                    501:                return;
                    502: 
                    503:        case S_SCHAR:
                    504:        case S_RUN:
                    505:                break;
                    506: 
                    507:        default:
                    508:                printf("uda%d: interrupt in unknown state %d ignored\n",
                    509:                        d, sc->sc_state);
                    510:                return;
                    511:        }
                    512: 
                    513:        if (udaddr->udasa&UDA_ERR) {
                    514:                printf("uda%d: fatal error (%o)\n", d, udaddr->udasa&0xffff);
                    515:                udaddr->udaip = 0;
                    516:                wakeup(um);
                    517:        }
                    518: 
                    519:        /*
                    520:         * Check for a buffer purge request.
                    521:         */
                    522:        if (ud->uda_ca.ca_bdp) {
                    523:                /*
                    524:                 * THIS IS A KLUDGE.
                    525:                 * Maybe we should change the entire
                    526:                 * UBA interface structure.
                    527:                 */
                    528:                int s = spl7();
                    529: 
                    530:                i = um->um_ubinfo;
                    531:                printd("uda: purge bdp %d\n", ud->uda_ca.ca_bdp);
                    532:                um->um_ubinfo = ud->uda_ca.ca_bdp<<28;
                    533:                ubapurge(um);
                    534:                um->um_ubinfo = i;
                    535:                (void) splx(s);
                    536:                ud->uda_ca.ca_bdp = 0;
                    537:                udaddr->udasa = 0;      /* signal purge complete */
                    538:        }
                    539: 
                    540:        /*
                    541:         * Check for response ring transition.
                    542:         */
                    543:        if (ud->uda_ca.ca_rspint) {
                    544:                ud->uda_ca.ca_rspint = 0;
                    545:                for (i = sc->sc_lastrsp;; i++) {
                    546:                        i %= NRSP;
                    547:                        if (ud->uda_ca.ca_rspdsc[i]&UDA_OWN)
                    548:                                break;
                    549:                        udrsp(um, ud, sc, i);
                    550:                        ud->uda_ca.ca_rspdsc[i] |= UDA_OWN;
                    551:                }
                    552:                sc->sc_lastrsp = i;
                    553:        }
                    554: 
                    555:        /*
                    556:         * Check for command ring transition.
                    557:         */
                    558:        if (ud->uda_ca.ca_cmdint) {
                    559:                printd("uda: command ring transition\n");
                    560:                ud->uda_ca.ca_cmdint = 0;
                    561:        }
                    562:        udstart(um);
                    563: }
                    564: 
                    565: /*
                    566:  * Process a response packet
                    567:  */
                    568: udrsp(um, ud, sc, i)
                    569:        register struct uba_ctlr *um;
                    570:        register struct uda *ud;
                    571:        register struct uda_softc *sc;
                    572:        int i;
                    573: {
                    574:        register struct mscp *mp;
                    575:        struct uba_device *ui;
                    576:        struct buf *dp, *bp;
                    577:        int st;
                    578: 
                    579:        mp = &ud->uda_rsp[i];
                    580:        mp->mscp_header.uda_msglen = sizeof (struct mscp);
                    581:        sc->sc_credits += mp->mscp_header.uda_credits & 0xf;
                    582:        if ((mp->mscp_header.uda_credits & 0xf0) > 0x10)
                    583:                return;
                    584:        /*
                    585:         * If it's an error log message (datagram),
                    586:         * pass it on for more extensive processing.
                    587:         */
                    588:        if ((mp->mscp_header.uda_credits & 0xf0) == 0x10) {
                    589:                uderror(um, (struct mslg *)mp);
                    590:                return;
                    591:        }
                    592:        if (mp->mscp_unit >= 8)
                    593:                return;
                    594:        if ((ui = udip[um->um_ctlr][mp->mscp_unit]) == 0)
                    595:                return;
                    596:        st = mp->mscp_status&M_ST_MASK;
                    597:        switch (mp->mscp_opcode) {
                    598:        case M_OP_STCON|M_OP_END:
                    599:                if (st == M_ST_SUCC)
                    600:                        sc->sc_state = S_RUN;
                    601:                else
                    602:                        sc->sc_state = S_IDLE;
                    603:                um->um_tab.b_active = 0;
                    604:                wakeup(um);
                    605:                break;
                    606: 
                    607:        case M_OP_ONLIN|M_OP_END:
                    608:                /*
                    609:                 * Link the drive onto the controller queue
                    610:                 */
                    611:                dp = &udutab[ui->ui_unit];
                    612:                dp->b_forw = NULL;
                    613:                if (um->um_tab.b_actf == NULL)
                    614:                        um->um_tab.b_actf = dp;
                    615:                else
                    616:                        um->um_tab.b_actl->b_forw = dp;
                    617:                um->um_tab.b_actl = dp;
                    618:                if (st == M_ST_SUCC) {
                    619:                        ui->ui_flags = 1;       /* mark it online */
                    620:                        radsize[ui->ui_unit] = (daddr_t)mp->mscp_untsize;
                    621:                        printd("uda: unit %d online\n", mp->mscp_unit);
                    622:                } else {
                    623:                        harderr(dp->b_actf, "ra");
                    624:                        printf("OFFLINE\n");
                    625:                        while (bp = dp->b_actf) {
                    626:                                dp->b_actf = bp->av_forw;
                    627:                                bp->b_flags |= B_ERROR;
                    628:                                iodone(bp);
                    629:                        }
                    630:                }
                    631:                dp->b_active = 1;
                    632:                break;
                    633: 
                    634:        case M_OP_AVATN:
                    635:                printd("uda: unit %d attention\n", mp->mscp_unit);
                    636:                ui->ui_flags = 0;       /* it went offline and we didn't notice */
                    637:                break;
                    638: 
                    639:        case M_OP_READ|M_OP_END:
                    640:        case M_OP_WRITE|M_OP_END:
                    641:                bp = (struct buf *)mp->mscp_cmdref;
                    642:                ubarelse(um->um_ubanum, &bp->b_resid);
                    643:                /*
                    644:                 * Unlink buffer from I/O wait queue.
                    645:                 */
                    646:                bp->av_back->av_forw = bp->av_forw;
                    647:                bp->av_forw->av_back = bp->av_back;
                    648:                dp = &udutab[ui->ui_unit];
                    649:                if (ui->ui_dk >= 0)
                    650:                        if (--dp->b_qsize == 0)
                    651:                                dk_busy &= ~(1<<ui->ui_dk);
                    652:                if (st == M_ST_OFFLN || st == M_ST_AVLBL) {
                    653:                        ui->ui_flags = 0;       /* mark unit offline */
                    654:                        /*
                    655:                         * Link the buffer onto the front of the drive queue
                    656:                         */
                    657:                        if ((bp->av_forw = dp->b_actf) == 0)
                    658:                                dp->b_actl = bp;
                    659:                        dp->b_actf = bp;
                    660:                        /*
                    661:                         * Link the drive onto the controller queue
                    662:                         */
                    663:                        if (dp->b_active == 0) {
                    664:                                dp->b_forw = NULL;
                    665:                                if (um->um_tab.b_actf == NULL)
                    666:                                        um->um_tab.b_actf = dp;
                    667:                                else
                    668:                                        um->um_tab.b_actl->b_forw = dp;
                    669:                                um->um_tab.b_actl = dp;
                    670:                                dp->b_active = 1;
                    671:                        }
                    672:                        return;
                    673:                }
                    674:                if (st != M_ST_SUCC) {
                    675:                        harderr(bp, "ra");
                    676:                        printf("status %o\n", mp->mscp_status);
                    677:                        bp->b_flags |= B_ERROR;
                    678:                }
                    679:                bp->b_resid = bp->b_bcount - mp->mscp_bytecnt;
                    680:                iodone(bp);
                    681:                break;
                    682: 
                    683:        case M_OP_GTUNT|M_OP_END:
                    684:                break;
                    685: 
                    686:        default:
                    687:                printf("uda: unknown packet\n");
                    688:        }
                    689: }
                    690: 
                    691: 
                    692: /*
                    693:  * Process an error log message
                    694:  *
                    695:  * For now, just log the error on the console.
                    696:  * Only minimal decoding is done, only "useful"
                    697:  * information is printed.  Eventually should
                    698:  * send message to an error logger.
                    699:  */
                    700: uderror(um, mp)
                    701:        register struct uba_ctlr *um;
                    702:        register struct mslg *mp;
                    703: {
                    704:        printf("uda%d:%d: %s error, ", um->um_ctlr, mp->mslg_seqnum,
                    705:                mp->mslg_flags&M_LF_SUCC ? "soft" : "hard");
                    706:        switch (mp->mslg_format) {
                    707:        case M_FM_CNTERR:
                    708:                printf("controller error, event 0%o\n", mp->mslg_event);
                    709:                break;
                    710: 
                    711:        case M_FM_BUSADDR:
                    712:                printf("host memory access error, event 0%o, addr 0%o\n",
                    713:                        mp->mslg_event, *((long *)&mp->mslg_busaddr[0]));
                    714:                break;
                    715: 
                    716:        case M_FM_DISKTRN:
                    717:                printf("disk transfer error, unit %d, grp %d, cyl %d, sec %d, ",
                    718:                        mp->mslg_unit, mp->mslg_group, mp->mslg_cylinder,
                    719:                        mp->mslg_sector);
                    720:                printf("trk %d, lbn %d, retry %d, level %d\n", mp->mslg_track,
                    721:                        mp->mslg_lbn, mp->mslg_retry, mp->mslg_level);
                    722:                break;
                    723: 
                    724:        case M_FM_SDI:
                    725:                printf("SDI error, unit %d, event 0%o, cyl %d\n", mp->mslg_unit,
                    726:                        mp->mslg_event, mp->mslg_cylinder);
                    727:                break;
                    728: 
                    729:        case M_FM_SMLDSK:
                    730:                printf("small disk error, unit %d, event 0%o, cyl %d\n",
                    731:                        mp->mslg_unit, mp->mslg_event, mp->mslg_sdecyl);
                    732:                break;
                    733: 
                    734:        default:
                    735:                printf("unknown error, unit %d, format 0%o, event 0%o\n",
                    736:                        mp->mslg_unit, mp->mslg_format, mp->mslg_event);
                    737:        }
                    738: }
                    739: 
                    740: 
                    741: /*
                    742:  * Find an unused command packet
                    743:  */
                    744: struct mscp *
                    745: udgetcp(um)
                    746:        struct uba_ctlr *um;
                    747: {
                    748:        register struct mscp *mp;
                    749:        register struct udaca *cp;
                    750:        register struct uda_softc *sc;
                    751:        register int i;
                    752: 
                    753:        cp = &uda[um->um_ctlr].uda_ca;
                    754:        sc = &uda_softc[um->um_ctlr];
                    755:        i = sc->sc_lastcmd;
                    756:        if ((cp->ca_cmddsc[i] & (UDA_OWN|UDA_INT)) == UDA_INT) {
                    757:                cp->ca_cmddsc[i] &= ~UDA_INT;
                    758:                mp = &uda[um->um_ctlr].uda_cmd[i];
                    759:                mp->mscp_unit = mp->mscp_modifier = 0;
                    760:                mp->mscp_opcode = mp->mscp_flags = 0;
                    761:                mp->mscp_bytecnt = mp->mscp_buffer = 0;
                    762:                mp->mscp_errlgfl = mp->mscp_copyspd = 0;
                    763:                sc->sc_lastcmd = (i + 1) % NCMD;
                    764:                return(mp);
                    765:        }
                    766:        return(NULL);
                    767: }
                    768: 
                    769: udread(dev)
                    770:        dev_t dev;
                    771: {
                    772:        register int unit = minor(dev) >> 3;
                    773: 
                    774:        if (unit >= NRA)
                    775:                u.u_error = ENXIO;
                    776:        else
                    777:                physio(udstrategy, &rudbuf[unit], dev, B_READ, minphys);
                    778: }
                    779: 
                    780: udwrite(dev)
                    781:        dev_t dev;
                    782: {
                    783:        register int unit = minor(dev) >> 3;
                    784: 
                    785:        if (unit >= NRA)
                    786:                u.u_error = ENXIO;
                    787:        else
                    788:                physio(udstrategy, &rudbuf[unit], dev, B_WRITE, minphys);
                    789: }
                    790: 
                    791: udreset(uban)
                    792:        int uban;
                    793: {
                    794:        register struct uba_ctlr *um;
                    795:        register struct uba_device *ui;
                    796:        register struct buf *bp, *dp;
                    797:        register int unit;
                    798:        struct buf *nbp;
                    799:        int d;
                    800: 
                    801:        for (d = 0; d < NUDA; d++) {
                    802:                if ((um = udminfo[d]) == 0 || um->um_ubanum != uban ||
                    803:                    um->um_alive == 0)
                    804:                        continue;
                    805:                printf(" uda%d", d);
                    806:                um->um_tab.b_active = 0;
                    807:                um->um_tab.b_actf = um->um_tab.b_actl = 0;
                    808:                uda_softc[d].sc_state = S_IDLE;
                    809:                for (unit = 0; unit < NRA; unit++) {
                    810:                        if ((ui = uddinfo[unit]) == 0)
                    811:                                continue;
                    812:                        if (ui->ui_alive == 0 || ui->ui_mi != um)
                    813:                                continue;
                    814:                        udutab[unit].b_active = 0;
                    815:                        udutab[unit].b_qsize = 0;
                    816:                }
                    817:                for (bp = udwtab[d].av_forw; bp != &udwtab[d]; bp = nbp) {
                    818:                        nbp = bp->av_forw;
                    819:                        ubarelse(uban, &bp->b_ubinfo);
                    820:                        /*
                    821:                         * Link the buffer onto the drive queue
                    822:                         */
                    823:                        dp = &udutab[dkunit(bp)];
                    824:                        if (dp->b_actf == 0)
                    825:                                dp->b_actf = bp;
                    826:                        else
                    827:                                dp->b_actl->av_forw = bp;
                    828:                        dp->b_actl = bp;
                    829:                        bp->av_forw = 0;
                    830:                        /*
                    831:                         * Link the drive onto the controller queue
                    832:                         */
                    833:                        if (dp->b_active == 0) {
                    834:                                dp->b_forw = NULL;
                    835:                                if (um->um_tab.b_actf == NULL)
                    836:                                        um->um_tab.b_actf = dp;
                    837:                                else
                    838:                                        um->um_tab.b_actl->b_forw = dp;
                    839:                                um->um_tab.b_actl = dp;
                    840:                                dp->b_active = 1;
                    841:                        }
                    842:                }
                    843:                udinit(d);
                    844:        }
                    845: }
                    846: 
                    847: uddump()
                    848: {
                    849:        return(ENXIO);
                    850: }

unix.superglobalmegacorp.com

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