Annotation of lucent/sys/src/9/next/scsi.c, revision 1.1.1.1

1.1       root        1: #include       "u.h"
                      2: #include       "../port/lib.h"
                      3: #include       "mem.h"
                      4: #include       "dat.h"
                      5: #include       "fns.h"
                      6: #include       "../port/error.h"
                      7: #include       "devtab.h"
                      8: #include       "io.h"
                      9: 
                     10: #define        DPRINT  if(debug)print
                     11: 
                     12: int    scsiownid = 7;
                     13: int    scsidebugs[8];
                     14: 
                     15: typedef struct SCSIdma SCSIdma;
                     16: typedef struct SCSIdev  SCSIdev;
                     17: 
                     18: void crankfifo(int);
                     19: void Xdelay(int);
                     20: 
                     21: enum
                     22: {
                     23:        DmaFifoOvflw = 16,      /* Amount of extra buffer for crankfifo  overflow */
                     24: 
                     25:        Dma             = 0x80,
                     26:        Nop             = 0x00,
                     27:        Flush           = 0x01,
                     28:        Reset           = 0x02,
                     29:        Select          = 0x41,
                     30:        Transfer        = 0x10,
                     31:        Cmdcomplete     = 0x11,
                     32:        Msgaccept       = 0x12
                     33: };
                     34: 
                     35: static QLock   scsilock;       /* access to device */
                     36: static Rendez  scsirendez;     /* sleep/wakeup for requesting process */
                     37: static Scsi *  curcmd;         /* currently executing command */
                     38: static int     debug;
                     39: 
                     40: /* NCR 53C90 device registers */
                     41: struct SCSIdev
                     42: {
                     43:        uchar   countlo;
                     44:        uchar   counthi;
                     45:        uchar   fifo;
                     46:        uchar   cmd;
                     47:        union { 
                     48:                struct {                /* Registers when READ */
                     49:                        uchar status;
                     50:                        uchar intr;
                     51:                        uchar step;
                     52:                        uchar fflags;
                     53:                        uchar config;
                     54:                        uchar Reserved1;
                     55:                        uchar Reserved2;
                     56:                };
                     57:                struct {                /* Registers when WRITTEN */
                     58:                        uchar destid;
                     59:                        uchar timeout;
                     60:                        uchar syncperiod;
                     61:                        uchar syncoffset;
                     62:                        uchar XXX;
                     63:                        uchar clkconf;
                     64:                        uchar test;     
                     65:                };                                                                              
                     66:        };
                     67: }; 
                     68: 
                     69: /*
                     70:  * allocate a scsi buf of any length
                     71:  * must be called at ialloc time and never freed
                     72:  */
                     73: Scsibuf *
                     74: scsialloc(ulong n)
                     75: {
                     76:        Scsibuf *b;
                     77:        ulong l, p;
                     78: 
                     79:        b = xalloc(sizeof(Scsibuf));
                     80:        p = (ulong)xspanalloc(n + 2*DmaFifoOvflw, BY2PG, 0);
                     81:        b->virt = (uchar *)kmappa(p);
                     82:        for(l = BY2PG; l < n + 2*DmaFifoOvflw + BY2PG; l += BY2PG)
                     83:                kmappa(p+l);
                     84:        b->phys = (uchar*)p;
                     85:        return b;
                     86: }
                     87: 
                     88: void
                     89: initscsi(void)
                     90: {
                     91: }
                     92: 
                     93: void
                     94: resetscsi(void)
                     95: {
                     96:        SCSIdev *dev = (SCSIdev *)SCSI;
                     97: 
                     98:        INITCTL(0x80);
                     99:        SETCTL(Int_mask);
                    100:        CLRCTL(Cpu_dma);
                    101: 
                    102:        dev->cmd = Reset;
                    103:        dev->cmd = Nop;
                    104:        dev->countlo = 0;
                    105:        dev->counthi = 0;
                    106:        dev->timeout = 146;
                    107:        dev->syncperiod = 0;
                    108:        dev->syncoffset = 0;
                    109:        dev->config = 0x10|(scsiownid&7);       /* Parity on | Bus id */
                    110:        dev->cmd = Dma|Nop;
                    111: }
                    112: 
                    113: static int
                    114: scsidone(void *arg)
                    115: {
                    116:        USED(arg);
                    117:        return (curcmd == 0);
                    118: }
                    119: 
                    120: int
                    121: scsiexec(Scsi *p, int rflag)
                    122: {
                    123:        SCSIdev *dev = (SCSIdev *)SCSI;
                    124:        SCSIdma *dma = (SCSIdma *)SCSIDMA;
                    125:        ulong n, up;
                    126: 
                    127:        debug = scsidebugs[p->target&7];
                    128:        DPRINT("scsi %d.%d cmd=0x%2.2ux ", p->target, p->lun, *(p->cmd.ptr));
                    129:        qlock(&scsilock);
                    130:        qlock(&dmalock);
                    131: 
                    132:        p->rflag = rflag;
                    133:        p->status = 0;
                    134: 
                    135:        CLRCTL(Cpu_dma);
                    136: 
                    137:        dma->chainbase = 0;
                    138:        dma->chainlimit = 0;
                    139:        dma->csr = Dinit | Dcreset | Dclrcint;
                    140: 
                    141:        dev->counthi = 0;
                    142:        dev->countlo = 0;
                    143:        dev->cmd = Dma|Nop;
                    144:        dev->cmd = Flush;               /* clear scsi fifo */
                    145: 
                    146:        while(p->cmd.ptr < p->cmd.lim)
                    147:                dev->fifo = *(p->cmd.ptr)++;
                    148: 
                    149:        dev->destid = p->target&7;
                    150:        n = p->data.lim - p->data.ptr;
                    151:        dev->counthi = n>>8;
                    152:        dev->countlo = n;
                    153:        dev->cmd = Dma|Nop;
                    154:        if(n) {
                    155:                up = (ulong)p->b->phys;
                    156:                dma->base  = up;
                    157:                dma->limit = up + ((n + 0xf)&~0xf);
                    158:                if(!rflag)
                    159:                        dma->limit += DmaFifoOvflw;     /* NeXT brain damage */
                    160:        }
                    161: 
                    162:        curcmd = p;
                    163:        dev->cmd = Select;
                    164: 
                    165:        while(waserror())
                    166:                ;
                    167:        DPRINT("S<");
                    168:        sleep(&scsirendez, scsidone, 0);
                    169:        poperror();
                    170:        qunlock(&dmalock);
                    171:        qunlock(&scsilock);
                    172:        debug = 0;
                    173:        return p->status;
                    174: }
                    175: 
                    176: void
                    177: scsiintr(int type)
                    178: {
                    179:        SCSIdev *dev = (SCSIdev *)SCSI;
                    180:        SCSIdma *dma = (SCSIdma *)SCSIDMA;
                    181:        Scsi *p = curcmd;
                    182:        int status, step, intr, n;
                    183:        ulong m, csr;
                    184: 
                    185:        USED(type);
                    186:        csr = dma->csr;
                    187: 
                    188:        CLRCTL(Cpu_dma);                /* Access the registers */
                    189: 
                    190:        /* Read cause */
                    191:        status = dev->status;
                    192:        step = dev->step;
                    193:        intr = dev->intr;
                    194: 
                    195:        intr |= ((step&7)<<8);
                    196: 
                    197:        DPRINT("\n\t[ status=%2.2ux step/intr=%3.3ux", status, intr);
                    198:        DPRINT(" dma=%8.8ux cmd status=%4.4ux ]", csr, p ? p->status : 0xffff);
                    199: 
                    200:        if(p == 0 || (intr & 0x80)) {   /* SCSI bus reset */
                    201:                dev->cmd = Nop;
                    202:                goto Done;
                    203:        }
                    204: 
                    205:        switch(p->status>>8){
                    206:        case 0x00:              /* Select was issued */
                    207:                switch(intr){
                    208:                default:
                    209:                        print("devscsi: bad case\n");
                    210:                        goto Done;
                    211:                case 0x020:             /* arbitration complete, selection timed out */
                    212:                        goto Done;
                    213:                case 0x218:             /* selection complete, no command phase */
                    214:                        p->status = 0x1000;
                    215:                        goto Done;
                    216:                case 0x318:             /* command phase ended prematurely */
                    217:                        n = (p->cmd.lim - p->cmd.base) - (dev->fflags & 0x1f);
                    218:                        p->status = (0x30+n)<<8;
                    219:                        goto Done;
                    220:                case 0x418:             /* select sequence complete */
                    221:                        p->status = 0x4100;
                    222:                        if((status & 0x07) == p->rflag){
                    223:                                DPRINT(" Dma|Transfer ");
                    224:                                dma->csr = Dcreset|Dinit;
                    225:                                dma->csr = 0;
                    226:                                if(p->rflag) {
                    227:                                        SETCTL(Dmadir);
                    228:                                        dma->csr = Dseten|Dsetread|Dinit;
                    229:                                }
                    230:                                else {
                    231:                                        CLRCTL(Dmadir);
                    232:                                        dma->csr = Dseten|Dinit;
                    233:                                }
                    234:                                dev->cmd = Dma|Transfer;
                    235:                                SETCTL(Cpu_dma);
                    236:                                return;
                    237:                        }
                    238:                        else if((status & 0x07) != 3)
                    239:                                goto Done;
                    240:                        /* else fall through */
                    241:                }
                    242: 
                    243:        case 0x41:      /* data transfer, if any, is finished */
                    244:                p->status = 0x4600;
                    245:                p->data.ptr = p->data.lim - ((dev->counthi<<8)|dev->countlo);
                    246:                if((status & 0x07) != 3)
                    247:                        goto Done;
                    248:                crankfifo(dma->limit - dma->base);
                    249:                dma->csr = Dcreset;
                    250:                DPRINT(" Cmdcomplete");
                    251:                dev->cmd = Cmdcomplete;
                    252:                return;
                    253: 
                    254:        case 0x46:      /* Cmdcomplete was issued */
                    255:                p->status = 0x6000|dev->fifo;
                    256:                m = dev->fifo;
                    257:                DPRINT(" end status=0x%2.2ux msg=0x%2.2ux", p->status, m);
                    258:                DPRINT(" Msgaccept");
                    259:                dev->cmd = Msgaccept;
                    260:                return;
                    261: 
                    262:        case 0x60:      /* Msgaccept was issued */
                    263:                goto Done;
                    264:        }
                    265: Done:
                    266:        DPRINT(" Done");
                    267:        curcmd = 0;
                    268:        wakeup(&scsirendez);
                    269: }
                    270: 
                    271: void
                    272: crankfifo(int n)
                    273: {
                    274:        if(n <= 0)
                    275:                return;
                    276: 
                    277:        n = n>>2;
                    278:        SETCTL(Cpu_dma);
                    279:        while(n--) {
                    280:                CLRCTL(Fifofl);
                    281:                SETCTL(Fifofl);
                    282:                CLRCTL(Fifofl);
                    283:        }
                    284:        CLRCTL(Cpu_dma);
                    285: }
                    286: 
                    287: void
                    288: Xdelay(int time)
                    289: {
                    290:        time *= 100;
                    291:        while(time--)
                    292:                ;       
                    293: }

unix.superglobalmegacorp.com

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