Annotation of researchv9/sys/boot/stand/st.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * @(#)st.c 1.1 86/02/03 Copyright (c) 1985 by Sun Microsystems, Inc.
                      3:  */
                      4: 
                      5: #include <sys/types.h>
                      6: #include <sys/inode.h>
                      7: #include <sun/dklabel.h>
                      8: #include <sun/dkio.h>
                      9: #include <sys/buf.h>
                     10: #include <sundev/screg.h>
                     11: #include <sundev/sireg.h>
                     12: #include <sundev/scsi.h>
                     13: #include <sundev/streg.h>
                     14: #include <machine/idprom.h>
                     15: #include "saio.h"
                     16: #include "param.h"
                     17: 
                     18: /*
                     19:  * Driver for Sysgen SC4000 and EMULEX MT-02 SCSI tape controllers.
                     20:  * Supports qic11 format only.
                     21:  */
                     22: extern int scdoit();
                     23: #ifdef SUN3
                     24: extern int sidoit();
                     25: #endif
                     26: 
                     27: #define min(a,b)       ((a)<(b)? (a): (b))
                     28: 
                     29: #define NSD 1
                     30: unsigned long staddrs[NSD] = { 0x0, };
                     31: 
                     32: extern int xxprobe(), xxboot();
                     33: int stopen(), stclose(), ststrategy();
                     34: 
                     35: 
                     36: struct stparam {
                     37:        int             st_target;
                     38:        int             st_unit;
                     39:        int             st_eof;
                     40:        int             st_lastcmd;
                     41:        int             st_ctype;
                     42: #ifdef SUN3
                     43:        int             st_ha_type;
                     44: #endif
                     45:        struct          saioreq subsip[1];      /* sip for host adapter */
                     46: };
                     47: 
                     48: /*
                     49:  * DMA-able buffers
                     50:  */
                     51: #ifdef SUN2
                     52: /* virtual addresses are precious on Sun-2 */
                     53: #define        MAXSTBSIZE      (20*1024)       
                     54: #endif
                     55: #ifdef SUN3
                     56: #define        MAXSTBSIZE      (127*512)       
                     57: #endif
                     58: struct stdma {
                     59:        char    sbuffer[SENSE_LENGTH];
                     60:        char    databuffer[MAXSTBSIZE];
                     61: };
                     62: 
                     63: #define STSBUF         (((struct stdma *)sip->si_dmaaddr)->sbuffer)
                     64: #define STBUF          (((struct stdma *)sip->si_dmaaddr)->databuffer)
                     65: 
                     66: #define ISAEMULEX(stp) (stp->st_ctype == ST_TYPE_EMULEX ? 1 : 0)
                     67: 
                     68: /*
                     69:  * What resources we need to run
                     70:  */
                     71: struct devinfo stinfo = {
                     72:        0,                              /* No device to map in */
                     73:        sizeof (struct stdma),
                     74:        sizeof (struct stparam),
                     75:        NSD,                            /* Dummy devices */
                     76:        staddrs,                        /* Dummy devices */
                     77:        MAP_MAINMEM,
                     78:        MAXSTBSIZE,                     /* transfer size */
                     79: };
                     80: 
                     81: struct boottab stdriver = {
                     82:        "st",   xxprobe, xxboot,
                     83:        stopen, stclose, ststrategy,
                     84:        "st: SCSI tape", &stinfo
                     85: };
                     86: 
                     87: #define        TAPE_TARGET             4       /* default SCSI target # for tape */
                     88: 
                     89: #define SENSE_BITS \
                     90: "\020\17NoCart\16NoDrive\15WriteProt\14EndMedium\13HardErr\12WrongBlock\
                     91: \11FileMark\7InvCmd\6NoData\5Flaking\4BOT\0034\0022\1GotReset"
                     92: 
                     93: #define SENSELOC       4       /* sysgen returns sense at this offset */
                     94: 
                     95: #define        ROUNDUP(x)      ((x + DEV_BSIZE - 1) & ~(DEV_BSIZE - 1))
                     96: 
                     97: #ifdef SUN3
                     98: /*
                     99:  * Determine type of host adaptor interface, si or sc.
                    100:  * Returns 1 if si host adaptor and 0 if sc host adaptor.
                    101:  */
                    102: st_probe(sip)
                    103:        struct saioreq *sip;
                    104: {
                    105:        if (siprobe(sip)) {
                    106:                return (1);
                    107:        } else {
                    108:                return (0);
                    109:        }
                    110: }
                    111: #endif
                    112: 
                    113: /*
                    114:  * Open the SCSI Tape controller
                    115:  */
                    116: int
                    117: stopen(sip)
                    118:        register struct saioreq *sip;
                    119: {
                    120:        register struct stparam *stp;
                    121:        register int r;
                    122:        register int skip;
                    123:        register int i;
                    124:        struct scsi_cdb cdb;
                    125:        struct scsi_scb scb;
                    126: 
                    127:        stp = (struct stparam *) sip->si_devdata;
                    128:        bzero( (char *)stp, (sizeof (struct stparam)));
                    129: 
                    130:        *stp->subsip = *sip;    /* initialize subsip */
                    131: 
                    132: #ifdef SUN3
                    133:        {
                    134:                extern struct boottab scdriver;
                    135:                extern struct boottab sidriver;
                    136: 
                    137:                /* FIXME, find out which scsi interface to use */
                    138:                if (st_probe(sip)) {
                    139:                        stp->st_ha_type = 1;
                    140: 
                    141:                        /* FIXME, must vector thru table */
                    142:                        stp->subsip->si_boottab = &sidriver;
                    143:                } else {
                    144:                        stp->st_ha_type = 0;
                    145: 
                    146:                        /* FIXME, must vector thru table */
                    147:                        stp->subsip->si_boottab = &scdriver;
                    148:                }
                    149:        }
                    150: #endif
                    151: #ifdef SUN2
                    152:        {
                    153:                extern struct boottab scdriver;
                    154: 
                    155:                stp->subsip->si_boottab = &scdriver;    
                    156:        }
                    157: #endif
                    158: 
                    159:        stp->subsip->si_unit = sip->si_unit >> 3;       /* Target number */
                    160:        if (stp->subsip->si_unit == 0) {
                    161:                stp->subsip->si_unit = TAPE_TARGET;
                    162:        }
                    163: 
                    164:        r = devopen(stp->subsip);
                    165:        if (r < 0) return r;
                    166: 
                    167:        /* Logical unit number */
                    168:        stp->st_unit = sip->si_unit & 0x07;
                    169: 
                    170:        /*
                    171:         * Must wait for tape controller to become ready.
                    172:         * This takes about 10 seconds for the Emulex.
                    173:         */
                    174:        /*
                    175:         * Test for the controller being ready. First test will fail if
                    176:         * the SCSI bus is permanently busy or if a previous op was 
                    177:         * interrupted in mid-transfer. Second one should work.
                    178:         */
                    179:        for (i = 0; i < 2; i++) {
                    180:                bzero((char *) &cdb, sizeof cdb);
                    181:                cdb.cmd = SC_TEST_UNIT_READY;
                    182:                cdb.count = 0;
                    183:                stp->subsip->si_cc = 0;
                    184:                stp->subsip->si_ma = 0;
                    185: #ifdef SUN3
                    186:                if (stp->st_ha_type)
                    187:                        r = sidoit(&cdb, &scb, stp->subsip);
                    188:                else
                    189: #endif
                    190:                        r = scdoit(&cdb, &scb, stp->subsip);
                    191:        }
                    192: 
                    193:        /* 
                    194:         * To figure out what type of tape controller is out there we send 
                    195:         * a REQUEST_SENSE command and see how much sense data comes back.  
                    196:         */
                    197:        stp->st_ctype = ST_TYPE_EMULEX;
                    198:        cdb.cmd = SC_REQUEST_SENSE;
                    199:        stp->subsip->si_cc = cdb.count = ST_EMULEX_SENSE_LEN;
                    200:        stp->subsip->si_ma = STSBUF;
                    201: #ifdef SUN3
                    202:        if (stp->st_ha_type)
                    203:                r = sidoit(&cdb, &scb, stp->subsip);
                    204:        else
                    205: #endif
                    206:                r = scdoit(&cdb, &scb, stp->subsip);
                    207:        if (r != ST_EMULEX_SENSE_LEN) {
                    208:                stp->st_ctype = ST_TYPE_SYSGEN;
                    209:                cdb.cmd = SC_REQUEST_SENSE;
                    210:                stp->subsip->si_cc = cdb.count = ST_SYSGEN_SENSE_LEN;
                    211:                stp->subsip->si_ma = STSBUF;
                    212: #ifdef SUN3
                    213:                if (stp->st_ha_type)
                    214:                        r = sidoit(&cdb, &scb, stp->subsip);
                    215:                else
                    216: #endif
                    217:                        r = scdoit(&cdb, &scb, stp->subsip);
                    218:                if (r == -1) {
                    219:                        printf("stopen: cannot get sense, %d\n", r);
                    220:                        return (-1);
                    221:                }
                    222:        } 
                    223: 
                    224:        /* 
                    225:         * Default format mode for emulex is qic24.
                    226:         * Needs to be qic11.
                    227:         */
                    228:        if (ISAEMULEX(stp)) {
                    229:                sip->si_cc = EM_MS_PL_LEN;
                    230:                if (stcmd(SC_QIC11, sip, 1) == 0) {
                    231:                        printf("stopen: mode select command fail");
                    232:                        return (-1);
                    233:                }
                    234:        }
                    235: 
                    236:        /*
                    237:         * Rewind a few times until it works.  First one will fail if
                    238:         * the SCSI bus is permanently busy if a previous op was interrupted
                    239:         * in mid-transfer.  Second one will fail with POR status, after
                    240:         * the scsi bus is reset from the busy.  Third one should work.  
                    241:         */
                    242:        sip->si_cc = 0;
                    243:        if (stcmd(SC_REWIND, sip, 0) == 0 &&
                    244:            stcmd(SC_REWIND, sip, 0) == 0 &&
                    245:            stcmd(SC_REWIND, sip, 1) == 0) {
                    246:                return (-1);
                    247:        }
                    248:        skip = sip->si_boff;
                    249:        while (skip--) {
                    250:                sip->si_cc = 0;
                    251:                if (stcmd(SC_SPACE_FILE, sip, 1) == 0) {
                    252:                        return (-1);
                    253:                }
                    254:        }
                    255:        stp->st_eof = 0;
                    256:        stp->st_lastcmd = 0;
                    257:        return (0);
                    258: }
                    259: 
                    260: /*
                    261:  * Close the tape drive.
                    262:  */
                    263: stclose(sip)
                    264:        register struct saioreq *sip;
                    265: {
                    266:        register struct stparam *stp;
                    267: 
                    268:        stp = (struct stparam *) sip->si_devdata;
                    269:        if (stp->st_lastcmd == SC_WRITE) {
                    270:                (void) stcmd(SC_WRITE_FILE_MARK, sip, 0);
                    271:        }
                    272:        (void) stcmd(SC_REWIND, sip, 0);
                    273: }
                    274: 
                    275: 
                    276: /*
                    277:  * Perform a read or write of the SCSI tape.
                    278:  */
                    279: int
                    280: ststrategy(sip, rw)
                    281:        register struct saioreq *sip;
                    282:        int rw;
                    283: {
                    284:        register struct stparam *stp;
                    285: 
                    286:        stp = (struct stparam *) sip->si_devdata;
                    287:        if (stp->st_eof) {
                    288:                stp->st_eof = 0;
                    289:                return (0);
                    290:        }
                    291:        return (stcmd(rw == WRITE ? SC_WRITE : SC_READ, sip, 1));
                    292: }
                    293: 
                    294: /*
                    295:  * Execute a scsi tape command
                    296:  */
                    297: int
                    298: stcmd(cmd, sip, errprint)
                    299:        int cmd;
                    300:        register struct saioreq *sip;
                    301:        int errprint;
                    302: {
                    303:        register struct st_emulex_mspl *mode;
                    304:        register int r, i, c;
                    305:        register char *buf;
                    306:        register struct stparam *stp;
                    307:        struct scsi_cdb cdb, scdb;
                    308:        struct scsi_scb scb, sscb;
                    309:        int count;
                    310:        int qic;
                    311:        int sense_length;
                    312:        char *cp;
                    313:        struct st_emulex_sense *ems;
                    314:        struct st_sysgen_sense *scs;
                    315: 
                    316:        count = sip->si_cc;
                    317:        stp = (struct stparam *)sip->si_devdata;
                    318:        buf =  sip->si_ma;
                    319: 
                    320:        if (cmd == SC_WRITE && buf != STBUF) {
                    321:                bcopy(buf, STBUF, (unsigned)count);
                    322:        }
                    323: 
                    324:        /* set up cdb */
                    325:        bzero((char *) &cdb, sizeof cdb);
                    326:        cdb.cmd = cmd;
                    327:        cdb.lun = stp->st_unit;
                    328:        c = ROUNDUP(count) / DEV_BSIZE;
                    329:        cdb.high_count = c >> 16;
                    330:        cdb.mid_count = (c >> 8) & 0xFF;
                    331:        cdb.low_count = c & 0xFF;
                    332:        stp->subsip->si_ma = STBUF;
                    333:        stp->subsip->si_cc = ROUNDUP(count);
                    334: 
                    335:        /* some fields in the cdb are command specific */
                    336:        switch (cmd) {
                    337: 
                    338:        case SC_QIC11:
                    339:                stp->subsip->si_ma = 0;
                    340:                stp->subsip->si_cc = 0; 
                    341:                if (ISAEMULEX(stp)) {
                    342:                        qic = ST_EMULEX_QIC11;
                    343:                        cdb.cmd = SC_MODE_SELECT;
                    344:                        goto MODE;
                    345:                } else {
                    346:                        cdb.cmd = SC_QIC02;
                    347:                        cdb.high_count = ST_SYSGEN_QIC11;
                    348:                        break;
                    349:                }
                    350:                /* NOTREACHED */
                    351: 
                    352:        case SC_QIC24:
                    353:                stp->subsip->si_ma = 0;
                    354:                stp->subsip->si_cc = 0; 
                    355:                if (ISAEMULEX(stp)) {
                    356:                        qic = ST_EMULEX_QIC24;
                    357:                        cdb.cmd = SC_MODE_SELECT;
                    358:                        goto MODE;
                    359:                } else {
                    360:                        cdb.cmd = SC_QIC02;
                    361:                        cdb.high_count = ST_SYSGEN_QIC24;
                    362:                        break;
                    363:                }
                    364:                /* NOTREACHED */
                    365: MODE:
                    366:        case SC_MODE_SELECT:
                    367:                mode = (struct st_emulex_mspl *)STSBUF;
                    368:                bzero(mode, sizeof(*mode));
                    369:                mode->hdr.bufm = 1;
                    370:                mode->bd.density = qic;
                    371:                mode->hdr.bd_len = EM_MS_BD_LEN;
                    372:                stp->subsip->si_ma = (char *)mode;
                    373:                stp->subsip->si_cc = cdb.count = EM_MS_PL_LEN;
                    374:                break;
                    375: 
                    376:        case SC_SPACE_FILE:
                    377:                cdb.cmd = SC_SPACE;     /* the real SCSI cmd */
                    378:                cdb.t_code = 1;         /* space file, not rec */
                    379:                cdb.low_count = 1;      /* space 1 file, not 0 */
                    380:                stp->subsip->si_ma = 0;
                    381:                stp->subsip->si_cc = 0;
                    382:                break;
                    383: 
                    384:        case SC_WRITE_FILE_MARK:
                    385:                cdb.count = 1;  
                    386:                /* fall through... */
                    387: 
                    388:        case SC_TEST_UNIT_READY:
                    389:        case SC_REWIND:
                    390:        case SC_LOAD:
                    391:                stp->subsip->si_ma = 0;
                    392:                stp->subsip->si_cc = 0;
                    393:                break;
                    394: 
                    395:        case SC_READ:
                    396:        case SC_WRITE:
                    397:                if (ISAEMULEX(stp)) {
                    398:                        cdb.t_code = 1;
                    399:                }
                    400:                break;
                    401: 
                    402:        default:
                    403:                if (errprint)
                    404:                        printf("st: unknown command\n");
                    405:                return (0);
                    406:        }
                    407: 
                    408:        /* execute the command */
                    409: #ifdef SUN3
                    410:        if (stp->st_ha_type)
                    411:                r = sidoit(&cdb, &scb, stp->subsip);
                    412:        else
                    413: #endif
                    414:                r = scdoit(&cdb, &scb, stp->subsip);
                    415: 
                    416:        /* allow for tape blocking */
                    417:        if (r > count)
                    418:                r = count;
                    419:        /* error */
                    420:        if (r == -1) 
                    421:                return (0);
                    422: 
                    423:        if (cmd == SC_READ) {
                    424:                if (min(count, r))
                    425:                        bcopy(STBUF, buf, (unsigned)(min(count, r)));
                    426:        }
                    427: 
                    428:        /* we may need to get sense data */
                    429:        if (scb.chk) {
                    430:                bzero((char *) &scdb, sizeof scdb);
                    431:                scdb.cmd = SC_REQUEST_SENSE;
                    432:                scdb.lun = stp->st_unit;
                    433:                if (ISAEMULEX(stp)) {
                    434:                        sense_length = stp->subsip->si_cc =
                    435:                            scdb.count = ST_EMULEX_SENSE_LEN;
                    436:                } else {
                    437:                        sense_length = stp->subsip->si_cc = 
                    438:                            scdb.count = ST_SYSGEN_SENSE_LEN;
                    439:                }
                    440:                stp->subsip->si_ma = STSBUF;
                    441: #ifdef SUN3
                    442:                if (stp->st_ha_type)
                    443:                        i = sidoit(&scdb, &sscb, stp->subsip );
                    444:                else
                    445: #endif
                    446:                        i = scdoit(&scdb, &sscb, stp->subsip );
                    447:                if (i != sense_length) {
                    448:                        if (errprint) {
                    449:                                printf("st: sense error\n");
                    450:                        }
                    451:                        stp->st_eof = 1;
                    452:                        return (0);
                    453:                } 
                    454:                if (ISAEMULEX(stp)) {
                    455:                        ems = (struct st_emulex_sense *)STSBUF;
                    456:                        if ((ems->ext_sense.fil_mk == 0) && errprint) {
                    457:                                printf("st: error:\n");
                    458:                                printf("\tsense key is %x", 
                    459:                                    ems->ext_sense.key);
                    460:                                printf("\terror is %x\n",
                    461:                                    ems->error);
                    462:                        }
                    463:                        stp->st_eof = 1;
                    464:                        return (r);
                    465:                } else  {
                    466:                        scs = (struct st_sysgen_sense *)STSBUF;
                    467:                        if ((scs->qic_sense.file_mark == 0) && errprint) {
                    468: #ifdef STBOOT
                    469:                                printf("st: error %x\n", 
                    470:                                        *(unsigned short *)&STSBUF[SENSELOC]);
                    471: #else  STBOOT
                    472:                                printf("st: error %b\n", 
                    473:                                        *(unsigned short *)&STSBUF[SENSELOC],
                    474:                                        SENSE_BITS);
                    475: #endif STBOOT
                    476:                        }
                    477:                        stp->st_eof = 1;
                    478:                        return (r);
                    479:                }
                    480:        }
                    481:        if (r >= count) {
                    482:                return (count ? count : 1);
                    483:        } else {
                    484:                if (errprint) {
                    485:                        printf("st: short transfer\n");
                    486:                }
                    487:                return (r);
                    488:        }
                    489: }
                    490: 

unix.superglobalmegacorp.com

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