Annotation of researchv9/sys/sundev/sf.c, revision 1.1.1.1

1.1       root        1: /*     @(#)sf.c 1.1 86/02/03 SMI       */
                      2: 
                      3: /*
                      4:  * Copyright (c) 1984 by Sun Microsystems, Inc.
                      5:  */
                      6: 
                      7: #include "sf.h"
                      8: #if NSF > 0
                      9: 
                     10: /*
                     11:  * SCSI driver for SCSI floppy disks.
                     12:  */
                     13: #include "../h/param.h"
                     14: #include "../h/systm.h"
                     15: #include "../h/dk.h"
                     16: #include "../h/buf.h"
                     17: #include "../h/conf.h"
                     18: #include "../h/user.h"
                     19: #include "../h/map.h"
                     20: #include "../h/vmmac.h"
                     21: /*
                     22:  *#include "../h/ioctl.h"
                     23:  *#include "../h/uio.h"
                     24:  *#include "../h/kernel.h"
                     25:  */
                     26: #include "../h/dkbad.h"
                     27: /*
                     28:  *#include "../h/vfs.h"
                     29:  *#include "../h/vnode.h"
                     30:  */
                     31: #include "../machine/pte.h"
                     32: #include "../machine/psl.h"
                     33: #include "../machine/mmu.h"
                     34: #include "../machine/cpu.h"
                     35: #include "../sun/dklabel.h"
                     36: #include "../sun/dkio.h"
                     37: /*#include "../pcfs/pc_label.h"*/
                     38: #include "../sundev/mbvar.h"
                     39: #include "../sundev/screg.h"
                     40: #include "../sundev/sireg.h"
                     41: #include "../sundev/scsi.h"
                     42: 
                     43: #define        MAX_RETRIES     0
                     44: #define        MAX_RESTORES    1
                     45: 
                     46: #define        SFUNIT(dev)     (minor(dev))
                     47: #define        SFNUM(un)       (un - sfunits)
                     48: 
                     49: #define b_cylin b_resid
                     50: 
                     51: #define BUSY_RETRY 1000
                     52: 
                     53: /*
                     54:  * Error message control.
                     55:  */
                     56: #define        EL_RETRY        3
                     57: #define EL_REST                2
                     58: #define        EL_FAIL         1
                     59: int sferrlvl = EL_REST;
                     60: 
                     61: /*
                     62:  * sf specific SCSI commands
                     63:  */
                     64: #define SC_INIT_CHARACTERISTICS 0x0c   /* initialize drive characteristics */
                     65: 
                     66: extern struct scsi_unit sfunits[];
                     67: extern struct scsi_unit_subr scsi_unit_subr[];
                     68: extern struct scsi_floppy sfloppy[];
                     69: extern int nsfloppy;
                     70: 
                     71: #define SF_LABELGET    0x01            /* getting device label */
                     72: #define SF_LABELWANT   0x02            /* waiting to get label */
                     73: 
                     74: struct sf_characteristics {
                     75:        u_char  sfc_ncyl;               /* number of cylinders */
                     76:        u_int   sfc_trkswtch    : 4;    /* track switching rate code */
                     77:        u_int   sfc_mstart      : 12;   /* motor start time (msec) */
                     78:        u_char  sfc_drive       : 4;    /* drive type (5 or 8 inch) */
                     79:        u_char  sfc_nhead       : 4;    /* number of heads */
                     80:        u_char  sfc_secsize;            /* sector size / 256 */
                     81:        u_char  sfc_uload;              /* head unload time in 1/10 sec */
                     82:        u_char  sfc_spt;                /* sectors per track */
                     83:        u_char  sfc_record;             /* recording density code */
                     84: };
                     85: 
                     86: /*
                     87:  * track switching codes
                     88:  */
                     89: #define TS_6MSEC       0       /* 6 msec */
                     90: #define TS_12MSEC      1       /* 12 msec */
                     91: #define TS_20MSEC      2       /* 20 msec */
                     92: #define TS_30MSEC      3       /* 30 msec */
                     93: 
                     94: /*
                     95:  * recording density codes
                     96:  */
                     97: #define        SDENSITY        0x00    /* single denisity */
                     98: #define DDENSITY       0xC0    /* double density */
                     99: 
                    100: static struct sf_characteristics default_characteristics = {
                    101:        40,
                    102:        TS_6MSEC,
                    103:        500,
                    104:        5,
                    105:        2,
                    106:        PC_SECSIZE/256,
                    107:        10,
                    108:        9,
                    109:        DDENSITY
                    110: };
                    111: 
                    112: static struct sf_characteristics current_characteristics;
                    113: 
                    114: /*
                    115:  * Return a pointer to this unit's unit structure.
                    116:  */
                    117: sfunitptr(md)
                    118:        register struct mb_device *md;
                    119: {
                    120:        return ((int)&sfunits[md->md_unit]);
                    121: }
                    122: 
                    123: /*
                    124:  * Attach device (boot time).
                    125:  */
                    126: sfattach(md)
                    127:        register struct mb_device *md;
                    128: {
                    129:        register struct scsi_unit *un;
                    130: 
                    131:        un = &sfunits[md->md_unit];
                    132:        un->un_md = md;
                    133:        un->un_mc = md->md_mc;
                    134:        un->un_unit = md->md_unit;
                    135:        un->un_target = TARGET(md->md_slave);
                    136:        un->un_lun = LUN(md->md_slave);
                    137:        un->un_ss = &scsi_unit_subr[TYPE(md->md_flags)];
                    138: }
                    139: 
                    140: static int
                    141: getlabel(dev)
                    142:        register dev_t dev;
                    143: {
                    144:        register struct scsi_unit *un;
                    145:        register char *bufp;
                    146:        register struct scsi_floppy *dsi;
                    147:        char c;
                    148: 
                    149:        un = &sfunits[SFUNIT(dev)];
                    150:        dsi = &sfloppy[SFUNIT(dev)];
                    151:        /*
                    152:         * We don't want multiple opens going on at the same time.
                    153:         */
                    154:        while (dsi->sf_flags & SF_LABELGET) {
                    155:                dsi->sf_flags |= SF_LABELWANT;
                    156:                sleep((caddr_t)dsi, PRIBIO);
                    157:                if (un->un_present)
                    158:                        return (1);
                    159:        }
                    160:        dsi->sf_flags |= SF_LABELGET;
                    161:        dsi->sf_nblk = 8;
                    162:        dsi->sf_spt = 8;
                    163:        dsi->sf_nhead = 1;
                    164:        if (sfcmd(dev, SC_TEST_UNIT_READY, 0, 0, (caddr_t)0)) {
                    165:                uprintf("sf%d: not online\n", SFNUM(un));
                    166:                goto out;
                    167:        }
                    168:        if (sfcmd(dev, SC_INIT_CHARACTERISTICS, 0,
                    169:            sizeof(default_characteristics),
                    170:            (caddr_t)&default_characteristics) ) {
                    171:                uprintf("sf%d: cannot init drive\n", SFNUM(un));
                    172:                goto out;
                    173:        }
                    174:        bufp = kmem_alloc(PC_SECSIZE);
                    175:        if (sfcmd(dev, SC_READ, PC_FATBLOCK, PC_SECSIZE, bufp)) {
                    176:                uprintf("sf%d: error reading label\n", SFNUM(un));
                    177:                kmem_free(bufp, PC_SECSIZE);
                    178:                goto out;
                    179:        }
                    180:        dsi->sf_mdb = bufp[0];
                    181:        c = bufp[1] & bufp[2];
                    182:        kmem_free(bufp, PC_SECSIZE);
                    183:        if (c != 0xFF) {
                    184:                uprintf("sf%d: bad label\n", SFNUM(un));
                    185:                goto out;
                    186:        }
                    187:        switch (dsi->sf_mdb) {
                    188:        case SS8SPT:
                    189:                dsi->sf_spt = 8;
                    190:                dsi->sf_nhead = 1;
                    191:                dsi->sf_nblk = 320;
                    192:                break;
                    193: 
                    194:        case DS8SPT:
                    195:                dsi->sf_spt = 8;
                    196:                dsi->sf_nhead = 2;
                    197:                dsi->sf_nblk = 640;
                    198:                break;
                    199: 
                    200:        case SS9SPT:
                    201:                dsi->sf_spt = 9;
                    202:                dsi->sf_nhead = 1;
                    203:                dsi->sf_nblk = 360;
                    204:                break;
                    205: 
                    206:        case DS9SPT:
                    207:                dsi->sf_spt = 9;
                    208:                dsi->sf_nhead = 2;
                    209:                dsi->sf_nblk = 720;
                    210:                break;
                    211: 
                    212:        default:
                    213:                uprintf("sf%d: bad label\n", SFNUM(un));
                    214:                goto out;
                    215:        }
                    216:        current_characteristics = default_characteristics;
                    217:        current_characteristics.sfc_spt = dsi->sf_spt;
                    218:        current_characteristics.sfc_nhead = dsi->sf_nhead;
                    219:        if (sfcmd(dev, SC_INIT_CHARACTERISTICS, 0,
                    220:            sizeof(current_characteristics),
                    221:            (caddr_t)&current_characteristics)) {
                    222:                uprintf("sf%d: cannot reinit drive\n", SFNUM(un));
                    223:        } else {
                    224:                un->un_present = 1;
                    225:        }
                    226: out:
                    227:        dsi->sf_flags &= ~SF_LABELGET;
                    228:        if (dsi->sf_flags & SF_LABELWANT) {
                    229:                dsi->sf_flags &= ~SF_LABELWANT;
                    230:                wakeup((caddr_t)dsi);
                    231:        }
                    232:        return (un->un_present);
                    233: }
                    234: 
                    235: /*ARGSUSED*/
                    236: sfopen(dev, flag)
                    237:        dev_t dev;
                    238:        int flag;
                    239: {
                    240:        register struct scsi_unit *un;
                    241:        register int unit;
                    242: 
                    243:        unit = SFUNIT(dev);
                    244:        if (unit >= nsfloppy) {
                    245:                return (ENXIO);
                    246:        }
                    247:        un = &sfunits[unit];
                    248:        if (un->un_mc == 0) {   /* never attached */
                    249:                return (ENXIO);
                    250:        }
                    251:        if (!un->un_present) {
                    252:                if (!getlabel(dev)) {
                    253:                        return (EIO);
                    254:                }
                    255:        }
                    256:        return (0);
                    257: }
                    258: 
                    259: /*ARGSUSED*/
                    260: sfclose(dev, flag)
                    261:        dev_t dev;
                    262:        int flag;
                    263: {
                    264:        register struct scsi_unit *un;
                    265: 
                    266:        un = &sfunits[SFUNIT(dev)];
                    267:        /*
                    268:         * make the driver get the label again on the next open
                    269:         */
                    270:        un->un_present = 0;
                    271: }
                    272: 
                    273: sfsize(dev)
                    274:        register dev_t dev;
                    275: {
                    276:        register struct scsi_unit *un;
                    277: 
                    278:        un = &sfunits[SFUNIT(dev)];
                    279:        if (!un->un_present) {
                    280:                return (-1);
                    281:        }
                    282:        return (sfloppy[SFUNIT(dev)].sf_nblk);
                    283: }
                    284: 
                    285: sfstrategy(bp)
                    286:        register struct buf *bp;
                    287: {
                    288:        register struct scsi_unit *un;
                    289:        register daddr_t bn;
                    290:        register int unit, s;
                    291:        register struct buf *dp;
                    292:        register struct scsi_floppy *dsi;
                    293: 
                    294:        unit = SFUNIT(bp->b_dev);
                    295:        if (unit >= nsfloppy) {
                    296:                printf("sf%d: sfstrategy: invalid unit\n", unit);
                    297:                bp->b_flags |= B_ERROR;
                    298:                iodone(bp);
                    299:                return;
                    300:        }
                    301:        un = &sfunits[unit];
                    302:        dsi = &sfloppy[unit];
                    303:        bn = dkblock(bp);
                    304:        if ((!un->un_present && bp != &un->un_sbuf) || (bn > dsi->sf_nblk)) {
                    305:                bp->b_flags |= B_ERROR;
                    306:                iodone(bp);
                    307:                return;
                    308:        }
                    309:        if (un->un_present) {
                    310:                if (bn == dsi->sf_nblk) {       /* EOF */
                    311:                        bp->b_resid = bp->b_bcount;
                    312:                        iodone(bp);
                    313:                        return;
                    314:                }
                    315:                bp->b_cylin = bn / (dsi->sf_spt * dsi->sf_nhead);
                    316:        } else {
                    317:                bp->b_cylin = 0;
                    318:        }
                    319:        dp = &un->un_utab;
                    320:        s = splx(pritospl(un->un_mc->mc_intpri));
                    321:        disksort(dp, bp);
                    322:        if (dp->b_active == 0) {
                    323:                (*un->un_c->c_ss->scs_ustart)(un);
                    324:                bp = &un->un_mc->mc_tab;
                    325:                if (bp->b_actf && bp->b_active == 0) {
                    326:                        (*un->un_c->c_ss->scs_start)(un);
                    327:                }
                    328:        }
                    329:        (void) splx(s);
                    330: }
                    331: 
                    332: /*
                    333:  * Do a special command.
                    334:  */
                    335: sfcmd(dev, cmd, sector, len, addr)
                    336:        register dev_t dev;
                    337:        register int cmd, sector, len;
                    338:        register caddr_t addr;
                    339: {
                    340:        register struct scsi_unit *un;
                    341:        register struct buf *bp;
                    342:        register int s;
                    343: 
                    344:        un = &sfunits[SFUNIT(dev)];
                    345:        bp = &un->un_sbuf;
                    346:        s = splx(pritospl(un->un_mc->mc_intpri));
                    347:        while (bp->b_flags&B_BUSY) {
                    348:                bp->b_flags |= B_WANTED;
                    349:                sleep((caddr_t)bp, PRIBIO);
                    350:        }
                    351:        bp->b_flags = B_BUSY|B_READ;
                    352:        (void) splx(s);
                    353:        un->un_scmd = cmd;
                    354:        bp->b_dev = dev;
                    355:        bp->b_blkno = sector;
                    356:        bp->b_un.b_addr = addr;
                    357:        bp->b_bcount = len;
                    358:        sfstrategy(bp);
                    359:        iowait(bp);
                    360:        bp->b_flags &= ~B_BUSY;
                    361:        if (bp->b_flags&B_WANTED)
                    362:                wakeup((caddr_t)bp);
                    363:        return (bp->b_flags & B_ERROR);
                    364: }
                    365: 
                    366: /*
                    367:  * Set up a transfer for the controller
                    368:  */
                    369: sfstart(bp, un)
                    370:        register struct buf *bp;
                    371:        register struct scsi_unit *un;
                    372: {
                    373:        register int nblk;
                    374:        register struct scsi_floppy *dsi;
                    375: 
                    376:        dsi = &sfloppy[SFUNIT(bp->b_dev)];
                    377:        un->un_blkno = dkblock(bp);
                    378:        if (bp == &un->un_sbuf) {
                    379:                un->un_cmd = un->un_scmd;
                    380:        } else if (bp->b_flags & B_READ) {
                    381:                un->un_cmd = SC_READ;
                    382:        } else {
                    383:                un->un_cmd = SC_WRITE;
                    384:        }
                    385:        if (un->un_cmd == SC_READ || un->un_cmd == SC_WRITE) {
                    386:                nblk = howmany(bp->b_bcount, PC_SECSIZE);
                    387:                un->un_count = MIN(nblk, dsi->sf_nblk - bp->b_blkno);
                    388:                bp->b_resid = bp->b_bcount - un->un_count * PC_SECSIZE;
                    389:                un->un_flags |= SC_UNF_DVMA;
                    390:        } else {
                    391:                if (un->un_cmd == SC_INIT_CHARACTERISTICS)
                    392:                        un->un_flags |= SC_UNF_DVMA;
                    393:                un->un_count = bp->b_bcount;
                    394:        }
                    395:        return (1);
                    396: }
                    397: 
                    398: /*
                    399:  * Make a cdb for disk i/o.
                    400:  */
                    401: sfmkcdb(c, un)
                    402:        register struct scsi_ctlr *c;
                    403:        struct scsi_unit *un;
                    404: {
                    405:        register struct scsi_cdb *cdb;
                    406: 
                    407:        cdb = &c->c_cdb;
                    408:        bzero((caddr_t)cdb, sizeof (*cdb));
                    409:        un->un_dma_addr = 0;
                    410:        un->un_dma_count = 0;
                    411:        cdb->cmd = un->un_cmd;
                    412:        cdb->lun = un->un_lun;
                    413:        switch (un->un_cmd) {
                    414:        case SC_TEST_UNIT_READY:
                    415:        case SC_REZERO_UNIT:
                    416:        case SC_REQUEST_SENSE:
                    417:                break;
                    418:        case SC_SEEK:
                    419:                cdbaddr(cdb, un->un_blkno);
                    420:                break;
                    421:        case SC_READ:
                    422:        case SC_WRITE:
                    423:                cdbaddr(cdb, un->un_blkno);
                    424:                cdb->count = un->un_count;
                    425:                un->un_dma_addr = un->un_baddr;
                    426:                un->un_dma_count = un->un_count * PC_SECSIZE;
                    427:                break;
                    428:        case SC_INIT_CHARACTERISTICS:
                    429:                un->un_dma_addr = un->un_baddr;
                    430:                un->un_dma_count = un->un_count;
                    431:                break;
                    432:        default:
                    433:                panic("sfmkcdb");
                    434:                break;
                    435:        }
                    436: }
                    437: 
                    438: /*
                    439:  * Interrupt processing.
                    440:  */
                    441: sfintr(c, resid, error)
                    442:        register struct scsi_ctlr *c;
                    443:        register int resid, error;
                    444: {
                    445:        register struct scsi_unit *un;
                    446:        register struct buf *bp;
                    447:        register struct mb_device *md;
                    448: 
                    449:        un = c->c_un;
                    450:        bp = un->un_mc->mc_tab.b_actf->b_actf;
                    451:        md = un->un_md;
                    452:        if (md->md_dk >= 0) {
                    453:                dk_busy &= ~(1 << md->md_dk);
                    454:        }
                    455:        if (error == SE_FATAL) {
                    456:                if (bp == &un->un_sbuf &&
                    457:                    ((un->un_flags & SC_UNF_DVMA) == 0)) {
                    458:                        (*c->c_ss->scs_done)(un->un_mc);
                    459:                } else {
                    460:                        mbdone(un->un_mc);
                    461:                        un->un_flags &= ~SC_UNF_DVMA;
                    462:                }
                    463:                bp->b_flags |= B_ERROR;
                    464:                printf("sf%d: SCSI FAILURE\n", SFNUM(un));
                    465:                (*c->c_ss->scs_off)(un);
                    466:                return;
                    467:        }
                    468:        if (error == SE_RETRYABLE || c->c_scb.chk || resid > 0) {
                    469:                sferror(c, un, bp);
                    470:                return;
                    471:        }
                    472:        if (c->c_cdb.cmd == SC_REZERO_UNIT &&
                    473:            !(bp == &un->un_sbuf &&
                    474:            un->un_scmd == SC_REZERO_UNIT)) {
                    475:                /* error recovery */
                    476:                sfmkcdb(c, un);
                    477:                if ((*c->c_ss->scs_cmd)(c, un, 1) == 0) {
                    478:                        printf("sf%d sfintr: scsi cmd failed 1\n", SFNUM(un));
                    479:                        (*c->c_ss->scs_off)(un);
                    480:                }
                    481:                return;
                    482:        }
                    483:        /* transfer worked */
                    484:        un->un_retries = un->un_restores = 0;
                    485:        if (un->un_sec_left) {  /* single sector stuff */
                    486:                un->un_sec_left--;
                    487:                un->un_baddr += PC_SECSIZE;
                    488:                un->un_blkno++;
                    489:                sfmkcdb(c, un);
                    490:                if ((*c->c_ss->scs_cmd)(c, un, 1) == 0) {
                    491:                        printf("sf%d: sfintr: scsi cmd failed 2\n", SFNUM(un));
                    492:                        (*c->c_ss->scs_off)(un);
                    493:                }
                    494:        } else if (bp == &un->un_sbuf &&
                    495:            ((un->un_flags & SC_UNF_DVMA) == 0)) {
                    496:                (*c->c_ss->scs_done)(un->un_mc);
                    497:        } else {
                    498:                mbdone(un->un_mc);
                    499:                un->un_flags &= ~SC_UNF_DVMA;
                    500:        }
                    501: }
                    502: 
                    503: /*
                    504:  * Error handling.
                    505:  */
                    506: sferror(c, un, bp)
                    507:        register struct scsi_ctlr *c;
                    508:        register struct scsi_unit *un;
                    509:        register struct buf *bp;
                    510: {
                    511: 
                    512:        if (un->un_present == 0) {      /* error trying to open */
                    513:                bp->b_flags |= B_ERROR;
                    514:                if (bp == &un->un_sbuf &&
                    515:                    ((un->un_flags & SC_UNF_DVMA) == 0)) {
                    516:                        (*c->c_ss->scs_done)(un->un_mc);
                    517:                } else {
                    518:                        mbdone(un->un_mc);
                    519:                        un->un_flags &= ~SC_UNF_DVMA;
                    520:                }
                    521:        } else if (un->un_retries++ < MAX_RETRIES) {
                    522:                /* retry */
                    523:                if (sferrlvl >= EL_RETRY) {
                    524:                        sferrmsg(c, un, bp, "retry");
                    525:                }
                    526:                if ((*c->c_ss->scs_cmd)(c, un, 1) == 0) {
                    527:                        printf("sf%d: sferror: scsi cmd failed 2\n", SFNUM(un));
                    528:                        (*c->c_ss->scs_off)(un);
                    529:                }
                    530:        } else if (un->un_restores++ < MAX_RESTORES) {
                    531:                /* retries exhausted, try restore */
                    532:                un->un_retries = 0;
                    533:                if (sferrlvl >= EL_REST) {
                    534:                        sferrmsg(c, un, bp, "restore");
                    535:                }
                    536:                c->c_cdb.cmd = SC_REZERO_UNIT;
                    537:                cdbaddr(&c->c_cdb, 0);
                    538:                c->c_cdb.count = 0;
                    539:                un->un_dma_addr = un->un_dma_count = 0;
                    540:                if ((*c->c_ss->scs_cmd)(c, un, 1) == 0) {
                    541:                        printf("sf%d: sferror: scsi cmd failed 3\n", SFNUM(un));
                    542:                        (*c->c_ss->scs_off)(un);
                    543:                }
                    544:        } else {
                    545:                /* complete failure */
                    546:                if (sferrlvl >= EL_FAIL) {
                    547:                        sferrmsg(c, un, bp, "failed");
                    548:                }
                    549:                (*c->c_ss->scs_off)(un);
                    550:                bp->b_flags |= B_ERROR;
                    551:                if (bp == &un->un_sbuf &&
                    552:                    ((un->un_flags & SC_UNF_DVMA) == 0)) {
                    553:                        (*c->c_ss->scs_done)(un->un_mc);
                    554:                } else {
                    555:                        mbdone(un->un_mc);
                    556:                        un->un_flags &= ~SC_UNF_DVMA;
                    557:                }
                    558:        }
                    559: }
                    560: 
                    561: sfread(dev, uio)
                    562:        dev_t dev;
                    563:        struct uio *uio;
                    564: {
                    565: 
                    566:        return (sfrw(dev, uio, B_READ));
                    567: }
                    568: 
                    569: sfrw(dev, uio, direction)
                    570:        dev_t dev;
                    571:        struct uio *uio;
                    572:        int direction;
                    573: {
                    574:        register struct scsi_unit *un;
                    575:        register int unit;
                    576: 
                    577:        unit = SFUNIT(dev);
                    578:        if (unit >= nsfloppy) {
                    579:                return (ENXIO);
                    580:        }
                    581:        un = &sfunits[unit];
                    582:        if ((uio->uio_offset % DEV_BSIZE) != 0) {
                    583:                return (EINVAL);
                    584:        }
                    585:        if ((uio->uio_iov->iov_len % DEV_BSIZE) != 0) {
                    586:                return (EINVAL);
                    587:        }
                    588:        return (physio(sfstrategy, &un->un_rbuf, dev, direction, minphys,uio));
                    589: }
                    590: 
                    591: sfwrite(dev, uio)
                    592:        dev_t dev;
                    593:        struct uio *uio;
                    594: {
                    595: 
                    596:        return (sfrw(dev, uio, B_WRITE));
                    597: }
                    598: 
                    599: /*ARGSUSED*/
                    600: sfioctl(dev, cmd, data, flag)
                    601:        register dev_t dev;
                    602:        register caddr_t data;
                    603: {
                    604:        register struct scsi_unit *un;
                    605:        register struct dk_info *inf;
                    606:        register int unit;
                    607: 
                    608:        unit = SFUNIT(dev);
                    609:        if (unit >= nsfloppy) {
                    610:                return (ENXIO);
                    611:        }
                    612:        un = &sfunits[unit];
                    613:        switch (cmd) {
                    614: 
                    615:        case DKIOCINFO:
                    616:                inf = (struct dk_info *)data;
                    617:                inf->dki_ctlr = getdevaddr(un->un_mc->mc_addr);
                    618:                inf->dki_unit = un->un_md->md_slave;
                    619:                inf->dki_ctype = DKC_SCSI;
                    620:                inf->dki_flags = DKI_FMTVOL;
                    621:                break;
                    622: 
                    623:        default:
                    624:                return (ENOTTY);
                    625:        }
                    626:        return (0);
                    627: }
                    628: 
                    629: static char *sf_class_00_errors[] = {
                    630:        "invalid sense code",
                    631:        "invalid sense code",
                    632:        "no seek complete",
                    633:        "invalid sense code",
                    634:        "drive not ready",
                    635:        "invalid sense code",
                    636:        "no track 00",
                    637:        "door open",
                    638:        "media not loaded",
                    639: };
                    640: 
                    641: static char *sf_class_01_errors[] = {
                    642:        "I.D. CRC error",
                    643:        "write fault",
                    644:        "write protected",
                    645:        "invalid sense code",
                    646:        "sector not found",
                    647:        "seek error",
                    648:        "(0x16) unformatted or bad format on drive",
                    649:        "(0x17) unformatted or bad format on drive",
                    650:        "invalid sense code",
                    651:        "two sided error",
                    652:        "wrong data mark found",
                    653:        "pad error",
                    654:        "invalid sense code",
                    655:        "lost data in FDC",
                    656:        "CRC error",
                    657:        "FDC failure",
                    658: };
                    659: 
                    660: static char *sf_class_02_errors[] = {
                    661:        "invalid command",
                    662:        "illegal block address",
                    663:        "invalid cdb",
                    664:        "invalid interleave",
                    665: };
                    666: 
                    667: static char *sf_class_03_errors[] = {
                    668:        "RAM error",
                    669:        "controller program memory checksum error",
                    670: };
                    671: 
                    672: static char **sf_errors[] = {
                    673:        sf_class_00_errors,
                    674:        sf_class_01_errors,
                    675:        sf_class_02_errors,
                    676:        sf_class_03_errors,
                    677: };
                    678: 
                    679: int sf_errct[] = {
                    680:        sizeof sf_class_00_errors / sizeof (char *),
                    681:        sizeof sf_class_01_errors / sizeof (char *),
                    682:        sizeof sf_class_02_errors / sizeof (char *),
                    683:        sizeof sf_class_03_errors / sizeof (char *),
                    684: };
                    685: 
                    686: char *sf_cmds[] = {
                    687:        "test unit ready",
                    688:        "rezero unit",
                    689:        "bad cmd",
                    690:        "request sense",
                    691:        "bad cmd",
                    692:        "bad cmd",
                    693:        "bad cmd",
                    694:        "bad cmd",
                    695:        "read",
                    696:        "bad cmd",
                    697:        "write",
                    698:        "seek",
                    699:        "initialize characteristics",
                    700: };
                    701: 
                    702: /*ARGSUSED*/
                    703: sferrmsg(c, un, bp, action)
                    704:        register struct scsi_ctlr *c;
                    705:        struct scsi_unit *un;
                    706:        struct buf *bp;
                    707:        char *action;
                    708: {
                    709:        char *sensemsg, *cmdname;
                    710:        register struct scsi_sense *sense;
                    711:        register int blkno;
                    712: 
                    713:        sense = c->c_sense;
                    714:        if (c->c_scb.chk == 0) {
                    715:                sensemsg = "invalid sense code";
                    716:        } else if (sense->class <= 3) {
                    717:                if (sense->code < sf_errct[sense->class]) {
                    718:                        sensemsg = sf_errors[sense->class][sense->code];
                    719:                } else {
                    720:                        sensemsg = "invalid sense code";
                    721:                }
                    722:        } else {
                    723:                sensemsg = "invalid sense class";
                    724:        }
                    725:        if (un->un_cmd < sizeof(sf_cmds)) {
                    726:                cmdname = sf_cmds[un->un_cmd];
                    727:        } else {
                    728:                cmdname = "bad cmd";
                    729:        }
                    730:        blkno = (sense->high_addr << 16) | (sense->mid_addr << 8) |
                    731:            sense->low_addr;
                    732:        printf("sf%d: %s %s (%s) blk %d\n", SFNUM(un),
                    733:            cmdname, action, sensemsg, blkno);
                    734: }
                    735: #endif NSF > 0

unix.superglobalmegacorp.com

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