Annotation of researchv9/sys/boot/stand/sd.c, revision 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.