Annotation of researchv9/sys/sundev/sf.c, revision 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.