## diffname ss/scsi.c 1992/0807 ## diff -e /dev/null /n/bootesdump/1992/0807/sys/src/9/ss/scsi.c 0a #include "u.h" #include "../port/lib.h" #include "mem.h" #include "dat.h" #include "fns.h" #include "../port/error.h" #include "devtab.h" #include "io.h" static int ownid = 7; Scsibuf * scsialloc(ulong n) { Scsibuf *b; KMap *k; ulong pa, va; int i, j; b = xalloc(sizeof(Scsibuf)); /* * Allocate space in host memory for the io buffer. * Allocate a block and kmap it page by page. kmap's are initially * in reverse order so rearrange them. * NOTE: dma mustn't cross a 16Mb boundary. */ i = (n+(BY2PG-1))/BY2PG; pa = (ulong)xspanalloc(i*BY2PG, BY2PG, 16*1024*1024) & ~KZERO; va = 0; k = 0; for(j=i-1; j>=0; j--){ k = kmappa(pa+j*BY2PG, PTEMAINMEM|PTENOCACHE); if(va && va != k->va+BY2PG) panic("scsialloc va unordered\n"); va = k->va; } /* * k->va is the base of the region */ b->virt = (void*)k->va; b->phys = (void*)k->pa; return b; } /* * NCR 53C90 commands */ enum { Dma = 0x80, Nop = 0x00, Flush = 0x01, Reset = 0x02, Busreset = 0x03, Select = 0x41, Transfer = 0x10, Cmdcomplete = 0x11, Msgaccept = 0x12 }; static QLock scsilock; /* access to device */ static Rendez scsirendez; /* sleep/wakeup for requesting process */ static Scsi * curcmd; /* currently executing command */ struct { DMAdev *dma; SCSIdev *scsi; } ioaddr; void resetscsi(void) { SCSIdev *dev; DMAdev *dma; KMap *k; k = kmappa(DMA, PTENOCACHE|PTEIO); ioaddr.dma = (DMAdev*)k->va; k = kmappa(SCSI, PTENOCACHE|PTEIO); ioaddr.scsi = (SCSIdev*)k->va; dev = ioaddr.scsi; dma = ioaddr.dma; dev->cmd = Reset; dev->cmd = Nop; dev->countlo = 0; dev->counthi = 0; dev->timeout = 146; dev->syncperiod = 0; dev->syncoffset = 0; dev->config = 0x10|(ownid&7); dev->cmd = Dma|Nop; dma->csr = Dma_Reset; delay(1); dma->csr = Int_en; dma->count = 0; putenab(getenab()|ENABDMA); /**/ } void initscsi(void) { } static int scsidone(void *arg) { USED(arg); return (curcmd == 0); } int scsiexec(Scsi *p, int rflag) { SCSIdev *dev = ioaddr.scsi; DMAdev *dma = ioaddr.dma; long n; qlock(&scsilock); if(waserror()){ qunlock(&scsilock); nexterror(); } p->rflag = rflag; p->status = 0; dma->csr = Dma_Flush|Int_en; dma->addr = (ulong)p->data.ptr; dev->counthi = 0; dev->countlo = 0; dev->cmd = Dma|Nop; dev->cmd = Flush; /* clear scsi fifo */ while (p->cmd.ptr < p->cmd.lim) dev->fifo = *(p->cmd.ptr)++; dev->destid = p->target&7; n = p->data.lim - p->data.ptr; dev->counthi = n>>8; dev->countlo = n; dev->cmd = Dma|Nop; dma->csr = Int_en; curcmd = p; dev->cmd = Select; sleep(&scsirendez, scsidone, 0); poperror(); qunlock(&scsilock); return p->status; } void scsibusreset(void) { SCSIdev *dev = ioaddr.scsi; int s; s = splhi(); dev->cmd = Nop; dev->cmd = Busreset; dev->cmd = Nop; splx(s); } static void scsimoan(char *msg, int status, int intr, int dmastat) { print("scsiintr: %s:", msg); print(" status=%2.2ux step/intr=%3.3ux", status, intr); print(" dma=%8.8ux cmd status=%4.4ux\n", dmastat, curcmd ? curcmd->status : 0xffff); } void scsiintr(void) { SCSIdev *dev = ioaddr.scsi; DMAdev *dma = ioaddr.dma; Scsi *p = curcmd; int status, step, intr, n; ulong m, csr; csr = dma->csr; status = dev->status; step = dev->step; intr = dev->intr; intr |= ((step&7)<<8); if(p == 0 || (intr & 0x80)) { /* SCSI bus reset */ dev->cmd = Nop; goto Done; } switch(p->status>>8){ case 0x00: /* Select was issued */ switch(intr){ default: scsimoan("bad case", status, intr, csr); print("cmd = #%2.2ux\n", dev->cmd); resetscsi(); scsibusreset(); goto Done; case 0x020: /* arbitration complete, selection timed out */ goto Done; case 0x218: /* selection complete, no command phase */ p->status = 0x1000; scsimoan("no cmd phase", status, intr, csr); resetscsi(); scsibusreset(); goto Done; case 0x318: /* command phase ended prematurely */ n = (p->cmd.lim - p->cmd.base) - (dev->fflags & 0x1f); p->status = (0x30+n)<<8; scsimoan("short cmd phase", status, intr, csr); resetscsi(); scsibusreset(); goto Done; case 0x418: /* select sequence complete */ p->status = 0x4100; if((status & 0x07) == p->rflag){ dma->csr = p->rflag ? En_dma|Write|Int_en : En_dma|Int_en; dev->cmd = Dma|Transfer; return; }else if((status & 0x07) != 3){ scsimoan("weird phase after cmd", status, intr, csr); goto Done; } /* else fall through */ } case 0x41: /* data transfer, if any, is finished */ p->status = 0x4600; p->data.ptr = p->data.lim - ((dev->counthi<<8)|dev->countlo); if((status & 0x07) != 3){ scsimoan("weird phase after xfr", status, intr, csr); goto Done; } if(p->rflag) while(dma->csr & Pack_cnt) ; dev->cmd = Cmdcomplete; return; case 0x46: /* Cmdcomplete was issued */ p->status = 0x6000|dev->fifo; m = dev->fifo; dev->cmd = Msgaccept; return; case 0x60: /* Msgaccept was issued */ goto Done; } Done: curcmd = 0; wakeup(&scsirendez); } #ifdef notdef void scsidump(void) { SCSIdev *dev = ioaddr.scsi; DMAdev *dma = ioaddr.dma; print("\nscsi:\n"); print(" countlo=0x%2.2ux\n", dev->countlo); print(" counthi=0x%2.2ux\n", dev->counthi); print(" cmd =0x%2.2ux\n", dev->cmd); print(" status =0x%2.2ux\n", dev->status); print(" intr =0x%2.2ux\n", dev->intr); print(" step =0x%2.2ux\n", dev->step); print(" fflags =0x%2.2ux\n", dev->countlo); print(" config =0x%2.2ux\n", dev->config); print("dma:\n"); print(" csr =0x%8.8ux\n", dma->csr); print(" addr =0x%8.8ux\n", dma->addr); print(" count =0x%4.4ux\n", dma->count); print(" diag =0x%8.8ux\n", dma->diag); } #endif . ## diffname ss/scsi.c 1992/0808 ## diff -e /n/bootesdump/1992/0807/sys/src/9/ss/scsi.c /n/bootesdump/1992/0808/sys/src/9/ss/scsi.c 263a USED(m); . 257a case 8: dma->csr = Drain|Int_en; /*FALLTHROUGH*/ case 9: while(dma->csr & Pack_cnt) ; break; default: break; } } . 254,256c if(p->rflag){ switch(dmatype){ . 102a dmatype = (dma->csr>>28) & 0xF; . 95c dev->config = 0x10|(scsiownid&7); . 11a static int dmatype; . 10c int scsiownid = 7; int scsidebugs[8]; . ## diffname ss/scsi.c 1992/0811 ## diff -e /n/bootesdump/1992/0808/sys/src/9/ss/scsi.c /n/bootesdump/1992/0811/sys/src/9/ss/scsi.c 108a print("scsi config #%2.2ux\n", dev->config); . 10c uchar scsiownid = 7; . ## diffname ss/scsi.c 1992/0812 ## diff -e /n/bootesdump/1992/0811/sys/src/9/ss/scsi.c /n/bootesdump/1992/0812/sys/src/9/ss/scsi.c 109d 92c dev->cmd = Dma|Nop; /* 2 are necessary */ dev->cmd = Dma|Nop; . ## diffname ss/scsi.c 1992/0813 ## diff -e /n/bootesdump/1992/0812/sys/src/9/ss/scsi.c /n/bootesdump/1992/0813/sys/src/9/ss/scsi.c 311c print(" fflags =0x%2.2ux\n", dev->fflags); . 306c print(" countmi=0x%2.2ux\n", dev->countmi); . 254c p->data.ptr = p->data.lim - ((dev->countmi<<8)|dev->countlo); . 169,182d 155a dev->countmi = n>>8; . 154d 145a dev->countmi = 0; . 144d 109a /* * try to determine chip type dev->conf2 = 0; dev->conf2 = 0x0A; delay(1); if((dev->conf2 & 0x0F) == 0x0A){ dev->conf3 = 0; dev->conf3 = 0x05; delay(1); if(dev->conf3 == 0x05) print("scsi type ESP236\n"); else print("scsi type ESP100A\n"); } else print("scsi type NCR53C90\n"); */ dev->cmd = Reset; dev->cmd = Dma|Nop; /* 2 are necessary for some chips */ dev->cmd = Dma|Nop; dev->clkconf = 4; /* BUG: 20MHz */ dev->timeout = 160; /* BUG: magic */ dev->syncperiod = 0; dev->syncoffset = 0; dev->config = Penable|(scsiownid&7); intr = dev->intr; USED(intr); . 91,102d 81a uchar intr; . 75a static void scsibusreset(void) { SCSIdev *dev = ioaddr.scsi; int s; uchar intr; s = splhi(); dev->config |= ResetIntDis; dev->cmd = Busreset; dev->config &= ~ResetIntDis; intr = dev->intr; USED(intr); splx(s); } . 54,56c Dma = 0x80, /* NCR 53C90 commands */ . 50,52c enum { ResetIntDis = 0x40, /* config regsiter */ Penable = 0x10, . ## diffname ss/scsi.c 1992/0820 ## diff -e /n/bootesdump/1992/0813/sys/src/9/ss/scsi.c /n/bootesdump/1992/0820/sys/src/9/ss/scsi.c 297d 51c ResetIntDis = 0x40, /* config register */ . ## diffname ss/scsi.c 1992/0908 ## diff -e /n/bootesdump/1992/0820/sys/src/9/ss/scsi.c /n/bootesdump/1992/0908/sys/src/9/ss/scsi.c 33,45c va = kmapregion(pa, i*BY2PG, PTEMAINMEM|PTENOCACHE); b->virt = (void*)va; b->phys = (void*)pa; . 27,28d 21c int i; . ## diffname ss/scsi.c 1992/0912 ## diff -e /n/bootesdump/1992/0908/sys/src/9/ss/scsi.c /n/bootesdump/1992/0912/sys/src/9/ss/scsi.c 19d ## diffname ss/scsi.c 1993/0501 # deleted ## diff -e /n/bootesdump/1992/0912/sys/src/9/ss/scsi.c /n/fornaxdump/1993/0501/sys/src/brazil/ss/scsi.c 1,326d