Annotation of coherent/d/286_KERNEL/USRSRC/io/st.c, revision 1.1.1.1

1.1       root        1: /* (-lgl
                      2:  *     COHERENT Driver Kit Version 1.1.0
                      3:  *     Copyright (c) 1982, 1990 by Mark Williams Company.
                      4:  *     All rights reserved. May not be copied without permission.
                      5:  -lgl) */
                      6: /*
                      7:  * This is a driver for the
                      8:  * Archive SC-400 Series Tape Controller.
                      9:  */
                     10: #include       <sys/coherent.h>
                     11: #include       <sys/buf.h>
                     12: #include       <sys/con.h>
                     13: #include       <sys/const.h>
                     14: #include       <sys/devices.h>
                     15: #include       <sys/inode.h>
                     16: #include       <sys/mtioctl.h>
                     17: #include       <sys/sched.h>
                     18: #include       <sys/seg.h>
                     19: #include       <sys/stat.h>
                     20: #include       <sys/uproc.h>
                     21: #include       <errno.h>
                     22: 
                     23: /*
                     24:  * Fixed parameters.
                     25:  */
                     26: #define        NCMDS   8                       /* Max # chained commands */
                     27: 
                     28: /*
                     29:  * Configurable parameters
                     30:  */
                     31: int    STIRQ   = 3;                    /* IRQ Level 3 */
                     32: int    STPORT  = 0x200;                /* I/O Port    */
                     33: int    STDMA   = 1;                    /* DMA Channel */
                     34: 
                     35: #define        BIT(n)          (1 << (n))
                     36: 
                     37: /*
                     38:  * Forward referenced functions.
                     39:  */
                     40: void   stcache();
                     41: void   stflush();
                     42: void   stinvoke();
                     43: void   ststart();
                     44: void   stintr();
                     45: void   strecov();
                     46: void   stnext();
                     47: void   stdiag();
                     48: void   stspin();
                     49: 
                     50: /*
                     51:  * Driver configuration.
                     52:  */
                     53: int    stload();
                     54: int    stuload();
                     55: int    stopen();
                     56: int    stclose();
                     57: int    stread();
                     58: int    stwrite();
                     59: int    stioctl();
                     60: void   stwatch();
                     61: int    nulldev();
                     62: int    nonedev();
                     63: 
                     64: CON    stcon   = {
                     65:        DFCHR,                          /* Flags        */
                     66:        ST_MAJOR,                               /* Major index  */
                     67:        stopen,                         /* Open         */
                     68:        stclose,                        /* Close        */
                     69:        nonedev,                        /* Block        */
                     70:        stread,                         /* Read         */
                     71:        stwrite,                        /* Write        */
                     72:        stioctl,                        /* Ioctl        */
                     73:        nulldev,                        /* Powerfail    */
                     74:        stwatch,                        /* Timeout      */
                     75:        stload,                         /* Load         */
                     76:        stuload                         /* Unload       */
                     77: };
                     78: 
                     79: /*
                     80:  * I/O Port Addresses
                     81:  */
                     82: #define        DATA_REG        (STPORT+0)      /* Data register */
                     83: #define        CTRL_REG        (STPORT+1)      /* Control/Status register */
                     84: #define        DMAGO_REG       (STPORT+2)      /* DMA Go register */
                     85: #define        DMARST_REG      (STPORT+3)      /* DMA reset register */
                     86: 
                     87: /*
                     88:  * Control Register
                     89:  */
                     90: #define        CR_RSTSAC       BIT(7)          /* 1 -> reset control micro     */
                     91: #define        CR_REQ          BIT(6)          /* 1 -> request to LSI chip     */
                     92: #define        CR_IEN          BIT(5)          /* 1 -> enables interrupts      */
                     93: #define        CR_DNIEN        BIT(4)          /* 1 -> enable DONE interrupts  */
                     94: 
                     95: /*
                     96:  * Status Register
                     97:  */
                     98: #define        SR_IRQF         BIT(7)          /* 1 -> Interrupt Request Flag  */
                     99: #define        SR_NRDY         BIT(6)          /* 0 -> Ready                   */
                    100: #define        SR_NEXC         BIT(5)          /* 0 -> Exception               */
                    101: #define        SR_DONE         BIT(4)          /* 1 -> DMA Done                */
                    102: #define        SR_TO_PC        BIT(3)          /* 1 -> Direction is to PC      */
                    103: 
                    104: /*
                    105:  * Controller Commands.
                    106:  */
                    107: #define        CC_SELECT       0x01            /* Select Drive 0               */
                    108: #define        CC_LOCK         0x11            /* Select Drive 0 and Lock      */
                    109: #define        CC_BOT          0x21            /* Rewind to beginning of tape  */
                    110: #define        CC_ERASE        0x22            /* Completely erase cartridge   */
                    111: #define        CC_TENSION      0x24            /* Wind tape to BOT, EOT, BOT   */
                    112: #define        CC_AUTO         0x25            /* Select auto-initialization   */
                    113: #define        CC_QIC11        0x26            /* Select QIC-11 media format   */
                    114: #define        CC_QIC24        0x27            /* Select QIC-24 media format   */
                    115: #define        CC_WRITE        0x40            /* Write to tape                */
                    116: #define        CC_WFM          0x60            /* Write file mark              */
                    117: #define        CC_READ         0x80            /* Read from tape               */
                    118: #define        CC_RFM          0xA0            /* Skip past next file mark     */
                    119: #define        CC_SENSE        0xC0            /* Read controller status       */
                    120: 
                    121: /*
                    122:  * Sense Status Bytes 0 and 1.
                    123:  */
                    124: #define        SS0_FIL         BIT(0)          /* File Mark Detected           */
                    125: #define        SS0_BNL         BIT(1)          /* Bad Block Not located        */
                    126: #define        SS0_UDA         BIT(2)          /* Unrecoverable data error     */
                    127: #define        SS0_EOM         BIT(3)          /* End of media                 */
                    128: #define        SS0_WRP         BIT(4)          /* Write Protected Cartridge    */
                    129: #define        SS0_USL         BIT(5)          /* Unselected Drive             */
                    130: #define        SS0_CNI         BIT(6)          /* Cartridge Not In Place       */
                    131: #define        SS0_ERR         (SS0_BNL+SS0_UDA+SS0_USL+SS0_CNI)
                    132: 
                    133: #define        SS1_POR         BIT(0)          /* Power on Reset Occurred      */
                    134: #define        SS1_BOM         BIT(3)          /* Beginning of media           */
                    135: #define        SS1_MBD         BIT(4)          /* Marginal Block Detected      */
                    136: #define        SS1_NDT         BIT(5)          /* No Data Detected             */
                    137: #define        SS1_ILL         BIT(6)          /* Illegal Command              */
                    138: #define        SS1_ERR         (SS1_NDT+SS1_ILL)
                    139: 
                    140: /*
                    141:  * Device States.
                    142:  */
                    143: #define        SDEAD   0               /* controller not found    */
                    144: #define        SIDLE   1               /* controller idle         */
                    145: #define        SCMD    2               /* initiating command      */
                    146: #define        SRUN    3               /* performing command      */
                    147: #define        SRDWR   4               /* starting read/write     */
                    148: #define        SBLOCK  5               /* performing read/write   */
                    149: #define        SBLEND  6               /* concluding block i/o    */
                    150: #define        SSENSE  7               /* reading status bytes    */
                    151: #define        SSDONE  8               /* concluding status sense */
                    152: 
                    153: /*
                    154:  * Driver State Information.
                    155:  */
                    156: struct st_s {
                    157:        int     st_state;
                    158:        int     st_mode;                /* IPR or IPW                   */
                    159:        int     st_iocmd;               /* CC_READ or CC_WRITE          */
                    160:        int     st_cmd;                 /* last command executed        */
                    161:        int     st_cmds[NCMDS];         /* list of chained commands     */
                    162:        int     st_ncmds;               /* num of chained commands      */
                    163:        int     st_iswr;
                    164:        int     st_wasio;
                    165:        int     st_iseof;
                    166:        int     st_error;
                    167:        paddr_t st_paddr;
                    168:        fsize_t st_resid;
                    169:        fsize_t st_size;
                    170:        saddr_t st_sel;
                    171:        SEG *   st_seg;
                    172:        char    st_status[6];
                    173:        int     st_nstat;
                    174:        int     st_rdys;                /* number of ready watchdogs    */
                    175:        int     st_nlost;               /* number of lost interrupts    */
                    176: } st;
                    177: 
                    178: /**
                    179:  *
                    180:  * void
                    181:  * stload()            -- initialize tape device
                    182:  *
                    183:  *     Action: Reset tape controller and drive.
                    184:  *             Seize tape interrupt vector.
                    185:  *
                    186:  *     Note:   If the tape controller is present and operational,
                    187:  *             a interrupt will occur and set st.st_state to SIDLE.
                    188:  */
                    189: static
                    190: stload()
                    191: {
                    192:        /*
                    193:         * Paranoia - Turn off DMA.
                    194:         * Should already be turned off.
                    195:         */
                    196:        dmaoff( STDMA );
                    197: 
                    198:        /*
                    199:         * Reset tape controller and drive
                    200:         */
                    201:        outb( CTRL_REG, CR_RSTSAC );
                    202: 
                    203:        /*
                    204:         * Wait at least 25 microseconds
                    205:         */
                    206:        stspin( 25 );
                    207: 
                    208:        /*
                    209:         * Terminate reset condition
                    210:         */
                    211:        outb( CTRL_REG, CR_IEN );
                    212: 
                    213:        /*
                    214:         * Seize tape interrupt vector.
                    215:         */
                    216:        setivec( STIRQ, &stintr );
                    217: }
                    218: 
                    219: /**
                    220:  *
                    221:  * stuload( dev )              -- Unload tape device.
                    222:  * dev_t dev;
                    223:  */
                    224: stuload( dev )
                    225: dev_t dev;
                    226: {
                    227:        /*
                    228:         * Turn off DMA.
                    229:         */
                    230:        dmaoff( STDMA );
                    231: 
                    232:        /*
                    233:         * Release tape interrupt vector.
                    234:         */
                    235:        clrivec( STIRQ );
                    236: 
                    237:        /*
                    238:         * Disable tape interrupts.
                    239:         */
                    240:        outb( CTRL_REG, 0 );
                    241: }
                    242: 
                    243: /**
                    244:  *
                    245:  * stopen( dev, mode )         -- open tape device
                    246:  * dev_t dev;
                    247:  * int mode;
                    248:  *
                    249:  *     Input:  dev  = tape device to be opened.
                    250:  *             mode = desired access mode.
                    251:  *
                    252:  *     Action: Refuse access if tape drive does not exist or is in use.
                    253:  *             Refuse simultaneous read and write access.
                    254:  *             Refuse access if cartridge is not inserted in tape drive.
                    255:  *             Refuse write access to a write protected cartridge.
                    256:  *             Allocate tape cache.
                    257:  *             Initialize device state.
                    258:  *             Lock tape cartridge.
                    259:  */
                    260: static
                    261: stopen( dev, mode )
                    262: register dev_t dev;
                    263: register int   mode;
                    264: {
                    265:        int s;
                    266: 
                    267:        /*
                    268:         * Refuse access if no tape drive.
                    269:         */
                    270:        if ( st.st_state == SDEAD ) {
                    271:                u.u_error = ENXIO;
                    272:                return;
                    273:        }
                    274: 
                    275:        /*
                    276:         * Refuse access if tape drive is already open.
                    277:         */
                    278:        if ( st.st_mode != 0 ) {
                    279:                u.u_error = EDBUSY;
                    280:                return;
                    281:        }
                    282: 
                    283:        /*
                    284:         * Access must be read-only or write-only.
                    285:         */
                    286:        if ( (mode != IPR) && (mode != IPW) ) {
                    287:                u.u_error = EINVAL;
                    288:                return;
                    289:        }
                    290: 
                    291:        /*
                    292:         * Wait for tape drive to become idle.
                    293:         */
                    294:        if ( stwait() < 0 ) {
                    295:                u.u_error = EINTR;
                    296:                return;
                    297:        }
                    298: 
                    299:        /*
                    300:         * Initialize tape interface.
                    301:         */
                    302:        s = sphi();
                    303:        outb( DMARST_REG, 0 );
                    304:        outb( CTRL_REG, CR_IEN );
                    305:        spl( s );
                    306: 
                    307:        /*
                    308:         * Obtain tape status.
                    309:         */
                    310:        stinvoke( CC_SENSE );
                    311: 
                    312:        /*
                    313:         * Wait for tape status.
                    314:         */
                    315:        if ( stwait() < 0 ) {
                    316:                u.u_error = EINTR;
                    317:                return;
                    318:        }
                    319: 
                    320:        /*
                    321:         * Refuse access if no cartridge.
                    322:         */
                    323:        if ( st.st_status[0] & (SS0_CNI|SS0_USL) ) {
                    324:                u.u_error = EDATTN;
                    325:                return;
                    326:        }
                    327: 
                    328:        /*
                    329:         * Refuse write access to a write protected cartridge.
                    330:         */
                    331:        if ( (mode == IPW) && (st.st_status[0] & SS0_WRP) ) {
                    332:                u.u_error = EROFS;
                    333:                return;
                    334:        }
                    335: 
                    336:        /*
                    337:         * Calculate desired cache size in Kbytes.
                    338:         */
                    339:        st.st_size = minor(dev) & ~0x80;
                    340:        if ( st.st_size == 0 )
                    341:                st.st_size = 256;
                    342: 
                    343:        /*
                    344:         * Allocate cache
                    345:         */
                    346:        for ( st.st_size *= 1024; st.st_size != 0; st.st_size -= 1024 )
                    347:                if ( st.st_seg = salloc( st.st_size, SFSYST|SFNSWP|SFNCLR ) )
                    348:                        break;
                    349: 
                    350:        /*
                    351:         * Refuse access if couldn't allocate cache.
                    352:         */
                    353:        if ( st.st_seg == 0 ) {
                    354:                u.u_error = ENOMEM;
                    355:                return;
                    356:        };
                    357: 
                    358:        /*
                    359:         * Initialize device state.
                    360:         */
                    361:        st.st_sel   = FP_SEL(st.st_seg->s_faddr);
                    362:        st.st_iswr  = (mode == IPW);
                    363:        st.st_paddr = st.st_seg->s_paddr;
                    364:        st.st_resid = (mode == IPW) ? st.st_size : 0 ;
                    365:        st.st_iocmd = (mode == IPW) ? CC_WRITE : CC_READ ;
                    366:        st.st_mode  = mode;
                    367:        st.st_iseof = 0;
                    368:        st.st_wasio = 0;
                    369:        st.st_error = 0;
                    370:        st.st_rdys  = 0;
                    371:        st.st_nlost = 0;
                    372: 
                    373:        /*
                    374:         * Lock cartridge if at beginning of media.
                    375:         */
                    376:        if ( st.st_status[1] & SS1_BOM )
                    377:                stinvoke( CC_LOCK );
                    378: }
                    379: 
                    380: /**
                    381:  *
                    382:  * stclose( dev, mode )                -- close tape device
                    383:  * dev_t dev;
                    384:  * int mode;
                    385:  *
                    386:  *     Input:  dev  = tape device to be closed.
                    387:  *             mode = access mode.
                    388:  *
                    389:  *     Action: If access mode was for writing, flush the tape cache.
                    390:  *             If data was written to tape, write a file mark.
                    391:  *             If data was read from tape on the non rewinding device,
                    392:  *             read until end of file or an error is encountered.
                    393:  *             Rewind the tape if the rewinding device is open.
                    394:  *             Unlock the tape cartridge.
                    395:  *             Clear tape state and release tape cache memory.
                    396:  */
                    397: static
                    398: stclose( dev, mode )
                    399: register dev_t dev;
                    400: {
                    401:        /*
                    402:         * Check if tape was opened for writing.
                    403:         */
                    404:        if ( st.st_iswr ) {
                    405: 
                    406:                /*
                    407:                 * Flush the tape cache.
                    408:                 */
                    409:                stflush();
                    410: 
                    411:                /*
                    412:                 * Write a file mark if data was written to tape.
                    413:                 */
                    414:                if ( st.st_wasio )
                    415:                        stinvoke( CC_WFM );
                    416:        }
                    417: 
                    418:        /*
                    419:         * Check if non-rewinding device was opened for reading.
                    420:         */
                    421:        else if ( st.st_wasio && (dev & 0x80 ) ) {
                    422: 
                    423:                /*
                    424:                 * Read file mark if not just past one.
                    425:                 */
                    426:                if ( (st.st_status[0] & SS0_FIL) == 0 )
                    427:                        stinvoke( CC_RFM );
                    428:        }
                    429: 
                    430:        /*
                    431:         * Rewinding device.
                    432:         */
                    433:        if ( (dev & 0x80) == 0 ) {
                    434: 
                    435:                /*
                    436:                 * Wait for controller to idle.
                    437:                 */
                    438:                while ( stwait() < 0 )
                    439:                        ;
                    440: 
                    441:                /*
                    442:                 * Initiate rewind.
                    443:                 */
                    444:                stinvoke( CC_BOT   );
                    445: 
                    446:                /*
                    447:                 * Unlock the drive [turn off the light].
                    448:                 */
                    449:                stinvoke( CC_SELECT );
                    450:        }
                    451: 
                    452:        /*
                    453:         * Clear tape state, releasing tape cache.
                    454:         */
                    455:        sfree( st.st_seg );
                    456:        st.st_seg  = 0;
                    457:        st.st_mode = 0;
                    458: }
                    459: 
                    460: /**
                    461:  *
                    462:  * stread( dev, iop )  -- tape device read
                    463:  * dev_t dev;
                    464:  * IO * iop;
                    465:  *
                    466:  *     Input:  dev = tape device to be read from.
                    467:  *             iop = pointer to IO structure.
                    468:  *
                    469:  *     Action: Transfer data from tape cache to user memory,
                    470:  *             filling the cache as required by initiating reads from tape.
                    471:  */
                    472: 
                    473: static
                    474: stread( dev, iop )
                    475: dev_t  dev;
                    476: register IO * iop;
                    477: {
                    478:        register int n;
                    479:        register int ioc;
                    480: 
                    481:        ioc = iop->io_ioc;
                    482:        
                    483:        while ( iop->io_ioc > 0 ) {
                    484: 
                    485:                /*
                    486:                 * Check for empty cache.
                    487:                 */
                    488:                while ( st.st_resid == 0 ) {
                    489: 
                    490:                        /*
                    491:                         * Special handling if end of file was encountered.
                    492:                         */
                    493:                        if ( st.st_iseof ) {
                    494: 
                    495:                                /*
                    496:                                 * Clear EOF if no data was transferred yet.
                    497:                                 */
                    498:                                if ( ioc == iop->io_ioc )
                    499:                                        st.st_iseof = 0;
                    500: 
                    501:                                return;
                    502:                        }
                    503: 
                    504:                        /*
                    505:                         * Abort on I/O error.
                    506:                         */
                    507:                        if ( u.u_error = st.st_error ) {
                    508:                                stdiag();
                    509:                                return;
                    510:                        }
                    511: 
                    512:                        /*
                    513:                         * Fill the cache from tape.
                    514:                         */
                    515:                        stcache();
                    516:                }
                    517: 
                    518:                /*
                    519:                 * Determine max data transferable in one chunk.
                    520:                 */
                    521:                n = iop->io_ioc;
                    522:                if ( n > st.st_resid )
                    523:                        n = st.st_resid;
                    524: 
                    525:                /*
                    526:                 * Transfer some data from cache to user memory.
                    527:                 */
                    528:                if ( pucopy( st.st_paddr, iop->io_base, n ) != n )
                    529:                        return;
                    530: 
                    531:                /*
                    532:                 * Update addresses and counts.
                    533:                 */
                    534:                iop->io_base += n;
                    535:                iop->io_ioc  -= n;
                    536:                st.st_resid  -= n;
                    537:                st.st_paddr  += n;
                    538:        }
                    539: }
                    540: 
                    541: /**
                    542:  *
                    543:  * stwrite( dev, iop ) -- write to tape device
                    544:  * dev_t dev;
                    545:  * IO * iop;
                    546:  *
                    547:  *     Input:  dev = tape device to be written to.
                    548:  *             iop = pointer to IO structure.
                    549:  *
                    550:  *     Action: Transfer data from user memory to tape cache,
                    551:  *             flushing the cache as required by initiating writes to tape.
                    552:  */
                    553: 
                    554: static
                    555: stwrite( dev, iop )
                    556: dev_t  dev;
                    557: register IO *iop;
                    558: {
                    559:        register int n;
                    560: 
                    561:        while ( iop->io_ioc > 0 ) {
                    562: 
                    563:                /*
                    564:                 * Determine max data transferable in one chunk.
                    565:                 */
                    566:                n = iop->io_ioc;
                    567:                if ( n > st.st_resid )
                    568:                        n = st.st_resid;
                    569: 
                    570:                /*
                    571:                 * Transfer some data from user memory to cache.
                    572:                 */
                    573:                if ( upcopy( iop->io_base, st.st_paddr, n ) != n )
                    574:                        break;
                    575: 
                    576:                /*
                    577:                 * Update addresses and counts.
                    578:                 */
                    579:                iop->io_base += n;
                    580:                iop->io_ioc  -= n;
                    581:                st.st_paddr  += n;
                    582:                st.st_resid  -= n;
                    583: 
                    584:                /*
                    585:                 * Flush the cache to tape if full.
                    586:                 */
                    587:                if ( st.st_resid == 0 )
                    588:                        stflush();
                    589: 
                    590:                /*
                    591:                 * Abort on I/O error.
                    592:                 */
                    593:                if ( u.u_error = st.st_error ) {
                    594:                        stdiag();
                    595:                        return;
                    596:                }
                    597:        }
                    598: }
                    599: 
                    600: /**
                    601:  *
                    602:  * stioctl( dev, cmd, arg )    -- service tape I/O control requests
                    603:  * int dev;
                    604:  * int cmd;
                    605:  * int arg;
                    606:  *
                    607:  *     Input:  dev = tape device to be serviced
                    608:  *             cmd = ioctl command
                    609:  *             arg = argument to ioctl command
                    610:  *
                    611:  *     Action: Service tape I/O control request.
                    612:  */
                    613: 
                    614: static
                    615: stioctl( dev, cmd, arg )
                    616: {
                    617:        if ( st.st_iswr )
                    618:                stflush();
                    619: 
                    620:        st.st_error = EINVAL;
                    621: 
                    622:        switch ( cmd ) {
                    623: 
                    624:        case MTERASE:
                    625:                stinvoke( CC_ERASE );
                    626:                break;
                    627: 
                    628:        case MTTENSE:
                    629:                stinvoke( CC_TENSION );
                    630:                break;
                    631: 
                    632:        case MTREWIND:
                    633:                if ( st.st_iswr && st.st_wasio ) {
                    634:                        stinvoke( CC_WFM );
                    635:                        st.st_wasio = 0;
                    636:                }
                    637:                stinvoke( CC_BOT );
                    638:                break;
                    639: 
                    640:        case MTWEOF:
                    641:                if ( st.st_iswr ) {
                    642:                        stinvoke( CC_WFM );
                    643:                        st.st_wasio = 0;
                    644:                }
                    645:                break;
                    646: 
                    647:        case MTFSKIP:
                    648:                if ( ! st.st_iswr ) {
                    649:                        if ( ! st.st_iseof )
                    650:                                stinvoke( CC_RFM );
                    651:                        st.st_iseof = 0;
                    652:                        st.st_resid = 0;
                    653:                }
                    654:                break;
                    655:        }
                    656: 
                    657:        /*
                    658:         * Record tape error code.
                    659:         */
                    660:        u.u_error = st.st_error;
                    661: }
                    662: 
                    663: /**
                    664:  *
                    665:  * void
                    666:  * stcache()   -- read from tape into cache
                    667:  *
                    668:  *     Action: Read as much data as possible into the tape cache.
                    669:  *             Set st.st_paddr to the cache address.
                    670:  *             Set st.st_resid to the number of data bytes in the cache.
                    671:  */
                    672: static void
                    673: stcache()
                    674: {
                    675:        /*
                    676:         * Try to fill cache from tape.
                    677:         */
                    678:        st.st_paddr = st.st_seg->s_paddr;
                    679:        st.st_resid = st.st_size;
                    680:        ststart();
                    681: 
                    682:        /*
                    683:         * Update cache information.
                    684:         */
                    685:        st.st_paddr = st.st_seg->s_paddr;
                    686:        st.st_resid = st.st_size - st.st_resid;
                    687: 
                    688:        /*
                    689:         * Clear the cache on I/O error.
                    690:         */
                    691:        if ( st.st_error )
                    692:                st.st_resid = 0;
                    693: }
                    694: 
                    695: /**
                    696:  *
                    697:  * void
                    698:  * stflush()   -- flush cache to tape
                    699:  *
                    700:  *     Action: Ensure tape cache is block aligned.
                    701:  *             Write cache to the tape.
                    702:  *             Set st.st_paddr to the cache address.
                    703:  *             Set st.st_resid to the number of cache bytes available.
                    704:  */
                    705: static void
                    706: stflush()
                    707: {
                    708:        static char zc;
                    709: 
                    710:        /*
                    711:         * Check for empty cache.
                    712:         */
                    713:        if ( st.st_resid == st.st_size )
                    714:                return;
                    715: 
                    716:        /*
                    717:         * Block align the cache.
                    718:         */
                    719:        while ( st.st_resid % BSIZE ) {
                    720:                kpcopy( &zc, st.st_paddr, 1 );
                    721:                st.st_paddr++;
                    722:                st.st_resid--;
                    723:        }
                    724: 
                    725:        /*
                    726:         * Flush the cache to tape.
                    727:         */
                    728:        st.st_paddr = st.st_seg->s_paddr;
                    729:        st.st_resid = st.st_size - st.st_resid;
                    730:        ststart();
                    731: 
                    732:        /*
                    733:         * Update cache information.
                    734:         */
                    735:        st.st_paddr = st.st_seg->s_paddr;
                    736:        st.st_resid = st.st_size;
                    737: }
                    738: 
                    739: /**
                    740:  *
                    741:  * void
                    742:  * stinvoke()  -- start tape control operation
                    743:  *
                    744:  *     Action: Initiate tape control operation.
                    745:  */
                    746: static void
                    747: stinvoke( cmd )
                    748: int cmd;
                    749: {
                    750:        register int s;
                    751: 
                    752:        /*
                    753:         * Disable interrupts.
                    754:         */
                    755:        s = sphi();
                    756: 
                    757:        /*
                    758:         * Wait for controller to become idle.
                    759:         */
                    760:        while ( st.st_state != SIDLE ) {
                    761: 
                    762:                /*
                    763:                 * Create chained command if possible.
                    764:                 */
                    765:                if ( st.st_ncmds < NCMDS ) {
                    766:                        st.st_cmds[ st.st_ncmds++ ] = cmd;
                    767:                        spl( s );
                    768:                        return;
                    769:                }
                    770: 
                    771:                sleep( &st, CVTTOUT, IVTTOUT, SVTTOUT );
                    772:        }
                    773: 
                    774:        /*
                    775:         * Setup for tape operation.
                    776:         */
                    777:        drvl[ST_MAJOR].d_time = 1;
                    778:        st.st_state = SCMD;
                    779:        st.st_error = 0;
                    780:        st.st_rdys  = 0;
                    781:        stspin( 100 );
                    782: 
                    783:        /*
                    784:         * Request tape operation.
                    785:         * Do NOT wait for results.
                    786:         */
                    787:        outb( DATA_REG, st.st_cmd = cmd );
                    788:        outb( CTRL_REG, CR_IEN+CR_REQ );
                    789: 
                    790:        /*
                    791:         * Enable interrupts.
                    792:         */
                    793:        spl( s );
                    794: }
                    795: 
                    796: /**
                    797:  *
                    798:  * void
                    799:  * ststart()   -- start tape read/write operation
                    800:  *
                    801:  *     Action: Initiate tape read/write operation.
                    802:  *             Wait for tape operation to complete.
                    803:  */
                    804: static void
                    805: ststart()
                    806: {
                    807:        register int s;
                    808: 
                    809:        /*
                    810:         * Disable interrupts.
                    811:         */
                    812:        s = sphi();
                    813: 
                    814:        /*
                    815:         * Wait for controller to become idle.
                    816:         */
                    817:        while ( st.st_state != SIDLE )
                    818:                sleep( &st, CVTTOUT, IVTTOUT, SVTTOUT );
                    819: 
                    820:        /*
                    821:         * Setup for tape read/write.
                    822:         */
                    823:        drvl[ST_MAJOR].d_time = 1;
                    824:        st.st_state = SRDWR;
                    825:        st.st_error = 0;
                    826:        st.st_rdys  = 0;
                    827:        stspin( 100 );
                    828: 
                    829:        /*
                    830:         * Tape read/write was last command executed.
                    831:         */
                    832:        if ( st.st_cmd == st.st_iocmd ) {
                    833:                /*
                    834:                 * Resume tape i/o operation.
                    835:                 * Simulate RDY interrupt.
                    836:                 */
                    837:                stintr();
                    838:        }
                    839:        else {
                    840:                /*
                    841:                 * Request tape operation.
                    842:                 */
                    843:                outb( DATA_REG, st.st_cmd = st.st_iocmd );
                    844:                outb( CTRL_REG, CR_IEN+CR_REQ );
                    845:        }
                    846: 
                    847:        /*
                    848:         * Wait for tape operation to complete.
                    849:         */
                    850:        while ( st.st_state != SIDLE )
                    851:                sleep( &st, CVTTOUT, IVTTOUT, SVTTOUT );
                    852: 
                    853:        /*
                    854:         * Enable interrupts.
                    855:         */
                    856:        spl( s );
                    857: }
                    858: 
                    859: /**
                    860:  *
                    861:  * void
                    862:  * stintr()    -- tape interrupt handler
                    863:  *
                    864:  *     Action: Service tape interrupts.
                    865:  *             Perform transitions to new tape states.
                    866:  *             Wake sleeping processes if appropriate.
                    867:  */
                    868: static void
                    869: stintr()
                    870: {
                    871:        register int csr;
                    872:        register int s;
                    873: 
                    874:        s   = sphi();
                    875:        csr = inb( CTRL_REG );
                    876: 
                    877:        /*
                    878:         * Initiate exception recovery.
                    879:         */
                    880:        if ( (csr & SR_NEXC) == 0 ) {
                    881:                strecov();
                    882:                spl( s );
                    883:                return;
                    884:        }
                    885: 
                    886:        /*
                    887:         * Clear ready watchdog count.
                    888:         */
                    889:        st.st_rdys = 0;
                    890: 
                    891:        /*
                    892:         * Process normal operations.
                    893:         */
                    894:        switch ( st.st_state ) {
                    895: 
                    896:        case SCMD:
                    897:                /*
                    898:                 * Command has been acknowledged.
                    899:                 * Wait for command completion.
                    900:                 */
                    901:                outb( CTRL_REG, CR_IEN );
                    902:                st.st_state = (st.st_cmd == CC_SENSE) ? SSENSE : SRUN;
                    903:                st.st_nstat = 0;
                    904:                break;
                    905: 
                    906:        case SRUN:
                    907:                /*
                    908:                 * Command has completed.
                    909:                 * Chain a sense status command if no other chained commands.
                    910:                 */
                    911:                if ( st.st_ncmds == 0 )
                    912:                        st.st_cmds[ st.st_ncmds++ ] = CC_SENSE;
                    913: 
                    914:                /*
                    915:                 * Initiate next chained command.
                    916:                 */
                    917:                stnext();
                    918:                break;
                    919: 
                    920:        case SRDWR:
                    921:                /*
                    922:                 * Read/Write command had been acknowledged.
                    923:                 * Clear tape request, enable done interrupt.
                    924:                 */
                    925:                outb( CTRL_REG, CR_IEN+CR_DNIEN );
                    926: 
                    927:                /*
                    928:                 * Define direct memory access parameters.
                    929:                 */
                    930:                dmaon( STDMA, st.st_paddr, BSIZE, st.st_iswr );
                    931: 
                    932:                /*
                    933:                 * If tape read command, wait for interface to switch direction
                    934:                 */
                    935:                if ( st.st_iocmd == CC_READ )
                    936:                        while ( (inb(CTRL_REG) & SR_TO_PC) != SR_TO_PC )
                    937:                                ;
                    938: 
                    939:                /*
                    940:                 * Enable DMA transfer on tape interface and at DMA controller chip.
                    941:                 */
                    942:                st.st_state = SBLOCK;
                    943:                outb( DMAGO_REG, 0 );
                    944:                dmago( STDMA );
                    945:                break;
                    946: 
                    947:        case SBLOCK:
                    948:                /*
                    949:                 * Perform Block I/O.
                    950:                 * Ignore RDY interrupt, wait for [DMA] DONE interrupt.
                    951:                 */
                    952:                if ( (csr & SR_DONE) == 0 )
                    953:                        break;
                    954: 
                    955:                /*
                    956:                 * Turn off DMA.
                    957:                 */
                    958:                dmaoff( STDMA );
                    959: 
                    960:                /*
                    961:                 * If more data remains to be transferred, reenable DMA.
                    962:                 * NOTE: do -= BEFORE if() to avoid potential compiler bug.
                    963:                 */
                    964:                st.st_resid -= BSIZE;
                    965:                if ( st.st_resid > 0 ) {
                    966:                        st.st_paddr += BSIZE;
                    967:                        dmaon( STDMA, st.st_paddr, BSIZE, st.st_iswr );
                    968:                        outb( DMAGO_REG, 0 );
                    969:                        dmago( STDMA );
                    970:                        break;
                    971:                }
                    972: 
                    973:                /*
                    974:                 * Disable done interrupt.
                    975:                 * Wait for I/O completion.
                    976:                 */
                    977:                outb( CTRL_REG, CR_IEN );
                    978:                st.st_state = SBLEND;
                    979:                break;
                    980: 
                    981:        case SBLEND:
                    982:                /*
                    983:                 * Completion of Block I/O.
                    984:                 * Clear the file mark and beginning of media indicators.
                    985:                 * Record the fact that data has been transferred.
                    986:                 */
                    987:                st.st_status[0] &= ~SS0_FIL;
                    988:                st.st_status[1] &= ~SS1_BOM;
                    989:                st.st_wasio = 1;
                    990:                stnext();
                    991:                break;
                    992: 
                    993:        case SSENSE:
                    994:                /*
                    995:                 * Sense Status Byte.
                    996:                 * Wait for availability.
                    997:                 */
                    998:                do {
                    999:                        csr = inb(CTRL_REG) & (SR_NRDY|SR_TO_PC);
                   1000:                } while ( csr != SR_TO_PC );
                   1001: 
                   1002:                /*
                   1003:                 * Save status byte.
                   1004:                 */
                   1005:                st.st_status[st.st_nstat] = inb(DATA_REG);
                   1006: 
                   1007:                /*
                   1008:                 * Acknowledge reception.
                   1009:                 * CR_REQ must be present for at least 20 microseconds.
                   1010:                 */
                   1011:                outb( CTRL_REG, CR_IEN+CR_REQ );
                   1012:                stspin( 20 );
                   1013:                outb( CTRL_REG, CR_IEN );
                   1014: 
                   1015:                /*
                   1016:                 * Change state to status completion if all bytes saved.
                   1017:                 */
                   1018:                if ( ++(st.st_nstat) == 6 )
                   1019:                        st.st_state = SSDONE;
                   1020:                break;
                   1021: 
                   1022:        case SSDONE:
                   1023:                /*
                   1024:                 * Completion of Sense Status Command.
                   1025:                 * Check for file mark.
                   1026:                 */
                   1027:                if ( st.st_status[0] & SS0_FIL ) {
                   1028:                        outb( DMARST_REG, 0 );
                   1029:                        st.st_iseof = 1;
                   1030:                }
                   1031: 
                   1032:                /*
                   1033:                 * Check for I/O error.
                   1034:                 */
                   1035:                else if ( (st.st_status[0] & SS0_ERR) ||
                   1036:                          (st.st_status[1] & SS1_ERR) ) {
                   1037:                        st.st_error = EIO;
                   1038:                }
                   1039: 
                   1040:                /*
                   1041:                 * Check for write protected cartridge.
                   1042:                 */
                   1043:                else if ( (st.st_iocmd == CC_WRITE) &&
                   1044:                          (st.st_status[0] & SS0_WRP) ) {
                   1045:                        st.st_error = EROFS;
                   1046:                }
                   1047: 
                   1048:                stnext();
                   1049:                break;
                   1050:        }
                   1051: 
                   1052:        spl( s );
                   1053: }
                   1054: 
                   1055: /**
                   1056:  *
                   1057:  * void
                   1058:  * strecov()   -- initiate recovery from exception conditions
                   1059:  *
                   1060:  *     Action: Invoked when the tape controller asserts EXCEPTION.
                   1061:  *             A sense status command is initiated to clear the exception.
                   1062:  */
                   1063: static void
                   1064: strecov()
                   1065: {
                   1066:        /*
                   1067:         * Ensure tape interface is idle.
                   1068:         */
                   1069:        outb( CTRL_REG, CR_IEN );
                   1070:        stspin( 100 );
                   1071: 
                   1072:        /*
                   1073:         * Turn off DMA on read/write exception.
                   1074:         */
                   1075:        if ( st.st_cmd == st.st_iocmd )
                   1076:                dmaoff( STDMA );
                   1077: 
                   1078:        /*
                   1079:         * Initiate sense status command.
                   1080:         */
                   1081:        outb( DATA_REG, st.st_cmd = CC_SENSE );
                   1082:        outb( CTRL_REG, CR_IEN+CR_REQ );
                   1083:        drvl[ST_MAJOR].d_time = 1;
                   1084:        st.st_state = SCMD;
                   1085:        st.st_error = 0;
                   1086:        st.st_rdys  = 0;
                   1087: }
                   1088: 
                   1089: /**
                   1090:  *
                   1091:  * static void
                   1092:  * stnext()    -- initiate next chained command.
                   1093:  */
                   1094: static void
                   1095: stnext()
                   1096: {
                   1097:        /*
                   1098:         * Ensure tape interface is idle.
                   1099:         */
                   1100:        outb( CTRL_REG, CR_IEN );
                   1101:        drvl[ST_MAJOR].d_time = 0;
                   1102:        st.st_state = SIDLE;
                   1103:        stspin( 100 );
                   1104: 
                   1105:        /*
                   1106:         * Initiate a chained command.
                   1107:         */
                   1108:        if ( st.st_ncmds ) {
                   1109:                outb( DATA_REG, st.st_cmd = st.st_cmds[ --st.st_ncmds ] );
                   1110:                outb( CTRL_REG, CR_IEN+CR_REQ );
                   1111:                drvl[ST_MAJOR].d_time = 1;
                   1112:                st.st_state = SCMD;
                   1113:                st.st_error = 0;
                   1114:                st.st_rdys  = 0;
                   1115:                return;
                   1116:        }
                   1117: 
                   1118:        /*
                   1119:         * Wake waiting processes.
                   1120:         */
                   1121:        wakeup( &st );
                   1122: }
                   1123: 
                   1124: /**
                   1125:  *
                   1126:  * void
                   1127:  * stwatch()   -- periodic [1 sec] watchdog
                   1128:  *
                   1129:  *     Action: If an exception condition exists, initate recovery actions.
                   1130:  *             If ready condition exists for 1-2 seconds, simulate interrupt.
                   1131:  *
                   1132:  *     Notes:  If an exception condition occurs after a ready interrupt has
                   1133:  *             been serviced, but before the ready condition is cleared,
                   1134:  *             the exception interrupt will not occur, and is simulated here.
                   1135:  */
                   1136: static void
                   1137: stwatch()
                   1138: {
                   1139:        register int csr;
                   1140:        register int s;
                   1141: 
                   1142:        /*
                   1143:         * Disable interrupts, preventing critical race with stintr().
                   1144:         */
                   1145:        s   = sphi();
                   1146:        csr = inb(CTRL_REG);
                   1147: 
                   1148:        /*
                   1149:         * Initiate recovery from exception conditions.
                   1150:         */
                   1151:        if ( (csr & SR_NEXC) == 0 )
                   1152:                strecov();
                   1153: 
                   1154:        /*
                   1155:         * Reset ready watchdog if not ready.
                   1156:         */
                   1157:        else if ( csr & SR_NRDY ) 
                   1158:                st.st_rdys = 0;
                   1159: 
                   1160:        /*
                   1161:         * Simulate lost ready interrupts after 2 seconds.
                   1162:         */
                   1163:        else if ( ++st.st_rdys >= 2 )
                   1164:                stintr();
                   1165: 
                   1166:        /*
                   1167:         * Enable interrupts.
                   1168:         */
                   1169:        spl( s );
                   1170: }
                   1171: 
                   1172: /**
                   1173:  * 
                   1174:  * void
                   1175:  * stdiag()    - Report tape status.
                   1176:  *
                   1177:  *     Action: Identify and report the highest priority tape error.
                   1178:  *             There will normally only be one valid error present.
                   1179:  *             The USL error can invalidate most remaining flags.
                   1180:  *             The CNI error can invalidate cartridge related flags.
                   1181:  *
                   1182:  *     Notes:  Never called from interrupt level, but always from background.
                   1183:  */
                   1184: static void
                   1185: stdiag()
                   1186: {
                   1187:        if ( st.st_status[0] & SS0_USL )
                   1188:                printf( "st: Unselected Drive\n" );
                   1189: 
                   1190:        else if ( st.st_status[0] & SS0_CNI )
                   1191:                printf( "st: Cartridge missing\n" );
                   1192: 
                   1193:        else if ( st.st_status[1] & SS1_NDT )
                   1194:                printf( "st: No data detected\n" );
                   1195: 
                   1196:        else if ( st.st_status[0] & SS0_BNL )
                   1197:                printf( "st: Bad block not located\n" );
                   1198: 
                   1199:        else if ( st.st_status[0] & SS0_UDA )
                   1200:                printf( "st: Unrecoverable data error\n" );
                   1201: 
                   1202:        else if ( st.st_status[1] & SS1_ILL )
                   1203:                printf( "st: Illegal command\n" );
                   1204: 
                   1205:        else
                   1206:                printf( "st: %x\n", (st.st_status[1] << 8) + st.st_status[0] );
                   1207: }
                   1208: 
                   1209: /**
                   1210:  *
                   1211:  * int
                   1212:  * stwait()    -- wait for tape controller to idle.
                   1213:  *
                   1214:  *     Return: 0  = tape controller idle.
                   1215:  *             -1 = signal received.
                   1216:  */
                   1217: static int
                   1218: stwait()
                   1219: {
                   1220:        int s;
                   1221: 
                   1222:        s = sphi();
                   1223:        while ( st.st_state != SIDLE ) {
                   1224: 
                   1225:                sleep( &st, CVTTOUT, IVTTOUT, SVTTOUT );
                   1226: 
                   1227:                if ( SELF->p_ssig ) {
                   1228:                        spl( s );
                   1229:                        return -1;
                   1230:                }
                   1231:        }
                   1232:        spl( s );
                   1233: 
                   1234:        return 0;
                   1235: }
                   1236: 
                   1237: /**
                   1238:  *
                   1239:  * void
                   1240:  * stspin( usec )      -- delay execution
                   1241:  * int usec;
                   1242:  *
                   1243:  *     Input:  usec = number of micro-seconds to delay.
                   1244:  *
                   1245:  *     Action: Wait at least 'usec' micro-seconds.
                   1246:  *
                   1247:  *     Notes:  Provides minimum delay required at times by tape controller.
                   1248:  *             Should function properly up to at least 16 Mhz system clock.
                   1249:  */
                   1250: 
                   1251: static void
                   1252: stspin( usec )
                   1253: register int usec;
                   1254: {
                   1255:        while ( --usec >= 0 )
                   1256:                ;
                   1257: }

unix.superglobalmegacorp.com

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