## diffname pc/scsi.c 1993/0915 ## diff -e /dev/null /n/fornaxdump/1993/0915/sys/src/brazil/pc/scsi.c 0a #include "u.h" #include "../port/lib.h" #include "mem.h" #include "dat.h" #include "fns.h" #include "io.h" #include "../port/error.h" /* * Known to devscsi.c. int scsidebugs[8]; int scsiownid = CtlrID; */ void initscsi(void) { } /* * Quick hack. Need to do a better job of dynamic initialisation * for machines with peculiar memory/cache restictions. * Also, what about 16Mb address limit on the Adaptec? */ static ulong bufdatasize; void scsibufreset(ulong datasize) { bufdatasize = datasize; } Scsibuf * scsibuf(void) { Scsibuf *b; b = smalloc(sizeof(*b)); b->virt = smalloc(bufdatasize); b->phys = (void *)(PADDR(b->virt)); return b; } void scsifree(Scsibuf *b) { free(b->virt); free(b); } /* * Hack for devvid */ Scsibuf * scsialloc(ulong n) { Scsibuf *b; b = smalloc(sizeof(*b)); b->virt = smalloc(n); b->phys = (void *)(PADDR(b->virt)); return b; } extern int (*aha1542reset(void))(Scsi*, int); extern int (*ultra14freset(void))(Scsi*, int); static int (*exec)(Scsi*, int); int scsiexec(Scsi *p, int rflag) { if(exec == 0) error(Enonexist); return (*exec)(p, rflag); } void resetscsi(void) { if(exec = aha1542reset()) return; exec = ultra14freset(); } . ## diffname pc/scsi.c 1994/0908 ## diff -e /n/fornaxdump/1993/0915/sys/src/brazil/pc/scsi.c /n/fornaxdump/1994/0908/sys/src/brazil/pc/scsi.c 84a int scsibio(Target *t, char lun, int dir, void *b, long n, long bsize, long bno) { uchar cmd[10]; int s, cdbsiz, nbytes; memset(cmd, 0, sizeof cmd); if(bno <= 0x1fffff && n < 256) { cmd[0] = 0x0A; if(dir == SCSIread) cmd[0] = 0x08; cmd[1] = (lun<<5) | bno >> 16; cmd[2] = bno >> 8; cmd[3] = bno; cmd[4] = n; cdbsiz = 6; } else { cmd[0] = 0x2A; if(dir == SCSIread) cmd[0] = 0x28; cmd[1] = (lun<<5); cmd[2] = bno >> 24; cmd[3] = bno >> 16; cmd[4] = bno >> 8; cmd[5] = bno; cmd[7] = n>>8; cmd[8] = n; cdbsiz = 10; } nbytes = n*bsize; s = scsiexec(t, dir, cmd, cdbsiz, b, &nbytes); if(s < 0) { scsireqsense(t, lun, 0); return -1; } return nbytes; } static char *key[] = { "no sense", "recovered error", "not ready", "medium error", "hardware error", "illegal request", "unit attention", "data protect", "blank check", "vendor specific", "copy aborted", "aborted command", "equal", "volume overflow", "miscompare", "reserved" }; int scsireqsense(Target *tp, char lun, int quiet) { char *s; int sr, try, nbytes; uchar cmd[6], *sense; sense = tp->scratch; for(try = 0; try < 5; try++) { memset(cmd, 0, sizeof(cmd)); cmd[0] = CMDreqsense; cmd[1] = lun<<5; cmd[4] = Nscratch; memset(sense, 0, sizeof(sense)); nbytes = Nscratch; sr = scsiexec(tp, SCSIread, cmd, sizeof(cmd), sense, &nbytes); if(sr != STok) return sr; /* * Unit attention. We can handle that. */ if((sense[2] & 0x0F) == 0x00 || (sense[2] & 0x0F) == 0x06) return STok; /* * Recovered error. Why bother telling me. */ if((sense[2] & 0x0F) == 0x01) return STok; /* * Unit is becoming ready */ if(sense[12] != 0x04 || sense[13] != 0x01) break; delay(5000); } if(quiet) return STcheck; s = key[sense[2]&0xf]; print("scsi%d: unit %d reqsense: '%s' code #%2.2ux #%2.2ux\n", tp->ctlrno, tp->target, s, sense[12], sense[13]); return STcheck; } . 81,83c int s, nbytes; uchar cmd[10], *d; memset(cmd, 0, sizeof(cmd)); cmd[0] = 0x25; cmd[1] = lun<<5; d = malloc(8); if(d == 0) return -1; nbytes = 8; s = scsiexec(t, SCSIread, cmd, sizeof(cmd), d, &nbytes); if(s < 0) { free(d); return s; } *size = (d[0]<<24)|(d[1]<<16)|(d[2]<<8)|(d[3]<<0); *bsize = (d[4]<<24)|(d[5]<<16)|(d[6]<<8)|(d[7]<<0); free(d); return 0; . 78,79c int scsicap(Target *t, char lun, ulong *size, ulong *bsize) . 73,75c uchar cmd[6]; memset(cmd, 0, sizeof cmd); cmd[0] = 0x1b; cmd[1] = lun<<5; cmd[4] = s ? 1 : 0; return scsiexec(t, SCSIread, cmd, sizeof(cmd), 0, 0); . 71c scsistart(Target *t, char lun, int s) . 69a for(;;){ ctlr = devno/NTarget; unit = devno%NTarget; if(ctlr >= MaxScsi || scsi[ctlr] == 0) return -1; t = &scsi[ctlr]->target[unit]; devno++; if(t->ok && (t->inq[0]&0x0F) == type){ *rt = t; *inq = t->inq; sprint(id, "scsi%d: unit %d", ctlr, unit); return devno; } } return -1; } . 68c inventory(); . 65,66c int scsiinv(int devno, int type, Target **rt, uchar **inq, char *id) { Target *t; int ctlr, unit; . 59,62c lock(&ilock); if(inited) { unlock(&ilock); return; } inited = 1; unlock(&ilock); for(i = 0; i < MaxScsi; i++){ if(scsi[i]) scsiprobe(scsi[i]); } . 57c int i; static Lock ilock; static int inited; . 51,55c static void inventory(void) . 47,48c Target *tp; uchar cmd[6]; int i, s, nbytes; for(i = 0; i < NTarget; i++) { tp = &ctlr->target[i]; /* * Test unit ready */ memset(cmd, 0, sizeof(cmd)); s = scsiexec(tp, SCSIread, cmd, sizeof(cmd), 0, 0); if(s < 0) continue; /* * Determine if the drive exists and is not ready or * is simply not responding */ if((s = scsireqsense(tp, 0, 0)) != STok){ print("scsi%d: unit %d unavailable, status %d\n", tp->ctlrno, i, s); continue; } /* * Inquire to find out what the device is * Drivers then use the result to attach to targets */ memset(tp->inq, 0, Ninq); cmd[0] = CMDinquire; cmd[4] = Ninq; nbytes = Ninq; s = scsiexec(tp, SCSIread, cmd, sizeof(cmd), tp->inq, &nbytes); if(s < 0) { print("scsi%d: unit %d inquire failed, status %d\n", tp->ctlrno, i, s); continue; } print("scsi%d: unit %d %s\n", tp->ctlrno, i, tp->inq+8); tp->ok = 1; } . 44,45c static void scsiprobe(Ctlr *ctlr) . 38,41c Target* scsiunit(int ctlr, int unit) { Target *t; if(ctlr < 0 || ctlr >= MaxScsi || scsi[ctlr] == 0) return 0; if(unit < 0 || unit >= NTarget) return 0; t = &scsi[ctlr]->target[unit]; if(t->ok == 0) return 0; return t; . 36c return (*scsi[tp->ctlrno]->io)(tp, rw, cmd, cbytes, data, dbytes); } . 33,34c int scsiexec(Target *tp, int rw, uchar *cmd, int cbytes, void *data, int *dbytes) . 30c Ctlr *ctlr; int ctlrno, n, t; for(ctlr = 0, ctlrno = 0; ctlrno < MaxScsi; ctlrno++){ if(ctlr == 0) ctlr = malloc(sizeof(Ctlr)); memset(ctlr, 0, sizeof(Ctlr)); if(isaconfig("scsi", ctlrno, ctlr) == 0) continue; for(n = 0; cards[n].type; n++){ if(strcmp(cards[n].type, ctlr->type)) continue; if((ctlr->io = (*cards[n].reset)(ctlrno, ctlr)) == 0) break; print("scsi%d: %s: port %lux irq %d addr %lux size %d\n", ctlrno, ctlr->type, ctlr->port, ctlr->irq, ctlr->mem, ctlr->size); for(t = 0; t < NTarget; t++){ ctlr->target[t].ctlrno = ctlrno; ctlr->target[t].target = t; ctlr->target[t].inq = xalloc(Ninq); ctlr->target[t].scratch = xalloc(Nscratch); } scsi[ctlrno] = ctlr; ctlr = 0; break; } } if(ctlr) free(ctlr); . 28c scsireset(void) . 20,26d 17a static int ncard; if(ncard == MaxScsi) panic("too many scsi cards\n"); cards[ncard].type = t; cards[ncard].reset = r; ncard++; . 16c addscsicard(char *t, Scsiio (*r)(int, ISAConf*)) . 14a CMDreqsense = 0x03, CMDinquire = 0x12, }; typedef struct { ISAConf; Scsiio io; Target target[NTarget]; } Ctlr; static Ctlr *scsi[MaxScsi]; static struct { char *type; Scsiio (*reset)(int, ISAConf*); } cards[MaxScsi+1]; . 9,13c enum { Ninq = 255, Nscratch = 255, . 7a #include "../port/netif.h" . 6a #include "ureg.h" . ## diffname pc/scsi.c 1995/0324 ## diff -e /n/fornaxdump/1994/0908/sys/src/brazil/pc/scsi.c /n/fornaxdump/1995/0324/sys/src/brazil/pc/scsi.c 340c t->ctlrno, t->target, s, sense[12], sense[13]); . 310c sr = scsiexec(t, SCSIread, cmd, sizeof(cmd), sense, &nbytes); . 300c sense = t->scratch; . 294c scsireqsense(Target *t, char lun, int quiet) . 144,145c print("scsi%d: unit %d %s\n", t->ctlrno, i, t->inq+8); t->ok = 1; . 141c print("scsi%d: unit %d inquire failed, status %d\n", t->ctlrno, i, s); . 139c s = scsiexec(t, SCSIread, cmd, sizeof(cmd), t->inq, &nbytes); . 135c memset(t->inq, 0, Ninq); . 126,127c if((s = scsireqsense(t, 0, 0)) != STok){ print("scsi%d: unit %d unavailable, status %d\n", t->ctlrno, i, s); . 118c s = scsiexec(t, SCSIread, cmd, sizeof(cmd), 0, 0); . 112c t = &ctlr->target[i]; . 107c Target *t; . 86c return (*scsi[t->ctlrno]->io)(t, rw, cmd, cbytes, data, dbytes); . 84c scsiexec(Target *t, int rw, uchar *cmd, int cbytes, void *data, int *dbytes) . ## diffname pc/scsi.c 1995/0328 ## diff -e /n/fornaxdump/1995/0324/sys/src/brazil/pc/scsi.c /n/fornaxdump/1995/0328/sys/src/brazil/pc/scsi.c 65a if(ctlr->mem) print(" addr %lux size %d\n", ctlr->mem, ctlr->size); print("\n"); . 63c print("scsi%d: %s: port %lux irq %d", . 60c if((ctlr->io = (*lp->reset)(ctlrno, ctlr)) == 0) . 57,58c for(lp = link; lp; lp = lp->link){ if(strcmp(lp->type, ctlr->type)) . 49c int ctlrno, t; Link *lp; . 38,42c if((lp = xalloc(sizeof(Link))) == 0) return; lp->type = t; lp->reset = r; lp->link = link; link = lp; linkcount++; . 36c Link *lp; . 34c addscsilink(char *t, Scsiio (*r)(int, ISAConf*)) . 32a Link* link; } Link; static Link *link; static int linkcount; . 31d 28c typedef struct Link Link; typedef struct Link { . ## diffname pc/scsi.c 1995/0329 ## diff -e /n/fornaxdump/1995/0328/sys/src/brazil/pc/scsi.c /n/fornaxdump/1995/0329/sys/src/brazil/pc/scsi.c 218a } int scsiinquiry(Target *t, char lun, void *data, int *datalen) { uchar cmd[6]; memset(cmd, 0, sizeof cmd); cmd[0] = CMDinquire; cmd[1] = lun<<5; cmd[4] = *datalen; return scsiexec(t, SCSIread, cmd, sizeof(cmd), data, datalen); . 215c cmd[0] = CMDstart; . 199c if(t->ok && (t->inq[0]&0x1F) == type){ . 152c s = scsiinquiry(t, 0, t->inq, &nbytes); . 149,150d 145c * Inquire to find out what the device is. . 16a CMDstart = 0x1B, CMDread10 = 0x28, CMDwrite10 = 0x2A, . 15a CMDread6 = 0x08, CMDwrite6 = 0x0A, . 14a CMDtest = 0x00, . ## diffname pc/scsi.c 1995/0403 ## diff -e /n/fornaxdump/1995/0329/sys/src/brazil/pc/scsi.c /n/fornaxdump/1995/0403/sys/src/brazil/pc/scsi.c 203,207c if(t->ok){ for(i = type; *i >= 0; i++){ if((t->inq[0]&0x1F) != *i) continue; *rt = t; *inq = t->inq; sprint(id, "scsi%d: unit %d", ctlr, unit); print("devno %d = %s\n", devno, id); return devno; } . 191c int ctlr, *i, unit; . 188c scsiinv(int devno, int *type, Target **rt, uchar **inq, char *id) . 161c print("scsi%d: unit %d:%2.2ux: %s\n", t->ctlrno, i, t->inq[0], t->inq+8); . ## diffname pc/scsi.c 1995/0404 ## diff -e /n/fornaxdump/1995/0403/sys/src/brazil/pc/scsi.c /n/fornaxdump/1995/0404/sys/src/brazil/pc/scsi.c 215a } int scsitest(Target *t, char lun) { uchar cmd[6]; memset(cmd, 0, sizeof(cmd)); cmd[0] = CMDtest; cmd[1] = lun<<5; return scsiexec(t, SCSIread, cmd, sizeof(cmd), 0, 0); . 133,138c if(scsitest(t, 0) < 0) . 127d ## diffname pc/scsi.c 1995/0405 ## diff -e /n/fornaxdump/1995/0404/sys/src/brazil/pc/scsi.c /n/fornaxdump/1995/0405/sys/src/brazil/pc/scsi.c 375,380c if(quiet == 0){ s = key[sense[2]&0x0F]; print("scsi%d: unit %d reqsense: '%s' code #%2.2ux #%2.2ux\n", t->ctlrno, t->target, s, sense[12], sense[13]); } free(sense); . 364a } . 363c if((sense[2] & 0x0F) == 0x01){ free(sense); . 358a } . 357c if((sense[2] & 0x0F) == 0x00 || (sense[2] & 0x0F) == 0x06){ free(sense); . 349,352c status = scsiexec(t, SCSIread, cmd, sizeof(cmd), sense, nbytes); if(status != STok){ free(sense); return status; } *nbytes = sense[0x07]+8; memmove(data, sense, *nbytes); . 346,347c cmd[4] = *nbytes; memset(sense, 0, *nbytes); . 340c sense = malloc(*nbytes); . 337c int status, try; . 334c scsireqsense(Target *t, char lun, void *data, int *nbytes, int quiet) . 307c nbytes = Nscratch; scsireqsense(t, lun, t->scratch, &nbytes, 0); . 271c return s; . 268,269d 263,266c if((s = scsiexec(t, SCSIread, cmd, sizeof(cmd), d, &nbytes)) == STok){ *size = (d[0]<<24)|(d[1]<<16)|(d[2]<<8)|(d[3]<<0); *bsize = (d[4]<<24)|(d[5]<<16)|(d[6]<<8)|(d[7]<<0); . 155c print("scsi%d: unit %d: %s\n", t->ctlrno, i, t->inq+8); . 139c nbytes = Nscratch; s = scsireqsense(t, 0, t->scratch, &nbytes, 0); if(s != STok){ . ## diffname pc/scsi.c 1995/0513 ## diff -e /n/fornaxdump/1995/0405/sys/src/brazil/pc/scsi.c /n/fornaxdump/1995/0513/sys/src/brazil/pc/scsi.c 206d 83c print(" addr 0x%luX", ctlr->mem & ~KZERO); if(ctlr->size) print(" size 0x%luX", ctlr->size); . 79c print("scsi%d: %s: port 0x%luX irq %d", . ## diffname pc/scsi.c 1995/0712 ## diff -e /n/fornaxdump/1995/0513/sys/src/brazil/pc/scsi.c /n/fornaxdump/1995/0712/sys/src/brazil/pc/scsi.c 9d ## diffname pc/scsi.c 1995/0722 ## diff -e /n/fornaxdump/1995/0712/sys/src/brazil/pc/scsi.c /n/fornaxdump/1995/0722/sys/src/brazil/pc/scsi.c 390a int scsidiskinfo(Target *t, char lun, uchar *data) { int s, nbytes, try; uchar cmd[10]; for(try=0; try<3; try++) { nbytes = 4; memset(cmd, 0, sizeof(cmd)); cmd[0] = 0x43; cmd[1] = lun<<5; cmd[7] = nbytes>>8; cmd[8] = nbytes>>0; s = scsiexec(t, SCSIread, cmd, sizeof(cmd), data, &nbytes); if(s == STok) break; nbytes = Nscratch; scsireqsense(t, lun, t->scratch, &nbytes, 0); } return s; } int scsitrackinfo(Target *t, char lun, int track, uchar *data) { int s, nbytes; uchar cmd[10]; nbytes = 12; memset(cmd, 0, sizeof(cmd)); cmd[0] = 0xe5; cmd[1] = lun<<5; cmd[5] = track; cmd[7] = nbytes>>8; cmd[8] = nbytes>>0; s = scsiexec(t, SCSIread, cmd, sizeof(cmd), data, &nbytes); return s; } . 234c cmd[4] = s? 1: 0; . 34c typedef struct Link { . 24c typedef struct { . 10c enum { . ## diffname pc/scsi.c 1995/0723 ## diff -e /n/fornaxdump/1995/0722/sys/src/brazil/pc/scsi.c /n/fornaxdump/1995/0723/sys/src/brazil/pc/scsi.c 436a } int scsibufsize(Target *t, char lun, int size) { int s, nbytes; uchar cmd[6], *d; nbytes = 12; memset(cmd, 0, sizeof(cmd)); cmd[0] = 0x15; cmd[1] = lun<<5; cmd[4] = nbytes; d = scsialloc(nbytes); if(d == 0) error(Enomem); memset(d, 0, nbytes); d[3] = 8; d[9] = size>>16; d[10] = size>>8; d[11] = size>>0; s = scsiexec(t, SCSIwrite, cmd, sizeof(cmd), d, &nbytes); scsifree(d); return s; } int scsireadcdda(Target *t, char lun, void *b, long n, long bsize, long bno) { uchar cmd[10]; int s, nbytes; memset(cmd, 0, sizeof(cmd)); cmd[0] = 0xd8; cmd[1] = (lun<<5); cmd[2] = bno >> 24; cmd[3] = bno >> 16; cmd[4] = bno >> 8; cmd[5] = bno; cmd[6] = n>>24; cmd[7] = n>>16; cmd[8] = n>>8; cmd[9] = n; nbytes = n*bsize; s = scsiexec(t, SCSIread, cmd, sizeof(cmd), b, &nbytes); if(s < 0) { nbytes = Nscratch; scsireqsense(t, lun, t->scratch, &nbytes, 0); return -1; } return nbytes; . 435c d = scsialloc(nbytes); if(d == 0) error(Enomem); memset(d, 0, nbytes); s = scsiexec(t, SCSIread, cmd, sizeof(cmd), d, &nbytes); memmove(data, d, 12); scsifree(d); . 424c uchar cmd[10], *d; . 410,416c memset(d, 0, nbytes); s = scsiexec(t, SCSIread, cmd, sizeof(cmd), d, &nbytes); memmove(data, d, 4); scsifree(d); . 404,408c d = scsialloc(nbytes); if(d == 0) error(Enomem); . 402c memset(cmd, 0, sizeof(cmd)); cmd[0] = 0x43; cmd[1] = lun<<5; cmd[7] = nbytes>>8; cmd[8] = nbytes>>0; . 400c nbytes = 4; . 397,398c int s, nbytes; uchar cmd[10], *d; . 272c scsifree(d); . 267,268c s = scsiexec(t, SCSIread, cmd, sizeof(cmd), d, &nbytes); if(s == STok) { . 265c error(Enomem); . 263c nbytes = 8; d = scsialloc(nbytes); . 33c static Ctlr* scsi[MaxScsi]; . ## diffname pc/scsi.c 1995/0724 ## diff -e /n/fornaxdump/1995/0723/sys/src/brazil/pc/scsi.c /n/fornaxdump/1995/0724/sys/src/brazil/pc/scsi.c 486,493c hnputl(cmd+2, bno); hnputl(cmd+6, n); . 467,469c hnputl(d+8, size); . 432,433c hnputs(cmd+7, nbytes); . 406,407c hnputs(cmd+7, nbytes); . 299,304c hnputl(cmd+2, bno); hnputs(cmd+7, n); . 289,290c hnputs(cmd+2, bno); . 270,271c *size = nhgetl(d+0); *bsize = nhgetl(d+4); . ## diffname pc/scsi.c 1995/0725 ## diff -e /n/fornaxdump/1995/0724/sys/src/brazil/pc/scsi.c /n/fornaxdump/1995/0725/sys/src/brazil/pc/scsi.c 209c if(id) sprint(id, "scsi%d: unit %d", ctlr, unit); . ## diffname pc/scsi.c 1995/0726 ## diff -e /n/fornaxdump/1995/0725/sys/src/brazil/pc/scsi.c /n/fornaxdump/1995/0726/sys/src/brazil/pc/scsi.c 469c scsireadcdda(Target *t, char lun, int dir, void *b, long n, long bsize, long bno) . ## diffname pc/scsi.c 1995/0808 ## diff -e /n/fornaxdump/1995/0726/sys/src/brazil/pc/scsi.c /n/fornaxdump/1995/0808/sys/src/brazil/pc/scsi.c 469c scsireadcdda(Target *t, char lun, int, void *b, long n, long bsize, long bno) . 410c memmove(data, d, 12); . 401a cmd[6] = track; . 397c nbytes = 12; . 392c scsidiskinfo(Target *t, char lun, int track, uchar *data) . 376c if((sense[2] & 0x0F) != 0x02 && (sense[12] != 0x04 || sense[13] != 0x01)) . 374c * Unit is becoming ready, rather than not ready . ## diffname pc/scsi.c 1996/0210 ## diff -e /n/fornaxdump/1995/0808/sys/src/brazil/pc/scsi.c /n/fornaxdump/1996/0210/sys/src/brazil/pc/scsi.c 382a buggery: . 380c default: /* * If unit is becoming ready, rather than not ready, * then wait a little then poke it again; should this * be here or in the caller? */ if((sense[12] == 0x04 && sense[13] == 0x01)){ while(waserror()) ; tsleep(&t->rendez, return0, 0, 500); poperror(); scsitest(t, lun); break; } goto buggery; } . 373,378c case 2: /* not ready */ if(sense[12] == 0x3A) /* medium not present */ goto buggery; /*FALLTHROUGH*/ . 371d 365,368c case 6: /* unit attention */ if(sense[12] != 0x29) /* power on, reset */ goto buggery; /*FALLTHROUGH*/ case 0: /* no sense */ case 1: /* recovered error */ . 357,363c switch(sense[2] & 0x0F){ . 342c for(try = 0; try < 20; try++) { . ## diffname pc/scsi.c 1996/0607 ## diff -e /n/fornaxdump/1996/0210/sys/src/brazil/pc/scsi.c /n/fornaxdump/1996/0607/sys/src/brazil/pc/scsi.c 499a } int scsierrstr(int errno) { char *p; switch(errno){ case STnomem: p = Enomem; break; case STtimeout: p = "bus timeout"; break; case STownid: p = "playing with myself"; break; case STharderr: p = Eio; break; case STok: p = Enoerror; break; case STcheck: p = "check condition"; break; case STcondmet: p = "condition met/good"; break; case STbusy: p = "busy"; break; case STintok: p = "intermediate/good"; break; case STintcondmet: p = "intermediate/condition met/good"; break; case STresconf: p = "reservation conflict"; break; case STterminated: p = "command terminated"; break; case STqfull: p = "queue full"; break; default: p = "unknown SCSI error"; break; } strncpy(up->error, p, NAMELEN); return -1; . 497c return scsierrstr(s); . 494c if(s != STok) { . 468c return scsierrstr(STnomem); . 442c return scsierrstr(STnomem); . 417c return scsierrstr(STnomem); . 394c print("scsi#%d: unit %d reqsense: '%s' code #%2.2ux #%2.2ux\n", . 308c return scsierrstr(s); . 305c if(s != STok) { . 267c return -1; . 161c print("scsi#%d: unit %d: %s\n", t->ctlrno, i, t->inq+8); . 157,158c if(s != STok) { print("scsi#%d: unit %d inquire failed, status %d\n", t->ctlrno, i, s); . 146c print("scsi#%d: unit %d unavailable, status %d\n", t->ctlrno, i, s); . 109c int s; /* * Call the device-specific I/O routine. * There should be no calls to 'error()' below this * which percolate back up. */ switch(s = (*scsi[t->ctlrno]->io)(t, rw, cmd, cbytes, data, dbytes)){ default: /* * It's more complicated than this. There are conditions which * are 'ok' but for which the returned status code is not 'STok'. * Also, not all conditions require a reqsense, there may be a * need to do a reqsense here when necessary and making it * available to the caller somehow. * * Later. */ break; } return s; . 81c print("scsi#%d: %s: port 0x%luX irq %d", . ## diffname pc/scsi.c 1996/0620 ## diff -e /n/fornaxdump/1996/0607/sys/src/brazil/pc/scsi.c /n/fornaxdump/1996/0620/sys/src/brazil/pc/scsi.c 289c return scsierrstr(STnomem); . ## diffname pc/scsi.c 1996/0622 ## diff -e /n/fornaxdump/1996/0620/sys/src/brazil/pc/scsi.c /n/fornaxdump/1996/0622/sys/src/brazil/pc/scsi.c 511,512c cmd[2] = bno>>24; cmd[3] = bno>>16; cmd[4] = bno>>8; cmd[5] = bno; cmd[6] = n>>8; cmd[7] = n; . 494c d[8] = size>>24; d[9] = size>>16; d[10] = size>>8; d[11] = size; . 460c cmd[7] = nbytes>>8; cmd[8] = nbytes; . 435c cmd[7] = nbytes>>8; cmd[8] = nbytes; . 321,322c cmd[2] = bno>>24; cmd[3] = bno>>16; cmd[4] = bno>>8; cmd[5] = bno; cmd[7] = n>>8; cmd[8] = n; cmd[9] = 0; . 313a cmd[5] = 0; . 312c cmd[2] = bno>>8; cmd[3] = bno; . 306d 293,294c *size = (d[0]<<24)|(d[1]<<16)|(d[2]<<8)|d[3]; *bsize = (d[4]<<24)|(d[5]<<16)|(d[6]<<8)|d[7]; . ## diffname pc/scsi.c 1996/1018 ## diff -e /n/fornaxdump/1996/0622/sys/src/brazil/pc/scsi.c /n/fornaxdump/1996/1018/sys/src/brazil/pc/scsi.c 376a *nbytes = n; . 374,375c cmd[4] = n; memset(sense, 0, n); . 368c n = *nbytes; sense = malloc(n); . 365c int n, status, try; . ## diffname pc/scsi.c 1996/1022 ## diff -e /n/fornaxdump/1996/1018/sys/src/brazil/pc/scsi.c /n/fornaxdump/1996/1022/sys/src/brazil/pc/scsi.c 425a print("scsi#%d: byte 2: #%2.2uX, bytes 15-17: #%2.2uX #%2.2uX #%2.2uX\n", t->ctlrno, sense[2], sense[15], sense[16], sense[17]); print("lastcmd (%d): ", lastcmdsz); for(n = 0; n < lastcmdsz; n++) print(" #%2.2uX", lastcmd[n]); print("\n"); . 325a cmd[6] = 0; . 117a case STcheck: memmove(lastcmd, cmd, cbytes); lastcmdsz = cbytes; /*FALLTHROUGH*/ . 105a static uchar lastcmd[16]; static int lastcmdsz; . ## diffname pc/scsi.c 1996/1224 ## diff -e /n/fornaxdump/1996/1022/sys/src/brazil/pc/scsi.c /n/fornaxdump/1996/1224/sys/src/brazil/pc/scsi.c 543,544c cmd[8] = n>>8; cmd[9] = n; . ## diffname pc/scsi.c 1997/0327 ## diff -e /n/fornaxdump/1996/1224/sys/src/brazil/pc/scsi.c /n/emeliedump/1997/0327/sys/src/brazil/pc/scsi.c 543,544c cmd[6] = n>>8; cmd[7] = n; . 248d 119c switch(s = scsi[t->ctlrno]->io(t, rw, cmd, cbytes, data, dbytes)){ . 78c if((ctlr->io = lp->reset(ctlrno, ctlr)) == 0) . ## diffname pc/scsi.c 1997/0628 ## diff -e /n/emeliedump/1997/0327/sys/src/brazil/pc/scsi.c /n/emeliedump/1997/0628/sys/src/brazil/pc/scsi.c 542,543c cmd[6] = n>>24; cmd[7] = n>>16; cmd[8] = n>>8; cmd[9] = n; . ## diffname pc/scsi.c 1997/0629 ## diff -e /n/emeliedump/1997/0628/sys/src/brazil/pc/scsi.c /n/emeliedump/1997/0629/sys/src/brazil/pc/scsi.c 323,324c } else { . ## diffname pc/scsi.c 1997/0808 ## diff -e /n/emeliedump/1997/0629/sys/src/brazil/pc/scsi.c /n/emeliedump/1997/0808/sys/src/brazil/pc/scsi.c 323c } else { . ## diffname pc/scsi.c 1997/1101 ## diff -e /n/emeliedump/1997/0808/sys/src/brazil/pc/scsi.c /n/emeliedump/1997/1101/sys/src/brazil/pc/scsi.c 85c print(" addr 0x%luX", PADDR(ctlr->mem)); . ## diffname pc/scsi.c 1998/0201 ## diff -e /n/emeliedump/1997/1101/sys/src/brazil/pc/scsi.c /n/emeliedump/1998/0201/sys/src/brazil/pc/scsi.c 531c uchar cmd[12]; . 504d 313,338c cmd[0] = CMDwrite10; if(dir == SCSIread) cmd[0] = CMDread10; cmd[1] = (lun<<5); cmd[2] = bno>>24; cmd[3] = bno>>16; cmd[4] = bno>>8; cmd[5] = bno; cmd[6] = 0; cmd[7] = n>>8; cmd[8] = n; cmd[9] = 0; cdbsiz = 10; . ## diffname pc/scsi.c 1998/0811 ## diff -e /n/emeliedump/1998/0201/sys/src/brazil/pc/scsi.c /n/emeliedump/1998/0811/sys/src/brazil/pc/scsi.c 191c print("scsi#%d: unit %d: %s\n", t->ctlrno, i, (char*)(t->inq+8)); . 83c ctlr->irq); . ## diffname pc/scsi.c 1998/0825 ## diff -e /n/emeliedump/1998/0811/sys/src/brazil/pc/scsi.c /n/emeliedump/1998/0825/sys/src/brazil/pc/scsi.c 81c print("scsi#%d: %s: port 0x%luX irq %lud", . ## diffname pc/scsi.c 1998/0910 ## diff -e /n/emeliedump/1998/0825/sys/src/brazil/pc/scsi.c /n/emeliedump/1998/0910/sys/src/brazil/pc/scsi.c 78c if((ctlr->io = scsidev[i]->reset(ctlrno, ctlr)) == 0) . 75,76c for(i = 0; scsidev[i]; i++){ if(strcmp(ctlr->type, scsidev[i]->type)) . 66,67c int ctlrno, i, t; . 48,62d 41,46d 35,39c extern SCSIdev* scsidev[]; . 33c static Ctlr* scsi[MaxScsi]; . 25,26c typedef struct { . 10,11c enum { . ## diffname pc/scsi.c 1998/0916 ## diff -e /n/emeliedump/1998/0910/sys/src/brazil/pc/scsi.c /n/emeliedump/1998/0916/sys/src/brazil/pc/scsi.c 48c if(cistrcmp(ctlr->type, scsidev[i]->type)) . ## diffname pc/scsi.c 1999/0119 ## diff -e /n/emeliedump/1998/0916/sys/src/brazil/pc/scsi.c /n/emeliedump/1999/0119/sys/src/brazil/pc/scsi.c 366,367c case 2: /* not ready */ if(sense[12] == 0x3A) /* medium not present */ . 361,362c case 0: /* no sense */ case 1: /* recovered error */ . 357,358c case 6: /* unit attention */ if(sense[12] != 0x29) /* power on, reset */ . 262c cmd[0] = CMDcapacity; . 212c sprint(id, "scsi%d: unit %d", ctlr, unit); . 163c print("scsi#%d: unit %d: %s\n", t->ctlrno, i, (char*)(t->inq+8)); . 160c print("scsi#%d: unit %d inquire failed, status %d\n", t->ctlrno, i, s); . 148c print("scsi#%d: unit %d unavailable, status %d\n", t->ctlrno, i, s); . 100,104c * It's more complicated than this. There are conditions * which are 'ok' but for which the returned status code * is not 'STok'. * Also, not all conditions require a reqsense, might * need to do a reqsense here and make it available to the * caller somehow. . 19a CMDcapacity = 0x25, . ## diffname pc/scsi.c 1999/0301 ## diff -e /n/emeliedump/1999/0119/sys/src/brazil/pc/scsi.c /n/emeliedump/1999/0301/sys/src/brazil/pc/scsi.c 411,520d 364c /* * 0x28 - not ready to ready transition, * medium may have changed. * 0x29 - power on, RESET or BUS DEVICE RESET occurred. */ if(sense[12] != 0x28 && sense[12] != 0x29) . 16,17d ## diffname pc/scsi.c 1999/0507 ## diff -e /n/emeliedump/1999/0301/sys/src/brazil/pc/scsi.c /n/emeliedump/1999/0507/sys/src/brazil/pc/scsi.c 334c scsireqsense(Target *t, int lun, void *data, int *nbytes, int quiet) . 284c scsibio(Target *t, int lun, int dir, void *b, long n, long bsize, long bno) . 260c scsicap(Target *t, int lun, ulong *size, ulong *bsize) . 248c scsiinquiry(Target *t, int lun, void *data, int *datalen) . 236c scsistart(Target *t, int lun, int s) . 225c scsitest(Target *t, int lun) . ## diffname pc/scsi.c 2000/0506 # deleted ## diff -e /n/emeliedump/1999/0507/sys/src/brazil/pc/scsi.c /n/emeliedump/2000/0506/sys/src/9/pc/scsi.c 1,468d