Annotation of researchv9/sys/sundev/sc.c, revision 1.1

1.1     ! root        1: #ifndef lint
        !             2: static char sccsid[] = "@(#)sc.c 1.1 86/02/03 Copyr 1985 Sun Micro";
        !             3: #endif
        !             4: 
        !             5: /*
        !             6:  * Copyright (c) 1985 by Sun Microsystems, Inc.
        !             7:  */
        !             8: 
        !             9: #include "sc.h"
        !            10: 
        !            11: #if NSC > 0
        !            12: /*
        !            13:  * Generic scsi routines.
        !            14:  */
        !            15:  
        !            16: #include "../h/param.h"
        !            17: #include "../h/systm.h"
        !            18: #include "../h/dk.h"
        !            19: #include "../h/buf.h"
        !            20: #include "../h/conf.h"
        !            21: #include "../h/dir.h"
        !            22: #include "../h/user.h"
        !            23: #include "../h/map.h"
        !            24: #include "../h/vmmac.h"
        !            25: /*
        !            26:  *#include "../h/ioctl.h"
        !            27:  *#include "../h/uio.h"
        !            28:  *#include "../h/kernel.h"
        !            29:  */
        !            30: #include "../h/dkbad.h"
        !            31: 
        !            32: #include "../machine/pte.h"
        !            33: #include "../machine/psl.h"
        !            34: #include "../machine/mmu.h"
        !            35: #include "../machine/cpu.h"
        !            36: #include "../machine/scb.h"
        !            37: 
        !            38: #include "../sun/dklabel.h"
        !            39: #include "../sun/dkio.h"
        !            40: 
        !            41: #include "../sundev/mbvar.h"
        !            42: #include "../sundev/screg.h"
        !            43: #include "../sundev/sireg.h"
        !            44: #include "../sundev/scsi.h"
        !            45: 
        !            46: struct scsi_ctlr scctlrs[NSC];
        !            47: #define SCNUM(sc)      (sc - scctlrs)
        !            48: 
        !            49: int    scprobe(), scslave(), scattach(), scgo(), scdone(), scpoll();
        !            50: int    scustart(), scstart(), sc_cmd(), sc_getstatus(), sc_cmdwait();
        !            51: int    sc_off(), sc_reset(), sc_dmacnt();
        !            52: 
        !            53: struct mb_ctlr *scinfo[NSC];
        !            54: extern struct mb_device *sdinfo[];
        !            55: struct mb_driver scdriver = {
        !            56:        scprobe, scslave, scattach, scgo, scdone, scpoll,
        !            57:        sizeof (struct scsi_ha_reg), "sd", sdinfo, "sc", scinfo, MDR_BIODMA,
        !            58: };
        !            59: 
        !            60: /* routines available to devices for mainbus scsi host adaptor */
        !            61: struct scsi_ctlr_subr scsubr = {
        !            62:        scustart, scstart, scdone, sc_cmd, sc_getstatus, sc_cmdwait,
        !            63:        sc_off, sc_reset, sc_dmacnt, scgo,
        !            64: };
        !            65: 
        !            66: extern int scsi_debug;
        !            67: extern int scsi_ntype;
        !            68: extern struct scsi_unit_subr scsi_unit_subr[];
        !            69: 
        !            70: /*
        !            71:  * Determine existence of SCSI host adapter.
        !            72:  */
        !            73: scprobe(reg, ctlr)
        !            74:        register struct scsi_ha_reg *reg;
        !            75:        register int ctlr;
        !            76: {
        !            77:        register struct scsi_ctlr *c;
        !            78: 
        !            79:        /* probe for different scsi host adaptor interfaces */
        !            80:        c = &scctlrs[ctlr];
        !            81:        if (peekc((char *)&reg->dma_count) == -1) {
        !            82:                return (0);
        !            83:        }
        !            84:        reg->dma_count = 0x6789;
        !            85:        if (reg->dma_count != 0x6789) {
        !            86:                return (0);
        !            87:        }
        !            88: 
        !            89:        /* allocate memory for sense information */
        !            90:        c->c_sense = (struct scsi_sense *) rmalloc(iopbmap,
        !            91:            (long) sizeof (struct scsi_sense));
        !            92:        if (c->c_sense == NULL) {
        !            93:                printf("scprobe: no iopb memory for sense.\n");
        !            94:                return (0);
        !            95:        }
        !            96: 
        !            97:        /* init controller information */
        !            98:        c->c_flags = SCSI_PRESENT;
        !            99:        c->c_har = reg;
        !           100:        c->c_ss = &scsubr;
        !           101:        sc_reset(c);
        !           102:        return (sizeof (struct scsi_ha_reg));
        !           103: }
        !           104: 
        !           105: /*
        !           106:  * See if a slave exists.
        !           107:  * Since it may exist but be powered off, we always say yes.
        !           108:  */
        !           109: /*ARGSUSED*/
        !           110: scslave(md, reg)
        !           111:        struct mb_device *md;
        !           112:        register struct scsi_ha_reg *reg;
        !           113: {
        !           114:        register struct scsi_unit *un;
        !           115:        register int type;
        !           116: 
        !           117:        /*
        !           118:         * This kludge allows autoconfig to print out "sd" for
        !           119:         * disks and "st" for tapes.  The problem is that there
        !           120:         * is only one md_driver for scsi devices.
        !           121:         */
        !           122:        type = TYPE(md->md_flags);
        !           123:        if (type >= scsi_ntype) {
        !           124:                panic("scslave: unknown type in md_flags");
        !           125:        }
        !           126: 
        !           127:        /* link unit to its controller */
        !           128:        un = (struct scsi_unit *)(*scsi_unit_subr[type].ss_unit_ptr)(md);
        !           129:        if (un == 0) {
        !           130:                panic("scslave: md_flags scsi type not configured in\n");
        !           131:        }
        !           132:        un->un_c = &scctlrs[md->md_ctlr];
        !           133:        md->md_driver->mdr_dname = scsi_unit_subr[type].ss_devname;
        !           134:        return (1);
        !           135: }
        !           136: 
        !           137: /*
        !           138:  * Attach device (boot time).
        !           139:  */
        !           140: scattach(md)
        !           141:        register struct mb_device *md;
        !           142: {
        !           143:        register struct mb_ctlr *mc = md->md_mc;
        !           144:        register struct scsi_ctlr *c = &scctlrs[md->md_ctlr];
        !           145:        register int type = TYPE(md->md_flags);
        !           146: 
        !           147:        if (type >= scsi_ntype) {
        !           148:                panic("scattach: unknown type in md_flags");
        !           149:        }
        !           150:        (*scsi_unit_subr[type].ss_attach)(md);
        !           151: 
        !           152:        /*
        !           153:         * Initialize interrupt register
        !           154:         */
        !           155:        if (mc->mc_intr) {
        !           156:                /* set up for vectored interrupts - we will pass ctlr ptr */
        !           157:                c->c_har->intvec = mc->mc_intr->v_vec;
        !           158:                *(mc->mc_intr->v_vptr) = (int)c;
        !           159:        } else {
        !           160:                /* use auto-vectoring */
        !           161:                c->c_har->intvec = AUTOBASE + mc->mc_intpri;
        !           162:        }
        !           163: }
        !           164: 
        !           165: /*
        !           166:  * SCSI unit start routine.
        !           167:  * Called by SCSI device drivers.
        !           168:  */
        !           169: scustart(un)
        !           170:        register struct scsi_unit *un;
        !           171: {
        !           172:        register struct buf *dp;
        !           173:        register struct mb_ctlr *mc;
        !           174: 
        !           175:        mc = un->un_mc;
        !           176:        dp = &un->un_utab;
        !           177:        /* 
        !           178:         * Caller guarantees: dp->b_actf != NULL && dp->b_active == 0 
        !           179:         */
        !           180:        /*
        !           181:         * Put device on ready queue for bus.
        !           182:         */
        !           183:        if (mc->mc_tab.b_actf == NULL) {
        !           184:                mc->mc_tab.b_actf = dp;
        !           185:        } else {
        !           186:                mc->mc_tab.b_actl->b_forw = dp;
        !           187:        }
        !           188:        dp->b_forw = NULL;
        !           189:        mc->mc_tab.b_actl = dp;
        !           190:        dp->b_active = 1;
        !           191:        dp->b_un.b_addr = (caddr_t) un;
        !           192: }
        !           193: 
        !           194: /*
        !           195:  * Set up a transfer for the bus.
        !           196:  */
        !           197: scstart(un)
        !           198:        register struct scsi_unit *un;
        !           199: {
        !           200:        register struct mb_ctlr *mc;
        !           201:        register struct buf *bp, *dp;
        !           202: 
        !           203:        mc = un->un_mc;
        !           204:        dp = mc->mc_tab.b_actf;      /* != NULL guaranteed by caller */
        !           205:        un = (struct scsi_unit *) dp->b_un.b_addr;
        !           206:        bp = dp->b_actf;
        !           207:        for (;;) {
        !           208:                if (bp == NULL) {         /* no more blocks for this device */
        !           209:                        un->un_utab.b_active = 0;
        !           210:                        dp = mc->mc_tab.b_actf = dp->b_forw;
        !           211:                        if (dp == NULL) {  /* no more devices for this ctlr */
        !           212:                                return;
        !           213:                        }
        !           214:                        un = (struct scsi_unit *) dp->b_un.b_addr;
        !           215:                        bp = dp->b_actf;
        !           216:                } else {
        !           217:                        if ((*un->un_ss->ss_start)(bp, un)) {
        !           218:                                mc->mc_tab.b_active = 1;
        !           219:                                un->un_c->c_un = un;
        !           220:                                if (bp == &un->un_sbuf  &&
        !           221:                                    ((un->un_flags & SC_UNF_DVMA) == 0)) {
        !           222:                                        scgo(mc);
        !           223:                                } else {
        !           224:                                        (void) mbgo(mc);
        !           225:                                }
        !           226:                                return;
        !           227:                        }
        !           228:                        dp->b_actf = bp = bp->av_forw;
        !           229:                }
        !           230:        }
        !           231: }
        !           232: 
        !           233: /*
        !           234:  * Start up a transfer
        !           235:  * Called via mbgo after buffer is in memory
        !           236:  */
        !           237: scgo(mc)
        !           238:        register struct mb_ctlr *mc;
        !           239: {
        !           240:        register struct scsi_unit *un;
        !           241:        register struct scsi_ctlr *c;
        !           242:        register struct buf *bp, *dp;
        !           243:        register int unit;
        !           244: 
        !           245:        c = &scctlrs[mc->mc_ctlr];
        !           246:        dp = mc->mc_tab.b_actf;
        !           247:        if (dp == NULL || dp->b_actf == NULL) {
        !           248:                panic("scgo queueing error 1");
        !           249:        }
        !           250:        bp = dp->b_actf;
        !           251:        un = c->c_un;
        !           252:        if (dp != &un->un_utab) {
        !           253:                panic("scgo queueing error 2");
        !           254:        }
        !           255:        un->un_baddr = MBI_ADDR(mc->mc_mbinfo);
        !           256:        if ((unit = un->un_md->md_dk) >= 0) {
        !           257:                dk_busy |= 1<<unit;
        !           258:                dk_xfer[unit]++;
        !           259:                dk_wds[unit] += bp->b_bcount >> 6;
        !           260:        }
        !           261:        (*un->un_ss->ss_mkcdb)(c, un);
        !           262:        if (sc_cmd(c, un, 1) == 0) {
        !           263:                (*un->un_ss->ss_intr)(c, 0, SE_RETRYABLE);
        !           264:                sc_off(un);
        !           265:        }
        !           266: }
        !           267: 
        !           268: /*
        !           269:  * Pass a command to the SCSI bus.
        !           270:  */
        !           271: sc_cmd(c, un, intr)
        !           272:        register struct scsi_ctlr *c;
        !           273:        register struct scsi_unit *un;
        !           274:        register int intr;
        !           275: {
        !           276:        register u_char *cp;
        !           277:        register int i, errct;
        !           278:        register u_short icr_mode;
        !           279: 
        !           280:        errct = 0;
        !           281:        do {
        !           282:                /* make sure scsi bus is not continuously busy */
        !           283:                for (i = WAIT_COUNT; i > 0; i--) {
        !           284:                        if (!(c->c_har->icr & ICR_BUSY))
        !           285:                                break;
        !           286:                        DELAY(10);
        !           287:                }
        !           288:                if (i == 0) {
        !           289:                        sc_reset(c);
        !           290:                        return (0);
        !           291:                }
        !           292: 
        !           293:                /* select target and wait for response */
        !           294:                c->c_har->data = (1 << un->un_target) | HOST_ADDR;
        !           295:                c->c_har->icr = ICR_SELECT;
        !           296: 
        !           297:                /* target never responded to selection */
        !           298:                if (sc_wait(c, ICR_BUSY) == 0) {
        !           299:                        c->c_har->data = 0;
        !           300:                        c->c_har->icr = 0;
        !           301:                        return (0);
        !           302:                }
        !           303:                /*
        !           304:                 * may need to map between the CPU's kernel context address
        !           305:                 * and the device's DVMA bus address
        !           306:                 */
        !           307:                c->c_har->dma_addr = un->un_dma_addr;
        !           308:                c->c_har->dma_count = ~un->un_dma_count; /* hardware is funny */
        !           309:                icr_mode = ICR_DMA_ENABLE;
        !           310:                if (intr) {
        !           311:                        icr_mode |= ICR_INTERRUPT_ENABLE;
        !           312:                        un->un_wantint = 1;
        !           313:                }
        !           314:                if  (! (un->un_dma_count & 1)) {
        !           315:                        icr_mode |= ICR_WORD_MODE;
        !           316:                }
        !           317:                c->c_har->icr = icr_mode;
        !           318:                cp = (u_char *) &c->c_cdb;
        !           319:                if (scsi_debug) {
        !           320:                        printf("sc%d: sc_cmd: target %d issuing command ",
        !           321:                            SCNUM(c), un->un_target);
        !           322:                        for (i = 0; i < sizeof (struct scsi_cdb); i++) {
        !           323:                                printf("%x ", *cp++);
        !           324:                        }
        !           325:                        printf("\n");
        !           326:                        cp = (u_char *) &c->c_cdb;
        !           327:                }
        !           328:                for (i = 0; i < sizeof (struct scsi_cdb); i++) {
        !           329:                        if (sc_putbyte(c, ICR_COMMAND, *cp++) == 0) {
        !           330:                                errct++;
        !           331:                                break;
        !           332:                        }
        !           333:                }
        !           334:                if (i == sizeof (struct scsi_cdb)) {
        !           335:                        return (1);
        !           336:                }
        !           337:        } while (errct < 5);
        !           338:        printf("sc_cmd: unrecoverable errors\n");
        !           339:        return (0);
        !           340: }
        !           341: 
        !           342: /*
        !           343:  * Handle a scsi bus interrupt for the mainbus scsi.
        !           344:  */
        !           345: scintr(c)
        !           346:        register struct scsi_ctlr *c;
        !           347: {
        !           348:        register int resid;
        !           349:        register struct scsi_unit *un;
        !           350: 
        !           351:        un = c->c_un;
        !           352:        if (un->un_wantint == 0) {
        !           353:                if (c->c_har->icr & ICR_BUS_ERROR) {
        !           354:                        printf("scsi bus error (unwanted interrupt)\n");
        !           355:                } else {
        !           356:                        printf("scsi: unwanted interrupt\n");
        !           357:                }
        !           358:                sc_reset(c);
        !           359:                return;
        !           360:        }
        !           361:        un->un_wantint = 0;
        !           362:        resid = ~c->c_har->dma_count;
        !           363:        if (c->c_har->icr & ICR_BUS_ERROR) {
        !           364:                printf("scsi bus error. icr %x resid %d\n",
        !           365:                    c->c_har->icr, resid);
        !           366:                sc_reset(c);
        !           367:                (*c->c_un->un_ss->ss_intr)(c, resid, SE_FATAL);
        !           368:                return;
        !           369:        }
        !           370:        if (c->c_har->icr & ICR_ODD_LENGTH) {
        !           371:                if ((c->c_cdb.cmd == SC_READ) || 
        !           372:                    (c->c_cdb.cmd == SC_REQUEST_SENSE)) {
        !           373:                        DVMA[un->un_baddr + un->un_dma_count - resid] =
        !           374:                            c->c_har->data;
        !           375:                        resid--;
        !           376:                } else if (c->c_cdb.cmd == SC_WRITE) {
        !           377:                        resid++;
        !           378:                } else {
        !           379:                        printf("scsi: odd length without xfer\n");
        !           380:                }
        !           381:        }
        !           382:        if (resid < 0) {
        !           383:                panic("scsi resid");
        !           384:        }
        !           385:        if (sc_getstatus(c->c_un, 0) == 0) {
        !           386:                (*c->c_un->un_ss->ss_intr)(c, resid, SE_RETRYABLE);
        !           387:        } else {
        !           388:                (*c->c_un->un_ss->ss_intr)(c, resid, SE_NO_ERROR);
        !           389:        }
        !           390: }
        !           391: 
        !           392: /*
        !           393:  * Handle a polling SCSI bus interrupt.
        !           394:  */
        !           395: scpoll()
        !           396: {
        !           397:        register struct scsi_ctlr *c;
        !           398:        register int serviced = 0;
        !           399: 
        !           400:        for (c = scctlrs; c < &scctlrs[NSC]; c++) {
        !           401:                if ((c->c_flags & SCSI_PRESENT) == 0)
        !           402:                        continue;
        !           403:                if ((c->c_har->icr & (ICR_INTERRUPT_REQUEST | ICR_BUS_ERROR)) 
        !           404:                    == 0) {
        !           405:                        continue;
        !           406:                }
        !           407:                serviced = 1;
        !           408:                scintr(c);
        !           409:        }
        !           410:        return (serviced);
        !           411: }
        !           412: 
        !           413: /*
        !           414:  * Clean up queues, free resources, and start next I/O
        !           415:  * all done after I/O finishes
        !           416:  * Called by mbdone after moving read data from Mainbus
        !           417:  */
        !           418: scdone(mc)
        !           419:        register struct mb_ctlr *mc;
        !           420: {
        !           421:        register struct buf *bp, *dp;
        !           422:        register struct scsi_unit *un;
        !           423:        register struct scsi_ctlr *c;
        !           424: 
        !           425:        bp = mc->mc_tab.b_actf->b_actf;
        !           426:        c = &scctlrs[mc->mc_ctlr];
        !           427:        un = c->c_un;
        !           428: 
        !           429:        /* advance controller queue */
        !           430:        dp = mc->mc_tab.b_actf;
        !           431:        mc->mc_tab.b_active = 0;
        !           432:        mc->mc_tab.b_actf = dp->b_forw;
        !           433: 
        !           434:        /* advance unit queue */
        !           435:        dp->b_active = 0;
        !           436:        dp->b_actf = bp->av_forw;
        !           437: 
        !           438:        iodone(bp);
        !           439: 
        !           440:        /* start next I/O on unit */
        !           441:        if (dp->b_actf)
        !           442:                scustart(un);
        !           443: 
        !           444:        /* start next I/O on controller */
        !           445:        if (mc->mc_tab.b_actf && mc->mc_tab.b_active == 0)
        !           446:                scstart(un);
        !           447: }
        !           448: 
        !           449: /*ARGSUSED*/
        !           450: sc_off(un)
        !           451:        struct scsi_unit *un;
        !           452: {
        !           453: 
        !           454: #ifdef notdef
        !           455:        /* if done to root real bad things happen... */
        !           456:        un->un_present = 0;
        !           457:        printf("scsi unit %d/%d offline\n", un->un_target, un->un_lun);
        !           458:        if (un->un_md->md_dk > 0) {
        !           459:                dk_mspw[un->un_md->md_dk]=0;
        !           460:        }
        !           461: #endif
        !           462: }
        !           463: 
        !           464: /*
        !           465:  * Wait for a condition on the scsi bus.
        !           466:  */
        !           467: sc_wait(c, cond)
        !           468:        register struct scsi_ctlr *c;
        !           469: {
        !           470:        register struct scsi_ha_reg *har = c->c_har;
        !           471:        register int i, icr;
        !           472: 
        !           473:        for (i = 0; i < WAIT_COUNT; i++) {
        !           474:                icr = har->icr;
        !           475:                if ((icr & cond) == cond) {
        !           476:                        return (1);
        !           477:                }
        !           478:                if (icr & ICR_BUS_ERROR) {
        !           479:                        break;
        !           480:                }
        !           481:                DELAY(10);
        !           482:        }
        !           483:        return (0);
        !           484: }
        !           485: 
        !           486: /*
        !           487:  * Wait for the completion of a scsi command.
        !           488:  */
        !           489: sc_cmdwait(c)
        !           490:        register struct scsi_ctlr *c;
        !           491: {
        !           492:        if (sc_wait(c, ICR_INTERRUPT_REQUEST) == 0) {
        !           493:                sc_reset(c);
        !           494:                return(0);
        !           495:        } else {
        !           496:                return(1);
        !           497:        }
        !           498: }
        !           499: 
        !           500: /*
        !           501:  * Put a byte into the scsi command register.
        !           502:  */
        !           503: sc_putbyte(c, bits, data)
        !           504:        register struct scsi_ctlr *c;
        !           505:        register u_short bits;
        !           506:        register u_char data;
        !           507: {
        !           508:        register struct scsi_ha_reg *har = c->c_har;
        !           509:        register int icr;
        !           510: 
        !           511:        if (sc_wait(c, ICR_REQUEST) == 0) {
        !           512:                sc_reset(c);
        !           513:                return (0);
        !           514:        }
        !           515:        icr = har->icr;
        !           516:        if ((icr & ICR_BITS) != bits) {
        !           517: #ifdef SCSI_DEBUG
        !           518:                printf("sc_putbyte error.\n");
        !           519:                sc_pr_icr("icr is     ", icr);
        !           520:                sc_pr_icr("waiting for", bits);
        !           521: #endif SCSI_DEBUG
        !           522:                sc_reset(c);
        !           523:                return (0);
        !           524:        }
        !           525:        har->cmd_stat = data;
        !           526:        return (1);
        !           527: }
        !           528: 
        !           529: /*
        !           530:  * Get a byte from the scsi command/status register.
        !           531:  */
        !           532: sc_getbyte(c, bits)
        !           533:        register struct scsi_ctlr *c;
        !           534: {
        !           535:        register struct scsi_ha_reg *har = c->c_har;
        !           536:        register int icr;
        !           537: 
        !           538:        if (sc_wait(c, ICR_REQUEST) == 0) {
        !           539:                sc_reset(c);
        !           540:                return (-1);
        !           541:        }
        !           542:        icr = har->icr;
        !           543:        if ((icr & ICR_BITS) != bits) {
        !           544:                if (bits == ICR_STATUS) {
        !           545:                        return (-1);    /* no more status */
        !           546:                }
        !           547: #ifdef SCSI_DEBUG
        !           548:                printf("sc_getbyte error.\n");
        !           549:                sc_pr_icr("icr is     ", icr);
        !           550:                sc_pr_icr("waiting for", bits);
        !           551: #endif SCSI_DEBUG
        !           552:                sc_reset(c);
        !           553:                return (-1);
        !           554:        }
        !           555:        return (har->cmd_stat);
        !           556: }
        !           557: 
        !           558: sc_dmacnt(c)
        !           559:        register struct scsi_ctlr *c;
        !           560: {
        !           561:        return (~c->c_har->dma_count);
        !           562: }
        !           563: 
        !           564: sc_reset(c)
        !           565:        register struct scsi_ctlr *c;
        !           566: {
        !           567:        register struct scsi_ha_reg *har = c->c_har;
        !           568: 
        !           569:        har->icr = ICR_RESET;
        !           570:        DELAY(50);
        !           571:        har->icr = 0;
        !           572: #ifdef SCSI_DEBUG
        !           573:        printf("scsi host adapter reset\n");
        !           574: #endif SCSI_DEBUG
        !           575: }
        !           576: 
        !           577: /*
        !           578:  * Get status bytes from scsi bus.
        !           579:  */
        !           580: sc_getstatus(un, recurse)
        !           581:        register struct scsi_unit *un;
        !           582: {
        !           583:        register struct scsi_ctlr *c = un->un_c;
        !           584:        register u_char *cp = (u_char *)&c->c_scb;
        !           585:        struct scsi_cdb save_cdb;
        !           586:        struct scsi_scb save_scb;
        !           587:        register int i;
        !           588:        register int b;
        !           589:        register int save_dma_addr;
        !           590:        register int save_dma_count;
        !           591:        register int save_reg_dma_count;
        !           592:        int resid;
        !           593:        short retval = 1;
        !           594:        int s;
        !           595: 
        !           596:        /* get all the status bytes */
        !           597:        for (i = 0;;) {
        !           598:                b = sc_getbyte(c, ICR_STATUS);
        !           599:                if (b < 0) {
        !           600:                        break;
        !           601:                }
        !           602:                if (i < STATUS_LEN) {
        !           603:                        cp[i++] = b;
        !           604:                }
        !           605:        }
        !           606: 
        !           607:        /* get command complete message */
        !           608:        b = sc_getbyte(c, ICR_MESSAGE_IN);
        !           609:        if (b != SC_COMMAND_COMPLETE) {
        !           610:                if (scsi_debug) {
        !           611:                        printf("Invalid SCSI message: %x\n", b);
        !           612:                        printf("Status bytes:");
        !           613:                        for (b = 0; b < i; b++) {
        !           614:                                printf(" %x", cp[b]);
        !           615:                        }
        !           616:                        printf("\n");
        !           617:                }
        !           618:                return (0);
        !           619:        }
        !           620:        if (scsi_debug) {
        !           621:                printf("sc%d: sc_getstatus: Got status ", SCNUM(c));
        !           622:                for (b = 0; b < i; b++) {
        !           623:                        printf(" %x", cp[b]);
        !           624:                }
        !           625:                printf("\n");
        !           626:        }
        !           627:        if (c->c_scb.busy) {
        !           628:                return (0);
        !           629:        }
        !           630: 
        !           631:        /* check for sense data */
        !           632:        if (c->c_scb.chk) {
        !           633:                if (recurse) {
        !           634:                        printf("scsi: chk on sense: invalid\n");
        !           635:                        return (0);
        !           636:                }
        !           637: 
        !           638:                /* save information while we get sense */
        !           639:                save_cdb = c->c_cdb;
        !           640:                save_scb = c->c_scb;
        !           641:                save_dma_addr = un->un_dma_addr;
        !           642:                save_dma_count = un->un_dma_count;
        !           643:                save_reg_dma_count = c->c_har->dma_count;
        !           644: 
        !           645:                /* set up for getting sense */
        !           646:                c->c_cdb.cmd = SC_REQUEST_SENSE;
        !           647:                c->c_cdb.lun = un->un_lun;
        !           648:                cdbaddr(&c->c_cdb, 0);
        !           649:                c->c_cdb.count = sizeof(struct scsi_sense);
        !           650:                un->un_dma_addr = (int)c->c_sense - (int)DVMA;
        !           651:                un->un_dma_count = sizeof(struct scsi_sense);
        !           652: 
        !           653:                /* get sense */
        !           654:                if ((s=0),sc_cmd(c, un, 0) == 0 ||
        !           655:                    (s=1),sc_cmdwait(c) == 0 ||
        !           656:                    (s=2),sc_getstatus(un, 1) == 0) {
        !           657:                        printf("scsi: cannot get sense %d\n", s);
        !           658:                        sc_off(un);
        !           659:                        retval = 0;
        !           660:                } 
        !           661:                resid = ~c->c_har->dma_count;
        !           662:                if (resid < 0) {
        !           663:                        printf("scsi: dma_count %x resid %d",
        !           664:                            c->c_har->dma_count, resid);
        !           665:                        panic("scsi sense count too big.");
        !           666:                }
        !           667: 
        !           668:                /* restore pre sense information */
        !           669:                c->c_cdb = save_cdb;
        !           670:                c->c_scb = save_scb;
        !           671:                un->un_dma_addr = save_dma_addr;
        !           672:                un->un_dma_count = save_dma_count;
        !           673:                c->c_har->dma_count = save_reg_dma_count;
        !           674:        }
        !           675:        return (retval);
        !           676: }
        !           677: 
        !           678: #ifdef SCSI_DEBUG
        !           679: /*
        !           680:  * Print out the scsi host adapter interface control register.
        !           681:  */
        !           682: sc_pr_icr(cp, i)
        !           683:        register char *cp;
        !           684: {
        !           685:        printf("\t%s: %x ", cp, i);
        !           686:        if (i & ICR_PARITY_ERROR)
        !           687:                printf("Parity err ");
        !           688:        if (i & ICR_BUS_ERROR)
        !           689:                printf("Bus err ");
        !           690:        if (i & ICR_ODD_LENGTH)
        !           691:                printf("Odd len ");
        !           692:        if (i & ICR_INTERRUPT_REQUEST)
        !           693:                printf("Int req ");
        !           694:        if (i & ICR_REQUEST) {
        !           695:                printf("Req ");
        !           696:                switch (i & ICR_BITS) {
        !           697:                case 0:
        !           698:                        printf("Data out ");
        !           699:                        break;
        !           700:                case ICR_INPUT_OUTPUT:
        !           701:                        printf("Data in ");
        !           702:                        break;
        !           703:                case ICR_COMMAND_DATA:
        !           704:                        printf("Command ");
        !           705:                        break;
        !           706:                case ICR_COMMAND_DATA | ICR_INPUT_OUTPUT:
        !           707:                        printf("Status ");
        !           708:                        break;
        !           709:                case ICR_MESSAGE | ICR_COMMAND_DATA:
        !           710:                        printf("Msg out ");
        !           711:                        break;
        !           712:                case ICR_MESSAGE | ICR_COMMAND_DATA | ICR_INPUT_OUTPUT:
        !           713:                        printf("Msg in ");
        !           714:                        break;
        !           715:                default:
        !           716:                        printf("DCM: %x ", i & ICR_BITS);
        !           717:                        break;
        !           718:                }
        !           719:        }
        !           720:        if (i & ICR_PARITY)
        !           721:                printf("Parity ");
        !           722:        if (i & ICR_BUSY)
        !           723:                printf("Busy ");
        !           724:        if (i & ICR_SELECT)
        !           725:                printf("Sel ");
        !           726:        if (i & ICR_RESET)
        !           727:                printf("Reset ");
        !           728:        if (i & ICR_PARITY_ENABLE)
        !           729:                printf("Par ena ");
        !           730:        if (i & ICR_WORD_MODE)
        !           731:                printf("Word mode ");
        !           732:        if (i & ICR_DMA_ENABLE)
        !           733:                printf("Dma ena ");
        !           734:        if (i & ICR_INTERRUPT_ENABLE)
        !           735:                printf("Int ena ");
        !           736:        printf("\n");
        !           737: }
        !           738: 
        !           739: /*
        !           740:  * Print out status completion block.
        !           741:  */
        !           742: sc_pr_scb(scbp)
        !           743:        register struct scsi_scb *scbp;
        !           744: {
        !           745:        register u_char *cp;
        !           746: 
        !           747:        cp = (u_char *) scbp;
        !           748:        printf("scb: %x", cp[0]);
        !           749:        if (scbp->ext_st1) {
        !           750:                printf(" %x", cp[1]);
        !           751:                if (scbp->ext_st2) {
        !           752:                        printf(" %x", cp[2]);
        !           753:                }
        !           754:        }
        !           755:        if (scbp->is) {
        !           756:                printf(" intermediate status");
        !           757:        }
        !           758:        if (scbp->busy) {
        !           759:                printf(" busy");
        !           760:        }
        !           761:        if (scbp->cm) {
        !           762:                printf(" condition met");
        !           763:        }
        !           764:        if (scbp->chk) {
        !           765:                printf(" check");
        !           766:        }
        !           767:        if (scbp->ext_st1 && scbp->ha_er) {
        !           768:                printf(" host adapter detected error");
        !           769:        }
        !           770:        printf("\n");
        !           771: }
        !           772: #endif SCSI_DEBUG
        !           773: #endif NSC > 0

unix.superglobalmegacorp.com

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