Annotation of researchv9/sys/boot/stand/si.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * @(#)si.c 1.1 86/02/03 Copyright (c) 1985 by Sun Microsystems, Inc.
        !             3:  */
        !             4: #include <sys/types.h>
        !             5: #include <sys/inode.h>
        !             6: #include <sys/buf.h>
        !             7: #include <sun/dklabel.h>
        !             8: #include <sun/dkio.h>
        !             9: #include <sundev/screg.h>
        !            10: #include <sundev/sireg.h>
        !            11: #include <sundev/scsi.h>
        !            12: #include "saio.h"
        !            13: #include <machine/sunromvec.h>
        !            14: #include <machine/idprom.h>
        !            15: 
        !            16: /*
        !            17:  * Low-level routines common to all devices on the SCSI bus.
        !            18:  */
        !            19: 
        !            20: /*
        !            21:  * Interface to the routines in this module is via a second "sip"
        !            22:  * structure contained in the caller's local variables.
        !            23:  *
        !            24:  * This "sip" must be initialized with sip->si_boottab = sidriver
        !            25:  * and must then be devopen()ed before any I/O can be done.
        !            26:  *
        !            27:  * The device must be closed with devclose().
        !            28:  */
        !            29: 
        !            30: 
        !            31: /* how si addresses look to the si vme scsi dma hardware */
        !            32: #define        SI_VME_DMA_ADDR(x)      (((int)x)&0x000FFFFF)
        !            33: 
        !            34: /* how si addresses look to the sun3/50 scsi dma hardware */
        !            35: #define        SI_OB_DMA_ADDR(x)       (((int)x)&0x00FFFFFF)
        !            36: struct sidma {
        !            37:        struct udc_table        udct;   /* dma information for udc */
        !            38: };
        !            39: 
        !            40: /*
        !            41:  * The interfaces we export
        !            42:  */
        !            43: extern char *devalloc();
        !            44: extern char *resalloc();
        !            45: extern int nullsys();
        !            46: int siopen();
        !            47: 
        !            48: struct boottab sidriver =
        !            49:        {"sd",  nullsys,        nullsys,        siopen,         nullsys,
        !            50:                nullsys,        "",     0};
        !            51: 
        !            52: 
        !            53: #define SI_VME_BASE    0x200000
        !            54: #define SI_OB_BASE     0x140000
        !            55: #define SI_SIZE                0x4000
        !            56: 
        !            57: /*
        !            58:  * Probe for si host adaptor interface. 
        !            59:  * Return 1 if found one, 0 otherwise.
        !            60:  */
        !            61: int
        !            62: siprobe(sip)
        !            63:        register struct saioreq *sip;
        !            64: {
        !            65:        register struct scsi_si_reg *sir;
        !            66:        struct idprom id;
        !            67:        register int base;
        !            68:        register int scsi_nstd;
        !            69:        register int ctlr;
        !            70:        enum MAPTYPES space;
        !            71: 
        !            72:        /* determine type of si interface */
        !            73:        if (idprom(IDFORM_1, &id) == IDFORM_1) {
        !            74:                if (id.id_machine == IDM_SUN3_M25) {
        !            75:                        return (1);
        !            76:                } else {
        !            77:                        base = SI_VME_BASE;
        !            78:                        space = MAP_VME24A16D;
        !            79:                        scsi_nstd = 2;
        !            80:                }
        !            81:        } else {
        !            82:                return (0);
        !            83:        }
        !            84: 
        !            85:        /* get base address of registers */
        !            86:        if (sip->si_ctlr < scsi_nstd) {
        !            87:                ctlr = base + (sip->si_ctlr * SI_SIZE);
        !            88:        } else {
        !            89:                return (0);
        !            90:        }
        !            91: 
        !            92:        /* now map it in */
        !            93:        if ((sir = (struct scsi_si_reg *)devalloc(space, ctlr, 
        !            94:            sizeof(struct scsi_si_reg))) == 0) {
        !            95:                return (0);
        !            96:        }
        !            97:        
        !            98:        /*
        !            99:         * SI vme scsi host adaptor occupies 2K bytes in the vme 
        !           100:         * address space. SC vme scsi host adaptor occupies 4K 
        !           101:         * bytes in the vme address space.
        !           102:         * peek past 2K bytes to determine which host adaptor is there.
        !           103:         */
        !           104:        if (peek((int)sir+0x800) == -1) {
        !           105:                return (1);
        !           106:        } else {
        !           107:                return (0);
        !           108:        }
        !           109: }
        !           110: 
        !           111: /*
        !           112:  * Open the SCSI host adapter.
        !           113:  */
        !           114: int
        !           115: siopen(sip)
        !           116:        register struct saioreq *sip;
        !           117: {
        !           118:        register struct scsi_si_reg *sir;
        !           119:        struct idprom id;
        !           120:        register int base;
        !           121:        register int scsi_nstd;
        !           122:        enum MAPTYPES space;
        !           123: 
        !           124:        /* determine type of si interface */
        !           125:        if (idprom(IDFORM_1, &id) == IDFORM_1) {
        !           126:                if (id.id_machine == IDM_SUN3_M25) {
        !           127:                        base = SI_OB_BASE;
        !           128:                        space = MAP_OBIO;
        !           129:                        scsi_nstd = 1;
        !           130:                } else {
        !           131:                        base = SI_VME_BASE;
        !           132:                        space = MAP_VME24A16D;
        !           133:                        scsi_nstd = 2;
        !           134:                }
        !           135:        } else {
        !           136:                return (-1);
        !           137:        }
        !           138: 
        !           139:        /* get base address of registers */
        !           140:        if (sip->si_ctlr < scsi_nstd) {
        !           141:                sip->si_ctlr = base + (sip->si_ctlr * SI_SIZE);
        !           142:        } else {
        !           143:                return (-1);
        !           144:        }
        !           145: 
        !           146:        /* now map it in */
        !           147:        sip->si_devaddr = devalloc(space, sip->si_ctlr, 
        !           148:            sizeof(struct scsi_si_reg));
        !           149:        if (sip->si_devaddr == 0) {
        !           150:                return (-1);
        !           151:        }
        !           152: 
        !           153:        /* allocate dma resources */
        !           154:        if (base == SI_OB_BASE) {
        !           155:                sip->si_dmaaddr = resalloc(RES_DMAMEM, sizeof(struct sidma));
        !           156:                if (sip->si_dmaaddr == 0) {
        !           157:                        return (-1);
        !           158:                }
        !           159:        } else {
        !           160:                sip->si_dmaaddr = 0;
        !           161:        }
        !           162: 
        !           163:        /* reset registers */
        !           164:        sir = (struct scsi_si_reg *) sip->si_devaddr;
        !           165:        sir->csr = 0;
        !           166:        DELAY(10);
        !           167:        sir->csr = SI_CSR_SCSI_RES | SI_CSR_FIFO_RES;
        !           168:        sir->bcr = 0;
        !           169:        if (base == SI_VME_BASE) {
        !           170:                sir->dma_addr = 0;
        !           171:                sir->dma_count = 0;
        !           172:                sir->iv_am = VME_SUPV_DATA_24;
        !           173:        }
        !           174:        return (0);
        !           175: }
        !           176: 
        !           177: 
        !           178: /*
        !           179:  * Write a command to the SCSI bus.
        !           180:  *
        !           181:  * The supplied sip is the one opened by siopen().
        !           182:  * DMA is done based on sip->si_ma and sip->si_cc.
        !           183:  *
        !           184:  * Returns -1 for error, otherwise returns the residual count not DMAed
        !           185:  * (zero for success).
        !           186:  *
        !           187:  * FIXME, this must be accessed via a boottab vector,
        !           188:  * to allow host adap to switch.
        !           189:  * Must pass cdb, scb in sip somewhere...
        !           190:  */
        !           191: int
        !           192: sidoit(cdb, scb, sip)
        !           193:        struct scsi_cdb *cdb;
        !           194:        struct scsi_scb *scb;
        !           195:        register struct saioreq *sip;
        !           196: {
        !           197:        register struct scsi_si_reg *sir;
        !           198:        register char *cp;
        !           199:        register int i;
        !           200:        register int b;
        !           201:        register int ob;
        !           202:        u_char junk;
        !           203: 
        !           204:        /* get to scsi control logic registers */
        !           205:        sir = (struct scsi_si_reg *) sip->si_devaddr;
        !           206:        if (sip->si_dmaaddr) {
        !           207:                ob = 1;
        !           208:        } else {
        !           209:                ob = 0;
        !           210:        }
        !           211: 
        !           212:        i = 100000;
        !           213:        for(;;) {
        !           214:                if ((sir->sbc_rreg.cbsr & SBC_CBSR_BSY) == 0) {
        !           215:                        break;
        !           216:                }
        !           217:                if (i-- <= 0) {
        !           218:                        si_reset(sir, ob);
        !           219:                        return (-1);
        !           220:                }
        !           221:        }
        !           222: 
        !           223:        /* select target */
        !           224:        sir->sbc_wreg.odr = (1 << sip->si_unit) | SI_HOST_ID;
        !           225:        sir->sbc_wreg.icr = SBC_ICR_DATA;
        !           226:        sir->sbc_wreg.icr |= SBC_ICR_SEL;
        !           227: 
        !           228:        /* wait for target to acknowledge our selection */
        !           229:        if (si_sbc_wait(&sir->sbc_rreg.cbsr, SBC_CBSR_BSY, 1) == 0) {
        !           230:                sc_error("sel, cbsr bsy never set");
        !           231:                goto failed;
        !           232:        }
        !           233:        sir->sbc_wreg.icr = 0;
        !           234: 
        !           235:        /* do initial dma setup */
        !           236:        sir->bcr = 0;   /* also reset dma_count for vme */
        !           237:        if (sip->si_cc > 0) {
        !           238:                if ((cdb->cmd == SC_READ) || (cdb->cmd == SC_REQUEST_SENSE)) {
        !           239:                        sir->csr &= ~SI_CSR_SEND;
        !           240:                } else {
        !           241:                        sir->csr |= SI_CSR_SEND;
        !           242:                }
        !           243:                sir->csr &= ~SI_CSR_FIFO_RES;
        !           244:                sir->csr |= SI_CSR_FIFO_RES;
        !           245:                sir->bcr = sip->si_cc;
        !           246:                if (ob == 0)
        !           247:                        sir->bcrh = 0;
        !           248:        }
        !           249: 
        !           250:        /* put command onto scsi bus */
        !           251:        cp = (char *)cdb;
        !           252:        if (si_putbyte(sir, PHASE_COMMAND, cp, sizeof(struct scsi_cdb)) == 0) {
        !           253:                sc_error("put of cmd onto scsi bus failed");
        !           254:                goto failed;
        !           255:        }
        !           256: 
        !           257:        /* finish dma setup and wait for dma completion */
        !           258:        if (sip->si_cc > 0) {
        !           259:                if (ob) {
        !           260:                    si_ob_dma_setup(sir, 
        !           261:                        &(((struct sidma *)sip->si_dmaaddr)->udct), cdb->cmd,
        !           262:                        sip->si_cc, sip->si_ma);
        !           263:                } else {
        !           264:                        if ((int)sip->si_ma & 1) {
        !           265:                                sc_error("dma begins on odd address");
        !           266:                                goto failed;
        !           267:                        } else if ((int)sip->si_ma & 2) {
        !           268:                                sir->csr |= SI_CSR_BPCON;
        !           269:                        } else {
        !           270:                                sir->csr &= ~SI_CSR_BPCON;
        !           271:                        }
        !           272:                        sir->dma_addr = SI_VME_DMA_ADDR(sip->si_ma);
        !           273:                        sir->dma_count = sip->si_cc;
        !           274:                }
        !           275: 
        !           276:                /* setup sbc and start dma */
        !           277:                sir->sbc_wreg.mr |= SBC_MR_DMA;
        !           278:                if ((cdb->cmd == SC_READ) || (cdb->cmd == SC_REQUEST_SENSE)) {
        !           279:                        sir->sbc_wreg.tcr = TCR_DATA_IN;
        !           280:                        sir->sbc_wreg.ircv = 0;
        !           281:                } else {
        !           282:                        sir->sbc_wreg.tcr = TCR_DATA_OUT;
        !           283:                        sir->sbc_wreg.icr = SBC_ICR_DATA;
        !           284:                        sir->sbc_wreg.send = 0;
        !           285:                }
        !           286:                if (ob == 0) {
        !           287:                        sir->csr |= SI_CSR_DMA_EN;
        !           288:                }
        !           289: 
        !           290:                /* wait for dma completion */
        !           291:                if (si_wait(&sir->csr, 
        !           292:                    SI_CSR_SBC_IP|SI_CSR_DMA_IP|SI_CSR_DMA_CONFLICT, 1)
        !           293:                    == 0) {
        !           294:                        sc_error("dma never completed");
        !           295:                        if (ob == 0) {
        !           296:                                sir->csr &= ~SI_CSR_DMA_EN;
        !           297:                        }
        !           298:                        si_dma_cleanup(sir, ob);
        !           299:                        goto failed;
        !           300:                }
        !           301:                if (ob == 0) {
        !           302:                        sir->csr &= ~SI_CSR_DMA_EN;
        !           303:                }
        !           304: 
        !           305:                /* check reason for dma completion */
        !           306:                if (sir->csr & SI_CSR_SBC_IP) {
        !           307:                        /* dma operation should end with a phase mismatch */
        !           308:                        si_sbc_wait(&sir->sbc_rreg.bsr, SBC_BSR_PMTCH, 0);
        !           309:                } else {
        !           310:                        if (sir->csr & SI_CSR_DMA_CONFLICT) {
        !           311:                                sc_error("invalid reg access during dma");
        !           312:                        } else if (sir->csr & SI_CSR_DMA_BUS_ERR) {
        !           313:                                sc_error("bus error during dma");
        !           314:                        } else {
        !           315:                                if (ob)
        !           316:                                        sc_error("unknown dma failure");
        !           317:                                else
        !           318:                                        sc_error("dma overrun");
        !           319:                        }
        !           320:                        si_dma_cleanup(sir, ob);
        !           321:                        goto failed;
        !           322:                }
        !           323: 
        !           324:                /* handle special dma recv situations */
        !           325:                if ((cdb->cmd == SC_READ) || (cdb->cmd == SC_REQUEST_SENSE)) {
        !           326:                    if (ob) {
        !           327:                        sir->udc_raddr = UDC_ADR_COUNT;
        !           328:                        if (si_wait(&sir->csr, SI_CSR_FIFO_EMPTY, 1) == 0) {
        !           329:                                sc_error("fifo never emptied");
        !           330:                                si_dma_cleanup(sir, ob);
        !           331:                                goto failed;
        !           332:                        }
        !           333:                        /* if odd byte recv, must grab last byte by hand */
        !           334:                        if ((sip->si_cc - sir->bcr) & 1) {
        !           335:                                cp = sip->si_ma + (sip->si_cc - sir->bcr) - 1;
        !           336:                                *cp = (sir->fifo_data & 0xff00) >> 8;
        !           337: 
        !           338:                        /* udc may not dma last word */
        !           339:                        } else if (((sir->udc_rdata*2) - sir->bcr) == 2) {
        !           340:                                cp = sip->si_ma + (sip->si_cc - sir->bcr);
        !           341:                                *(cp - 2) = (sir->fifo_data & 0xff00) >> 8;
        !           342:                                *(cp - 1) = sir->fifo_data & 0x00ff;
        !           343:                        }
        !           344: 
        !           345:                    } else if ((sir->csr & SI_CSR_LOB) != 0) {
        !           346:                        cp = sip->si_ma + (sip->si_cc - sir->bcr);
        !           347:                        if ((sir->csr & SI_CSR_BPCON) == 0) {
        !           348:                            switch (sir->csr & SI_CSR_LOB) {
        !           349:                            case SI_CSR_LOB_THREE:
        !           350:                                    *(cp - 3) = (sir->bpr & 0xff000000) >> 24;
        !           351:                                    *(cp - 2) = (sir->bpr & 0x00ff0000) >> 16;
        !           352:                                    *(cp - 1) = (sir->bpr & 0x0000ff00) >> 8;
        !           353:                                    break;
        !           354:                            case SI_CSR_LOB_TWO:
        !           355:                                    *(cp - 2) = (sir->bpr & 0xff000000) >> 24;
        !           356:                                    *(cp - 1) = (sir->bpr & 0x00ff0000) >> 16;
        !           357:                                    break;
        !           358:                            case SI_CSR_LOB_ONE:
        !           359:                                    *(cp - 1) = (sir->bpr & 0xff000000) >> 24;
        !           360:                                    break;
        !           361:                            }
        !           362:                        } else {
        !           363:                                *(cp - 1) = (sir->bpr & 0x0000ff00) >> 8;
        !           364:                        }
        !           365:                    }
        !           366:                }
        !           367: 
        !           368:                /* clear sbc interrupt */
        !           369:                junk = sir->sbc_rreg.clr;
        !           370: 
        !           371:                /* cleanup after a dma operation */
        !           372:                si_dma_cleanup(sir, ob);
        !           373:        }
        !           374: 
        !           375:        /* get status */
        !           376:        cp = (char *)scb;
        !           377:        for (i = 0;;) {
        !           378:                b = si_getbyte(sir, PHASE_STATUS);
        !           379:                if (b == -1) {
        !           380:                        break;
        !           381:                }
        !           382:                if (i < STATUS_LEN) {
        !           383:                        cp[i++] = b;
        !           384:                }
        !           385:        }
        !           386:        b = si_getbyte(sir, PHASE_MSG_IN);
        !           387:        if (b != SC_COMMAND_COMPLETE) {
        !           388:                if (b >= 0) {   /* if not, si_getbyte already printed msg */
        !           389:                        sc_error("invalid message");
        !           390:                }
        !           391:                goto failed;
        !           392:        }
        !           393:        return (sip->si_cc - sir->bcr);
        !           394: 
        !           395: failed:
        !           396:        si_reset(sir, ob);
        !           397:        return (-1);
        !           398: }
        !           399: 
        !           400: si_ob_dma_setup(sir, udct, cmd, cc, ma)
        !           401:        register struct scsi_si_reg *sir;
        !           402:        register struct udc_table *udct;
        !           403:        register u_char cmd;
        !           404:        register int cc;
        !           405:        register char *ma;
        !           406: {
        !           407:        /* setup udc dma info */
        !           408:        udct->haddr = ((SI_OB_DMA_ADDR(ma) & 0xff0000) >> 8) | 
        !           409:                UDC_ADDR_INFO;
        !           410:        udct->laddr = SI_OB_DMA_ADDR(ma) & 0xffff;
        !           411:        udct->hcmr = UDC_CMR_HIGH;
        !           412:        udct->count = cc / 2;
        !           413:        if ((cmd == SC_READ) || (cmd == SC_REQUEST_SENSE)) {
        !           414:                udct->rsel = UDC_RSEL_RECV;
        !           415:                udct->lcmr = UDC_CMR_LRECV;
        !           416:        } else {
        !           417:                udct->rsel = UDC_RSEL_SEND;
        !           418:                udct->lcmr = UDC_CMR_LSEND;
        !           419:                if (cc & 1) {
        !           420:                        udct->count++;
        !           421:                }
        !           422:        }
        !           423: 
        !           424:        /* initialize chain address register */
        !           425:        DELAY(SI_UDC_WAIT);
        !           426:        sir->udc_raddr = UDC_ADR_CAR_HIGH;
        !           427:        DELAY(SI_UDC_WAIT);
        !           428:        sir->udc_rdata = ((int)udct & 0xff0000) >> 8;
        !           429:        DELAY(SI_UDC_WAIT);
        !           430:        sir->udc_raddr = UDC_ADR_CAR_LOW;
        !           431:        DELAY(SI_UDC_WAIT);
        !           432:        sir->udc_rdata = (int)udct & 0xffff;
        !           433: 
        !           434:        /* initialize master mode register */
        !           435:        DELAY(SI_UDC_WAIT);
        !           436:        sir->udc_raddr = UDC_ADR_MODE;
        !           437:        DELAY(SI_UDC_WAIT);
        !           438:        sir->udc_rdata = UDC_MODE;
        !           439: 
        !           440:        /* issue start chain command */
        !           441:        DELAY(SI_UDC_WAIT);
        !           442:        sir->udc_raddr = UDC_ADR_COMMAND;
        !           443:        DELAY(SI_UDC_WAIT);
        !           444:        sir->udc_rdata = UDC_CMD_STRT_CHN;
        !           445: }
        !           446: 
        !           447: /*
        !           448:  * Reset some register information after a dma operation.
        !           449:  */
        !           450: si_dma_cleanup(sir, ob)
        !           451:        register struct scsi_si_reg *sir;
        !           452:        register int ob;
        !           453: {
        !           454:        if (ob) {
        !           455:                sir->udc_raddr = UDC_ADR_COMMAND;
        !           456:                DELAY(SI_UDC_WAIT);
        !           457:                sir->udc_rdata = UDC_CMD_RESET;
        !           458:        } else {
        !           459:                sir->csr &- ~SI_CSR_DMA_EN;
        !           460:                sir->dma_addr = 0;
        !           461:        }
        !           462:        sir->sbc_wreg.mr &= ~SBC_MR_DMA;
        !           463:        sir->sbc_wreg.icr = 0;
        !           464:        sir->sbc_wreg.tcr = 0;
        !           465: }
        !           466: 
        !           467: /*
        !           468:  * Wait for a condition to be (de)asserted.
        !           469:  */
        !           470: si_wait(reg, cond, set)
        !           471:        register u_short *reg;
        !           472:        register u_short cond;
        !           473:        register int set;
        !           474: {
        !           475:        register int i;
        !           476:        register u_short regval;
        !           477: 
        !           478:        for (i = 0; i < 1000000; i++) {
        !           479:                regval = *reg;
        !           480:                if ((set == 1) && (regval & cond)) {
        !           481:                        return (1);
        !           482:                }
        !           483:                if ((set == 0) && !(regval & cond)) {
        !           484:                        return (1);
        !           485:                } 
        !           486:                DELAY(600);
        !           487:        }
        !           488:        return (0);
        !           489: }
        !           490: 
        !           491: /*
        !           492:  * Wait for a condition to be (de)asserted on the scsi bus.
        !           493:  */
        !           494: si_sbc_wait(reg, cond, set)
        !           495:        register caddr_t reg;
        !           496:        register u_char cond;
        !           497:        register int set;
        !           498: {
        !           499:        register int i;
        !           500:        register u_char regval;
        !           501: 
        !           502:        for (i = 0; i < 1000000; i++) {
        !           503:                regval = *reg;
        !           504:                if ((set == 1) && (regval & cond)) {
        !           505:                        return (1);
        !           506:                }
        !           507:                if ((set == 0) && !(regval & cond)) {
        !           508:                        return (1);
        !           509:                } 
        !           510:                DELAY(600);
        !           511:        }
        !           512:        return (0);
        !           513: }
        !           514: 
        !           515: /*
        !           516:  * Put a byte onto the scsi bus.
        !           517:  */
        !           518: si_putbyte(sir, phase, data, numbytes)
        !           519:        register struct scsi_si_reg *sir;
        !           520:        register u_short phase;
        !           521:        register u_char *data;
        !           522:        register int numbytes;
        !           523: {
        !           524:        register int i;
        !           525: 
        !           526:        /* set up tcr so a phase match will occur */
        !           527:        if (phase == PHASE_COMMAND) {
        !           528:                sir->sbc_wreg.tcr = TCR_COMMAND;
        !           529:        } else if (phase == PHASE_MSG_OUT) {
        !           530:                sir->sbc_wreg.tcr = TCR_MSG_OUT;
        !           531:        } else {
        !           532:                sc_error("putbyte, bad phase specified");
        !           533:                return (0);
        !           534:        }
        !           535: 
        !           536:        /* put all desired bytes onto scsi bus */
        !           537:        for (i = 0; i < numbytes; i++) {
        !           538:                /* wait for target to request a byte */
        !           539:                if (si_sbc_wait(&sir->sbc_rreg.cbsr, SBC_CBSR_REQ, 1) == 0) {
        !           540:                        sc_error("putbyte: target never set REQ");
        !           541:                        return (0);
        !           542:                }
        !           543: 
        !           544:                /* load data for transfer */
        !           545:                sir->sbc_wreg.odr = *data++;
        !           546:                sir->sbc_wreg.icr = SBC_ICR_DATA;
        !           547: 
        !           548:                /* make sure phase match occurred */
        !           549:                if ((sir->sbc_rreg.bsr & SBC_BSR_PMTCH) == 0) {
        !           550:                        sc_error("putbyte: phase mismatch");
        !           551:                        return (0);
        !           552:                }
        !           553: 
        !           554:                /* complete req/ack handshake */
        !           555:                sir->sbc_wreg.icr |= SBC_ICR_ACK;
        !           556:                if (si_sbc_wait(&sir->sbc_rreg.cbsr, SBC_CBSR_REQ, 0) == 0) {
        !           557:                        sc_error("putbyte: target never released REQ");
        !           558:                        return (0);
        !           559:                }
        !           560:                sir->sbc_wreg.icr = 0;
        !           561:        }
        !           562:        sir->sbc_wreg.tcr = 0;
        !           563:        return (1);
        !           564: }
        !           565: 
        !           566: /*
        !           567:  * Get a byte from the scsi bus.
        !           568:  */
        !           569: si_getbyte(sir, phase)
        !           570:        register struct scsi_si_reg *sir;
        !           571:        register u_short phase;
        !           572: {
        !           573:        register u_char data;
        !           574: 
        !           575:        /* set up tcr so a phase match will occur */
        !           576:        if (phase == PHASE_STATUS) {
        !           577:                sir->sbc_wreg.tcr = TCR_STATUS;
        !           578:        } else if (phase == PHASE_MSG_IN) {
        !           579:                sir->sbc_wreg.tcr = TCR_MSG_IN;
        !           580:        } else {
        !           581:                sc_error("getbyte, bad phase specified");
        !           582:                return (-1);
        !           583:        }
        !           584: 
        !           585:        /* wait for target request */
        !           586:        if (si_sbc_wait(&sir->sbc_rreg.cbsr, SBC_CBSR_REQ, 1) == 0) {
        !           587:                sc_error("getbyte: target never set REQ");
        !           588:                sir->sbc_wreg.tcr = 0;
        !           589:                return (-1);
        !           590:        }
        !           591: 
        !           592:        /* check for correct information phase on scsi bus */
        !           593:        if (phase != (sir->sbc_rreg.cbsr & CBSR_PHASE_BITS)) {
        !           594:                if (phase != PHASE_STATUS) {
        !           595:                        sc_error("getbyte: phase mismatch");
        !           596:                }
        !           597:                sir->sbc_wreg.tcr = 0;
        !           598:                return (-1);
        !           599:        }
        !           600: 
        !           601:        /* grab data */
        !           602:        data = sir->sbc_rreg.cdr;
        !           603:        sir->sbc_wreg.icr = SBC_ICR_ACK;
        !           604: 
        !           605:        /* complete req/ack handshake */
        !           606:        if (si_sbc_wait(&sir->sbc_rreg.cbsr, SBC_CBSR_REQ, 0) == 0) {
        !           607:                sc_error("getbyte: target never released REQ");
        !           608:                sir->sbc_wreg.icr = 0;
        !           609:                sir->sbc_wreg.tcr = 0;
        !           610:                return (-1);
        !           611:        }
        !           612:        sir->sbc_wreg.icr = 0;
        !           613:        sir->sbc_wreg.tcr = 0;
        !           614:        return (data);
        !           615: }
        !           616: 
        !           617: /*
        !           618:  * Reset SCSI control logic.
        !           619:  */
        !           620: si_reset(sir, ob)
        !           621:        register struct scsi_si_reg *sir;
        !           622:        register int ob;
        !           623: {
        !           624:        register u_char junk;
        !           625: 
        !           626:        /* reset bcr, fifo, udc, and sbc */
        !           627:        sir->bcr = 0;
        !           628:        sir->csr = 0;
        !           629:        DELAY(10);
        !           630:        sir->csr = SI_CSR_SCSI_RES|SI_CSR_FIFO_RES;
        !           631:        if (ob == 0) {
        !           632:                sir->dma_addr = 0;
        !           633:                sir->dma_count = 0;
        !           634:        }
        !           635: 
        !           636:        /* issue scsi bus reset */
        !           637:        sir->sbc_wreg.icr = SBC_ICR_RST;
        !           638:        DELAY(50);
        !           639:        sir->sbc_wreg.icr = 0;
        !           640:        junk = sir->sbc_rreg.clr;
        !           641:        DELAY(10000000);
        !           642: }

unix.superglobalmegacorp.com

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