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