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

1.1       root        1: /*
                      2:  * @(#)sd.c 1.1 86/02/03 Copyright (c) 1985 by Sun Microsystems, Inc.
                      3:  */
                      4: #include <sys/param.h>
                      5: #include <sys/inode.h>
                      6: #include <sun/dklabel.h>
                      7: #include <sun/dkio.h>
                      8: #include <sys/buf.h>
                      9: #include <sundev/screg.h>
                     10: #include <sundev/sireg.h>
                     11: #include <sundev/scsi.h>
                     12: #include <machine/sunromvec.h>
                     13: #include <machine/idprom.h>
                     14: #include "saio.h"
                     15: #include "param.h"
                     16: 
                     17: /* For RAM-based code, print detailed error messages */
                     18: #if !defined(SDBOOT) && !defined(BOOTBLOCK)
                     19: #define SDERRORS
                     20: #endif
                     21: 
                     22: /*
                     23:  * Scsi disk parameter block
                     24:  */
                     25: struct sdparam {
                     26:        int     sd_target;
                     27:        int     sd_unit;
                     28:        int     sd_boff;
                     29: #ifdef SUN3
                     30:        int     sd_ha_type;
                     31: #endif
                     32:        struct saioreq subsip[1];       /* Sip for host adapter */
                     33: };
                     34: 
                     35: /*
                     36:  * Record an error message from scsi
                     37:  */
                     38: #define DEBUG FIXME
                     39: 
                     40: #if (!defined(SDBOOT)) & !defined(STBOOT) & !defined(DEBUG)
                     41: 
                     42: #define        sc_error(msg)   scerrmsg = msg
                     43: #define DEFERRED_ERRORS
                     44: extern char *scerrmsg;
                     45: 
                     46: #else
                     47: 
                     48: extern sc_error();     /* It's in sc.c */
                     49: #undef DEFERRED_ERRORS
                     50: 
                     51: #endif
                     52: 
                     53: /*
                     54:  * Our DMA space
                     55:  */
                     56: struct sddma {
                     57:        char    buffer[MAXBSIZE];
                     58:        struct dk_label xlabel[1];
                     59: };
                     60: 
                     61: #define SDBUF          (((struct sddma *)sip->si_dmaaddr)->buffer)
                     62: #define label          (((struct sddma *)sip->si_dmaaddr)->xlabel)
                     63: 
                     64: /*
                     65:  * What resources we need to run
                     66:  */
                     67: struct devinfo sdinfo = {
                     68:        0,                              /* No device to map in */
                     69:        sizeof (struct sddma),
                     70:        sizeof (struct sdparam),
                     71:        0,                              /* Dummy devices */
                     72:        0,                              /* Dummy devices */
                     73:        MAP_MAINMEM,
                     74:        MAXBSIZE,                       /* transfer size */
                     75: };
                     76: 
                     77: /*
                     78:  * The interfaces we export
                     79:  */
                     80: extern int xxprobe(), xxboot();
                     81: int sdopen(), sdclose(), sdstrategy();
                     82: 
                     83: struct boottab sddriver = {
                     84:        "sd",   xxprobe, xxboot,
                     85:         sdopen, sdclose, sdstrategy,
                     86:        "sd: Adaptec SCSI disk", &sdinfo
                     87: };
                     88: 
                     89: #ifndef BOOTBLOCK
                     90: 
                     91: /*
                     92:  * Test routine for isspinning() to see if SCSI disk is running.
                     93:  */
                     94: sdspin(sip, dummy)
                     95:        struct saioreq *sip;
                     96:        int dummy;
                     97: {
                     98: 
                     99: #ifdef lint
                    100:        dummy = dummy;
                    101: #endif lint
                    102:        sip->si_bn = 0;
                    103:        sip->si_cc = 0;
                    104:        sip->si_ma = 0;
                    105:        return (sdcmd (SC_TEST_UNIT_READY, sip, 0));
                    106: }
                    107: #endif
                    108: 
                    109: #ifdef SUN3
                    110: /*
                    111:  * Determine type of host adaptor interface, si or sc.
                    112:  * Returns 1 if si host adaptor and 0 if sc host adaptor.
                    113:  */
                    114: sd_probe(sip)
                    115:        struct saioreq *sip;
                    116: {
                    117:        if (siprobe(sip)) {
                    118:                return (1);
                    119:        } else {
                    120:                return (0);
                    121:        }
                    122: }
                    123: #endif
                    124: 
                    125: /*
                    126:  * Open the SCSI Disk controller
                    127:  */
                    128: sdopen(sip)
                    129:        register struct saioreq *sip;
                    130: {
                    131:        register struct sdparam *sdp;
                    132:        register short *sp, sum;
                    133:        register int count, r;
                    134: 
                    135:        sdp = (struct sdparam *)sip->si_devdata;
                    136:        bzero( (char *)sdp, (sizeof (struct sdparam)));
                    137: 
                    138:        /*
                    139:         * Open the host adapter
                    140:         */
                    141:        *sdp->subsip = *sip;            /* Initialize sub-sip */
                    142: #ifdef SUN3
                    143:        {
                    144:                extern struct boottab scdriver;
                    145:                extern struct boottab sidriver;
                    146: 
                    147:                /* FIXME, find out which scsi interface to use */
                    148:                if (sd_probe(sip)) {
                    149:                        sdp->sd_ha_type = 1;
                    150: 
                    151:                        /* FIXME, must vector thru table */
                    152:                        sdp->subsip->si_boottab = &sidriver;    
                    153:                } else {
                    154:                        sdp->sd_ha_type = 0;
                    155: 
                    156:                        /* FIXME, must vector thru table */
                    157:                        sdp->subsip->si_boottab = &scdriver;    
                    158:                }
                    159: 
                    160:        }
                    161: #endif
                    162: #ifdef SUN2
                    163:        {
                    164:                extern struct boottab scdriver;
                    165: 
                    166:                sdp->subsip->si_boottab = &scdriver;    
                    167:        }
                    168: #endif
                    169:        sdp->subsip->si_unit = sip->si_unit >> 2;       /* Target number */
                    170:        r = devopen(sdp->subsip);
                    171:        if (r < 0) return r;
                    172: 
                    173:        sdp->sd_unit = sip->si_unit & 0x03;     /* Logical unit number */
                    174: 
                    175: #ifndef BOOTBLOCK
                    176:        /*
                    177:         * Check that the disk is up and running...
                    178:         */
                    179:        switch (isspinning(sdspin, (char *)sip, 0)) {
                    180: 
                    181:        default:        /* Error from sdspin */
                    182:        case 0:         /* Disk still not ready */
                    183:                /* isspinning has already printed "Giving up..." */
                    184:                return (-1);
                    185: 
                    186:        case 1:
                    187:                break;
                    188: 
                    189:        case 2:
                    190:                DELAY(1000000);  /* one second delay after spinup */
                    191:                break;
                    192:        }
                    193: #endif
                    194: 
                    195:        /*
                    196:         * Actually read the label
                    197:         */
                    198:        label->dkl_magic = 0;
                    199:        sip->si_ma = (char *)label;
                    200:        sip->si_cc = SECSIZE;
                    201:        sip->si_bn = 0;         /* Read block #0 */
                    202:        if (sdcmd(SC_READ, sip, 1) <= 0) {
                    203:                return (-1);
                    204:        }
                    205:        if (chklabel(label))
                    206:                return -1;
                    207:        sdp->sd_boff = (unsigned short)(label->dkl_map[sip->si_boff].dkl_cylno)
                    208:            * (unsigned short)(label->dkl_nhead * label->dkl_nsect);
                    209:        return (0);
                    210: }
                    211: 
                    212: /*
                    213:  * Execute reads or writes for the outside world.
                    214:  */
                    215: sdstrategy(sip, rw)
                    216:        struct saioreq *sip;
                    217:        register int rw;
                    218: {
                    219:        rw = sdcmd(rw == WRITE ? SC_WRITE : SC_READ, sip, 1);
                    220:        if (rw < 0)
                    221:                rw = 0;
                    222:        return rw;
                    223: }
                    224: 
                    225: /*
                    226:  * Internal interface to the disk command set
                    227:  *
                    228:  * Returns the character count read (or 1 if count==0) for success,
                    229:  * returns 0 for failure, or -1 for severe unretryable failure.
                    230:  */
                    231: int
                    232: sdcmd(cmd, sip, errprint)
                    233:        int cmd;
                    234:        register struct saioreq *sip;
                    235:        int errprint;
                    236: {
                    237:        int blkno, acount;
                    238:        register char *buf;
                    239:        register struct sdparam *sdp;
                    240:        struct scsi_cdb cdb, scdb;
                    241:        struct scsi_scb scb, sscb;
                    242:        register int retry, r, i, count;
                    243: 
                    244:        blkno = sip->si_bn;
                    245:        acount = sip->si_cc;
                    246:        buf = sip->si_ma;
                    247:        sdp = (struct sdparam *)sip->si_devdata;
                    248: 
                    249:        if (cmd == SC_WRITE)
                    250:                bcopy(buf, SDBUF, (unsigned)acount);
                    251: 
                    252:        /* set up cdb */
                    253:        bzero((char *) &cdb, sizeof cdb);
                    254:        cdb.cmd = cmd;
                    255:        cdb.lun = sdp->sd_unit;
                    256:        blkno += sdp->sd_boff;
                    257:        cdbaddr(&cdb, blkno);
                    258:        count = (acount + SECSIZE -1) & ~(SECSIZE-1);
                    259:        cdb.count = count / SECSIZE;
                    260:        retry = 0;
                    261:        do {
                    262:                sdp->subsip->si_cc = count;
                    263:                sdp->subsip->si_ma = SDBUF;
                    264: #ifdef SUN3
                    265:                if (sdp->sd_ha_type)
                    266:                        r = sidoit(&cdb, &scb, sdp->subsip);
                    267:                else
                    268: #endif
                    269:                        r = scdoit(&cdb, &scb, sdp->subsip);
                    270:                if (r < 0) 
                    271:                        return -1; /* Major SCSI bus error, already printed */
                    272:                if (scb.chk) {
                    273:                        bzero((char *) &scdb, sizeof scdb);
                    274:                        scdb.cmd = SC_REQUEST_SENSE;
                    275:                        scdb.lun = sdp->sd_unit;
                    276:                        scdb.count = sizeof (struct scsi_sense);
                    277:                        sdp->subsip->si_cc = scdb.count;
                    278:                        sdp->subsip->si_ma = SDBUF;
                    279: #ifdef SUN3
                    280:                        if (sdp->sd_ha_type)
                    281:                                i = sidoit(&scdb, &sscb, sdp->subsip);
                    282:                        else
                    283: #endif
                    284:                                i = scdoit(&scdb, &sscb, sdp->subsip);
                    285:                        if (i >= 4) {   /* all the sense Adaptec gives us */
                    286: #ifndef DEFERRED_ERRORS
                    287:                                if (errprint) sd_pr_sense(SDBUF, i);
                    288: #endif
                    289:                                continue;
                    290:                        } else {        /* can't get sense, give up */
                    291:                                if (errprint) {
                    292:                                        printf("sd: scsi %s\n",
                    293: #ifdef DEFERRED_ERRORS
                    294:                                        scerrmsg ? scerrmsg :
                    295: #endif
                    296:                                        "sense failed");
                    297:                                }
                    298:                                return (0);
                    299:                        }
                    300:                } else if (scb.busy) {
                    301:                        sc_error("disk busy");
                    302:                        DELAY(100000);
                    303:                        continue;
                    304:                }
                    305:                if (r != count) {
                    306: #ifndef DEFERRED_ERRORS
                    307:                        if (errprint)
                    308:                                printf("sd: dma count is %d wanted %d\n",
                    309:                                    r, count);
                    310: #endif
                    311:                        continue;
                    312:                }
                    313:                if (cmd == SC_READ)
                    314:                        bcopy(SDBUF, buf, (unsigned)acount);
                    315: #ifdef DEFERRED_ERRORS
                    316:                scerrmsg = 0;
                    317: #endif
                    318:                return (count ? count : 1);
                    319:        } while (retry++ < 16);
                    320: #ifdef DEFERRED_ERRORS
                    321:        if (errprint) {
                    322:                if (scb.chk) {
                    323:                        sd_pr_sense(SDBUF, i);
                    324:                } else if (scerrmsg) {
                    325:                        printf("sd: scsi %s\n", scerrmsg);
                    326:                } else if (r != count) {
                    327:                        printf("sd: dma count is %d wanted %d\n", r, count);
                    328:                } else {
                    329:                        /* we should never get this far */
                    330:                        printf("sd: retry count exceeded\n");
                    331:                }
                    332:        }
                    333: #endif
                    334:        return (0);
                    335: }
                    336: 
                    337: #ifdef SDERRORS
                    338: char   *class_00_errors[] = {
                    339:        "No sense",
                    340:        "No index signal",
                    341:        "No seek complete",
                    342:        "Write fault",
                    343:        "Drive not ready",
                    344:        "Drive not selected",
                    345:        "No track 00",
                    346:        "Multiple drives selected",
                    347:        "No address acknowledged",
                    348:        "Media not loaded",
                    349:        "Insufficient capacity",
                    350: };
                    351: 
                    352: char   *class_01_errors[] = {
                    353:        "I.D. CRC error",
                    354:        "Unrecoverable data error",
                    355:        "I.D. address mark not found",
                    356:        "Data address mark not found",
                    357:        "Record not found",
                    358:        "Seek error",
                    359:        "DMA timeout error",
                    360:        "Write protected",
                    361:        "Correctable data check",
                    362:        "Bad block found",
                    363:        "Interleave error",
                    364:        "Data transfer incomplete",
                    365:        "Unformatted or bad format on drive",
                    366:        "Self test failed",
                    367:        "Defective track (media errors)",
                    368: };
                    369: 
                    370: char   *class_02_errors[] = {
                    371:        "Invalid command",
                    372:        "Illegal block address",
                    373:        "Aborted",
                    374:        "Volume overflow",
                    375: };
                    376: 
                    377: char   **sc_errors[] = {
                    378:        class_00_errors,
                    379:        class_01_errors,
                    380:        class_02_errors,
                    381:        0, 0, 0, 0,
                    382: };
                    383: 
                    384: int    sc_errct[] = {
                    385:        sizeof class_00_errors / sizeof (char *),
                    386:        sizeof class_01_errors / sizeof (char *),
                    387:        sizeof class_02_errors / sizeof (char *),
                    388:        0, 0, 0, 0,
                    389: };
                    390: 
                    391: char   *sc_sense7_keys [] = {
                    392:        "No sense",
                    393:        "Recoverable error",
                    394:        "Not ready",
                    395:        "Media error",
                    396:        "Hardware error",
                    397:        "Illegal request",
                    398:        "Media change",
                    399:        "Write protect",
                    400:        "Diagnostic unique",
                    401:        "Vendor unique",
                    402:        "Power up failed",
                    403:        "Aborted command",
                    404:        "Equal",
                    405:        "Volume overflow",
                    406: };
                    407: #endif SDERRORS
                    408: 
                    409: /*
                    410:  * Print out sense info.
                    411:  */
                    412: sd_pr_sense(sp, len)
                    413:        register unsigned char *sp;
                    414:        register int len;
                    415: {
                    416: 
                    417: #ifndef SDERRORS
                    418:        printf("sd: error");
                    419:        while (--len >= 0) {
                    420:                printf(" %x", *sp++);
                    421:        }
                    422:        printf("\n");
                    423: #else  SDERRORS
                    424: #ifdef lint
                    425:        len = len;      /* Avoid spurious "len unused" messages */
                    426: #endif lint
                    427:        printf("sd: ");
                    428:        if (((struct scsi_sense *)sp)->class <= 6) {
                    429:                register struct scsi_sense *sense;
                    430: 
                    431:                sense = (struct scsi_sense *) sp;
                    432:                if (sense->code < sc_errct[sense->class]) {
                    433:                        printf("%s", sc_errors[sense->class][sense->code]);
                    434:                } else {
                    435:                        printf("error %x", *sp);
                    436:                }
                    437:                if (sense->adr_val) {
                    438:                        printf("- block no. %d", (sense->high_addr << 16) |
                    439:                            (sense->mid_addr << 8) | sense->low_addr);
                    440:                }
                    441:        } else {        /* Sense class 7: the standardized one */
                    442:                register struct scsi_ext_sense *sense7;
                    443: 
                    444:                sense7 = (struct scsi_ext_sense *) sp;
                    445:                if (sense7->fil_mk) {
                    446:                        printf("file mark ");
                    447:                }
                    448:                if (sense7->eom) {
                    449:                        printf("end of medium ");
                    450:                }
                    451:                if (sense7->key 
                    452:                    < sizeof (sc_sense7_keys) / sizeof (sc_sense7_keys[0])) {
                    453:                        printf("%s", sc_sense7_keys[sense7->key]);
                    454:                } else {
                    455:                        printf("sense key %x", sense7->key);
                    456:                }
                    457:                printf(" block no. %x", (sense7->info_1 << 24) |
                    458:                    (sense7->info_2 << 16) | (sense7->info_3 << 8) |
                    459:                    sense7->info_4);
                    460:        }
                    461:        printf("\n");
                    462: #endif SDERRORS
                    463: }
                    464: 
                    465: 
                    466: /*
                    467:  * Close scsi disk
                    468:  *
                    469:  * We must close the host adapter too.
                    470:  */
                    471: int
                    472: sdclose(sip)
                    473:        struct saioreq *sip;
                    474: {
                    475:        devclose(((struct sdparam *)sip->si_devdata)->subsip);
                    476: }

unix.superglobalmegacorp.com

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