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

unix.superglobalmegacorp.com

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