Annotation of lucent/sys/src/9/next/scsi.c, revision 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.