| plan 9 kernel history: overview | file list | diff list |
1995/0329/pc/scsi.c (diff list | history)
| 1993/0915/sys/src/9/pc/scsi.c:4,84 – 1994/0908/sys/src/9/pc/scsi.c:4,343 (short | long) | ||
| 1993/0915 | #include "dat.h" #include "fns.h" #include "io.h" | |
| 1994/0908 | #include "ureg.h" | |
| 1993/0915 | #include "../port/error.h" | |
| 1994/0908 | #include "../port/netif.h" | |
| 1993/0915 |
| |
| 1994/0908 | enum { Ninq = 255, Nscratch = 255, | |
| 1993/0915 | ||
| 1994/0908 | 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]; | |
| 1993/0915 | void | |
| 1994/0908 | addscsicard(char *t, Scsiio (*r)(int, ISAConf*)) | |
| 1993/0915 | { | |
| 1994/0908 | static int ncard; if(ncard == MaxScsi) panic("too many scsi cards\n"); cards[ncard].type = t; cards[ncard].reset = r; ncard++; | |
| 1993/0915 | } | |
| 1994/0908 | scsireset(void) | |
| 1993/0915 | { | |
| 1994/0908 | 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); | |
| 1993/0915 | } | |
| 1994/0908 | int scsiexec(Target *tp, int rw, uchar *cmd, int cbytes, void *data, int *dbytes) | |
| 1993/0915 | { | |
| 1994/0908 | return (*scsi[tp->ctlrno]->io)(tp, rw, cmd, cbytes, data, dbytes); } | |
| 1993/0915 |
| |
| 1994/0908 | 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; | |
| 1993/0915 | } | |
| 1994/0908 | static void scsiprobe(Ctlr *ctlr) | |
| 1993/0915 | { | |
| 1994/0908 | 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; } | |
| 1993/0915 | } | |
| 1994/0908 | static void inventory(void) | |
| 1993/0915 | { | |
| 1994/0908 | int i; static Lock ilock; static int inited; | |
| 1993/0915 |
| |
| 1994/0908 | lock(&ilock); if(inited) { unlock(&ilock); return; } inited = 1; unlock(&ilock); for(i = 0; i < MaxScsi; i++){ if(scsi[i]) scsiprobe(scsi[i]); } | |
| 1993/0915 | } | |
| 1994/0908 | int scsiinv(int devno, int type, Target **rt, uchar **inq, char *id) { Target *t; int ctlr, unit; | |
| 1993/0915 |
| |
| 1994/0908 | inventory(); | |
| 1993/0915 | ||
| 1994/0908 | 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; } | |
| 1993/0915 | int | |
| 1994/0908 | scsistart(Target *t, char lun, int s) | |
| 1993/0915 | { | |
| 1994/0908 | 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); | |
| 1993/0915 | } | |
| 1994/0908 | int scsicap(Target *t, char lun, ulong *size, ulong *bsize) | |
| 1993/0915 | { | |
| 1994/0908 | 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; | |
| 1993/0915 | } | |
| 1994/0908 | 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; } | |
| 1994/0908/sys/src/9/pc/scsi.c:81,89 – 1995/0324/sys/src/9/pc/scsi.c:81,89 (short | long) | ||
| 1993/0915 | } | |
| 1994/0908 | int | |
| 1995/0324 | scsiexec(Target *t, int rw, uchar *cmd, int cbytes, void *data, int *dbytes) | |
| 1993/0915 | { | |
| 1994/0908 |
| |
| 1995/0324 | return (*scsi[t->ctlrno]->io)(t, rw, cmd, cbytes, data, dbytes); | |
| 1994/0908 | } | |
| 1993/0915 | ||
| 1994/0908 | Target* | |
| 1994/0908/sys/src/9/pc/scsi.c:104,121 – 1995/0324/sys/src/9/pc/scsi.c:104,121 | ||
| 1994/0908 | static void scsiprobe(Ctlr *ctlr) | |
| 1993/0915 | { | |
| 1994/0908 |
| |
| 1995/0324 | Target *t; | |
| 1994/0908 | uchar cmd[6]; int i, s, nbytes; for(i = 0; i < NTarget; i++) { | |
| 1995/0324 | t = &ctlr->target[i]; | |
| 1994/0908 | /* * Test unit ready */ memset(cmd, 0, sizeof(cmd)); | |
| 1995/0324 | s = scsiexec(t, SCSIread, cmd, sizeof(cmd), 0, 0); | |
| 1994/0908 | if(s < 0) continue; | |
| 1994/0908/sys/src/9/pc/scsi.c:123,130 – 1995/0324/sys/src/9/pc/scsi.c:123,130 | ||
| 1994/0908 | * Determine if the drive exists and is not ready or * is simply not responding */ | |
| 1995/0324 | if((s = scsireqsense(t, 0, 0)) != STok){ print("scsi%d: unit %d unavailable, status %d\n", t->ctlrno, i, s); | |
| 1994/0908 | continue; } | |
| 1994/0908/sys/src/9/pc/scsi.c:132,148 – 1995/0324/sys/src/9/pc/scsi.c:132,148 | ||
| 1994/0908 | * Inquire to find out what the device is * Drivers then use the result to attach to targets */ | |
| 1995/0324 | memset(t->inq, 0, Ninq); | |
| 1994/0908 | cmd[0] = CMDinquire; cmd[4] = Ninq; nbytes = Ninq; | |
| 1995/0324 | s = scsiexec(t, SCSIread, cmd, sizeof(cmd), t->inq, &nbytes); | |
| 1994/0908 | if(s < 0) { | |
| 1995/0324 | print("scsi%d: unit %d inquire failed, status %d\n", t->ctlrno, i, s); | |
| 1994/0908 | continue; } | |
| 1995/0324 | print("scsi%d: unit %d %s\n", t->ctlrno, i, t->inq+8); t->ok = 1; | |
| 1994/0908 | } | |
| 1993/0915 | } | |
| 1994/0908/sys/src/9/pc/scsi.c:291,303 – 1995/0324/sys/src/9/pc/scsi.c:291,303 | ||
| 1994/0908 | }; int | |
| 1995/0324 | scsireqsense(Target *t, char lun, int quiet) | |
| 1994/0908 | { char *s; int sr, try, nbytes; uchar cmd[6], *sense; | |
| 1995/0324 | sense = t->scratch; | |
| 1994/0908 | for(try = 0; try < 5; try++) { memset(cmd, 0, sizeof(cmd)); | |
| 1994/0908/sys/src/9/pc/scsi.c:307,313 – 1995/0324/sys/src/9/pc/scsi.c:307,313 | ||
| 1994/0908 | memset(sense, 0, sizeof(sense)); nbytes = Nscratch; | |
| 1995/0324 | sr = scsiexec(t, SCSIread, cmd, sizeof(cmd), sense, &nbytes); | |
| 1994/0908 | if(sr != STok) return sr; | |
| 1994/0908/sys/src/9/pc/scsi.c:337,343 – 1995/0324/sys/src/9/pc/scsi.c:337,343 | ||
| 1994/0908 | s = key[sense[2]&0xf]; print("scsi%d: unit %d reqsense: '%s' code #%2.2ux #%2.2ux\n", | |
| 1995/0324 | t->ctlrno, t->target, s, sense[12], sense[13]); | |
| 1994/0908 | return STcheck; } | |
| 1995/0324/sys/src/9/pc/scsi.c:25,45 – 1995/0328/sys/src/9/pc/scsi.c:25,54 (short | long) | ||
| 1994/0908 | static Ctlr *scsi[MaxScsi]; | |
| 1995/0328 | typedef struct Link Link; typedef struct Link { | |
| 1994/0908 | char *type; Scsiio (*reset)(int, ISAConf*); | |
| 1995/0328 | Link* link; } Link; static Link *link; static int linkcount; | |
| 1993/0915 | void | |
| 1994/0908 |
| |
| 1995/0328 | addscsilink(char *t, Scsiio (*r)(int, ISAConf*)) | |
| 1993/0915 | { | |
| 1994/0908 |
| |
| 1995/0328 | Link *lp; | |
| 1994/0908 |
| |
| 1995/0328 | if((lp = xalloc(sizeof(Link))) == 0) return; lp->type = t; lp->reset = r; lp->link = link; link = lp; linkcount++; | |
| 1993/0915 | } void | |
| 1995/0324/sys/src/9/pc/scsi.c:46,52 – 1995/0328/sys/src/9/pc/scsi.c:55,62 | ||
| 1994/0908 | scsireset(void) | |
| 1993/0915 | { | |
| 1994/0908 | Ctlr *ctlr; | |
| 1995/0328 | int ctlrno, t; Link *lp; | |
| 1994/0908 | for(ctlr = 0, ctlrno = 0; ctlrno < MaxScsi; ctlrno++){ if(ctlr == 0) | |
| 1995/0324/sys/src/9/pc/scsi.c:54,68 – 1995/0328/sys/src/9/pc/scsi.c:64,81 | ||
| 1994/0908 | memset(ctlr, 0, sizeof(Ctlr)); if(isaconfig("scsi", ctlrno, ctlr) == 0) continue; | |
| 1995/0328 | for(lp = link; lp; lp = lp->link){ if(strcmp(lp->type, ctlr->type)) | |
| 1994/0908 | continue; | |
| 1995/0328 | if((ctlr->io = (*lp->reset)(ctlrno, ctlr)) == 0) | |
| 1994/0908 | break; | |
| 1995/0328 | print("scsi%d: %s: port %lux irq %d", | |
| 1994/0908 | ctlrno, ctlr->type, ctlr->port, ctlr->irq, ctlr->mem, ctlr->size); | |
| 1995/0328 | if(ctlr->mem) print(" addr %lux size %d\n", ctlr->mem, ctlr->size); print("\n"); | |
| 1994/0908 | for(t = 0; t < NTarget; t++){ ctlr->target[t].ctlrno = ctlrno; | |
| 1995/0328/sys/src/9/pc/scsi.c:12,19 – 1995/0329/sys/src/9/pc/scsi.c:12,25 (short | long) | ||
| 1994/0908 | Ninq = 255, Nscratch = 255, | |
| 1993/0915 | ||
| 1995/0329 | CMDtest = 0x00, | |
| 1994/0908 | CMDreqsense = 0x03, | |
| 1995/0329 | CMDread6 = 0x08, CMDwrite6 = 0x0A, | |
| 1994/0908 | CMDinquire = 0x12, | |
| 1995/0329 | CMDstart = 0x1B, CMDread10 = 0x28, CMDwrite10 = 0x2A, | |
| 1994/0908 | }; typedef struct { | |
| 1995/0328/sys/src/9/pc/scsi.c:142,155 – 1995/0329/sys/src/9/pc/scsi.c:148,159 | ||
| 1994/0908 | } /* | |
| 1995/0329 | * Inquire to find out what the device is. | |
| 1994/0908 | * Drivers then use the result to attach to targets */ | |
| 1995/0324 | memset(t->inq, 0, Ninq); | |
| 1994/0908 |
| |
| 1995/0324 |
| |
| 1995/0329 | s = scsiinquiry(t, 0, t->inq, &nbytes); | |
| 1994/0908 | if(s < 0) { | |
| 1995/0324 | print("scsi%d: unit %d inquire failed, status %d\n", t->ctlrno, i, s); | |
| 1994/0908 | continue; | |
| 1995/0328/sys/src/9/pc/scsi.c:196,202 – 1995/0329/sys/src/9/pc/scsi.c:200,206 | ||
| 1994/0908 | t = &scsi[ctlr]->target[unit]; devno++; | |
| 1995/0329 | if(t->ok && (t->inq[0]&0x1F) == type){ | |
| 1994/0908 | *rt = t; *inq = t->inq; sprint(id, "scsi%d: unit %d", ctlr, unit); | |
| 1995/0328/sys/src/9/pc/scsi.c:212,221 – 1995/0329/sys/src/9/pc/scsi.c:216,237 | ||
| 1994/0908 | uchar cmd[6]; memset(cmd, 0, sizeof cmd); | |
| 1995/0329 | cmd[0] = CMDstart; | |
| 1994/0908 | cmd[1] = lun<<5; cmd[4] = s ? 1 : 0; return scsiexec(t, SCSIread, cmd, sizeof(cmd), 0, 0); | |
| 1995/0329 | } 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); | |
| 1993/0915 | } | |
| 1994/0908 | int | |
| 1995/0329/sys/src/9/pc/scsi.c:158,164 – 1995/0403/sys/src/9/pc/scsi.c:158,164 (short | long) | ||
| 1995/0324 | print("scsi%d: unit %d inquire failed, status %d\n", t->ctlrno, i, s); | |
| 1994/0908 | continue; } | |
| 1995/0324 |
| |
| 1995/0403 | print("scsi%d: unit %d:%2.2ux: %s\n", t->ctlrno, i, t->inq[0], t->inq+8); | |
| 1995/0324 | t->ok = 1; | |
| 1994/0908 | } | |
| 1993/0915 | } | |
| 1995/0329/sys/src/9/pc/scsi.c:185,194 – 1995/0403/sys/src/9/pc/scsi.c:185,194 | ||
| 1993/0915 | } | |
| 1994/0908 | int | |
| 1995/0403 | scsiinv(int devno, int *type, Target **rt, uchar **inq, char *id) | |
| 1994/0908 | { Target *t; | |
| 1995/0403 | int ctlr, *i, unit; | |
| 1993/0915 | ||
| 1994/0908 | inventory(); | |
| 1993/0915 | ||
| 1995/0329/sys/src/9/pc/scsi.c:200,210 – 1995/0403/sys/src/9/pc/scsi.c:200,215 | ||
| 1994/0908 | t = &scsi[ctlr]->target[unit]; devno++; | |
| 1995/0329 |
| |
| 1994/0908 |
| |
| 1995/0403 | 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; } | |
| 1994/0908 | } } return -1; | |
| 1995/0403/sys/src/9/pc/scsi.c:124,141 – 1995/0404/sys/src/9/pc/scsi.c:124,135 (short | long) | ||
| 1994/0908 | scsiprobe(Ctlr *ctlr) | |
| 1993/0915 | { | |
| 1995/0324 | Target *t; | |
| 1994/0908 |
| |
| 1995/0324 | t = &ctlr->target[i]; | |
| 1994/0908 |
| |
| 1995/0324 |
| |
| 1994/0908 |
| |
| 1995/0404 | if(scsitest(t, 0) < 0) | |
| 1994/0908 | continue; /* | |
| 1995/0403/sys/src/9/pc/scsi.c:213,218 – 1995/0404/sys/src/9/pc/scsi.c:207,224 | ||
| 1994/0908 | } } return -1; | |
| 1995/0404 | } 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); | |
| 1994/0908 | } | |
| 1993/0915 | int | |
| 1995/0404/sys/src/9/pc/scsi.c:136,142 – 1995/0405/sys/src/9/pc/scsi.c:136,144 (short | long) | ||
| 1994/0908 | * Determine if the drive exists and is not ready or * is simply not responding */ | |
| 1995/0324 |
| |
| 1995/0405 | nbytes = Nscratch; s = scsireqsense(t, 0, t->scratch, &nbytes, 0); if(s != STok){ | |
| 1995/0324 | print("scsi%d: unit %d unavailable, status %d\n", t->ctlrno, i, s); | |
| 1994/0908 | continue; } | |
| 1995/0404/sys/src/9/pc/scsi.c:152,158 – 1995/0405/sys/src/9/pc/scsi.c:154,160 | ||
| 1995/0324 | print("scsi%d: unit %d inquire failed, status %d\n", t->ctlrno, i, s); | |
| 1994/0908 | continue; } | |
| 1995/0403 |
| |
| 1995/0405 | print("scsi%d: unit %d: %s\n", t->ctlrno, i, t->inq+8); | |
| 1995/0324 | t->ok = 1; | |
| 1994/0908 | } | |
| 1993/0915 | } | |
| 1995/0404/sys/src/9/pc/scsi.c:260,274 – 1995/0405/sys/src/9/pc/scsi.c:262,273 | ||
| 1994/0908 | return -1; nbytes = 8; | |
| 1995/0405 | 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); | |
| 1994/0908 | } | |
| 1995/0405 | return s; | |
| 1993/0915 | } | |
| 1994/0908 | int | |
| 1995/0404/sys/src/9/pc/scsi.c:304,310 – 1995/0405/sys/src/9/pc/scsi.c:303,310 | ||
| 1994/0908 | nbytes = n*bsize; s = scsiexec(t, dir, cmd, cdbsiz, b, &nbytes); if(s < 0) { | |
| 1995/0405 | nbytes = Nscratch; scsireqsense(t, lun, t->scratch, &nbytes, 0); | |
| 1994/0908 | return -1; } return nbytes; | |
| 1995/0404/sys/src/9/pc/scsi.c:331,367 – 1995/0405/sys/src/9/pc/scsi.c:331,374 | ||
| 1994/0908 | }; int | |
| 1995/0324 |
| |
| 1995/0405 | scsireqsense(Target *t, char lun, void *data, int *nbytes, int quiet) | |
| 1994/0908 | { char *s; | |
| 1995/0405 | int status, try; | |
| 1994/0908 | uchar cmd[6], *sense; | |
| 1995/0324 |
| |
| 1995/0405 | sense = malloc(*nbytes); | |
| 1994/0908 | for(try = 0; try < 5; try++) { memset(cmd, 0, sizeof(cmd)); cmd[0] = CMDreqsense; cmd[1] = lun<<5; | |
| 1995/0405 | cmd[4] = *nbytes; memset(sense, 0, *nbytes); | |
| 1994/0908 |
| |
| 1995/0324 |
| |
| 1994/0908 |
| |
| 1995/0405 | status = scsiexec(t, SCSIread, cmd, sizeof(cmd), sense, nbytes); if(status != STok){ free(sense); return status; } *nbytes = sense[0x07]+8; memmove(data, sense, *nbytes); | |
| 1994/0908 | /* * Unit attention. We can handle that. */ | |
| 1995/0405 | if((sense[2] & 0x0F) == 0x00 || (sense[2] & 0x0F) == 0x06){ free(sense); | |
| 1994/0908 | return STok; | |
| 1995/0405 | } | |
| 1994/0908 | /* * Recovered error. Why bother telling me. */ | |
| 1995/0405 | if((sense[2] & 0x0F) == 0x01){ free(sense); | |
| 1994/0908 | return STok; | |
| 1995/0405 | } | |
| 1994/0908 | /* * Unit is becoming ready | |
| 1995/0404/sys/src/9/pc/scsi.c:372,383 – 1995/0405/sys/src/9/pc/scsi.c:379,390 | ||
| 1994/0908 | delay(5000); } | |
| 1995/0324 |
| |
| 1995/0405 | 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); | |
| 1994/0908 | return STcheck; } | |
| 1995/0405/sys/src/9/pc/scsi.c:76,86 – 1995/0513/sys/src/9/pc/scsi.c:76,88 (short | long) | ||
| 1995/0328 | if((ctlr->io = (*lp->reset)(ctlrno, ctlr)) == 0) | |
| 1994/0908 | break; | |
| 1995/0328 |
| |
| 1995/0513 | print("scsi%d: %s: port 0x%luX irq %d", | |
| 1994/0908 | ctlrno, ctlr->type, ctlr->port, ctlr->irq, ctlr->mem, ctlr->size); | |
| 1995/0328 | if(ctlr->mem) | |
| 1995/0513 | print(" addr 0x%luX", ctlr->mem & ~KZERO); if(ctlr->size) print(" size 0x%luX", ctlr->size); | |
| 1995/0328 | print("\n"); | |
| 1994/0908 | for(t = 0; t < NTarget; t++){ | |
| 1995/0405/sys/src/9/pc/scsi.c:203,209 – 1995/0513/sys/src/9/pc/scsi.c:205,210 | ||
| 1995/0403 | *rt = t; *inq = t->inq; sprint(id, "scsi%d: unit %d", ctlr, unit); | |
| 1994/0908 | } | |
| 1995/0513/sys/src/9/pc/scsi.c:6,12 – 1995/0712/sys/src/9/pc/scsi.c:6,11 (short | long) | ||
| 1993/0915 | #include "io.h" | |
| 1994/0908 | #include "ureg.h" | |
| 1993/0915 | #include "../port/error.h" | |
| 1994/0908 |
| |
| 1993/0915 | ||
| 1994/0908 | enum { Ninq = 255, | |
| 1995/0712/sys/src/9/pc/scsi.c:7,13 – 1995/0722/sys/src/9/pc/scsi.c:7,14 (short | long) | ||
| 1994/0908 | #include "ureg.h" | |
| 1993/0915 | #include "../port/error.h" | |
| 1994/0908 |
| |
| 1995/0722 | enum { | |
| 1994/0908 | Ninq = 255, Nscratch = 255, | |
| 1993/0915 | ||
| 1995/0712/sys/src/9/pc/scsi.c:21,27 – 1995/0722/sys/src/9/pc/scsi.c:22,29 | ||
| 1995/0329 | CMDwrite10 = 0x2A, | |
| 1994/0908 | }; | |
| 1995/0722 | typedef struct { | |
| 1994/0908 | ISAConf; Scsiio io; | |
| 1995/0712/sys/src/9/pc/scsi.c:31,37 – 1995/0722/sys/src/9/pc/scsi.c:33,40 | ||
| 1994/0908 | static Ctlr *scsi[MaxScsi]; | |
| 1995/0328 | typedef struct Link Link; | |
| 1995/0722 | typedef struct Link { | |
| 1994/0908 | char *type; Scsiio (*reset)(int, ISAConf*); | |
| 1995/0712/sys/src/9/pc/scsi.c:231,237 – 1995/0722/sys/src/9/pc/scsi.c:234,240 | ||
| 1994/0908 | memset(cmd, 0, sizeof cmd); | |
| 1995/0329 | cmd[0] = CMDstart; | |
| 1994/0908 | cmd[1] = lun<<5; | |
| 1995/0722 | cmd[4] = s? 1: 0; | |
| 1994/0908 | return scsiexec(t, SCSIread, cmd, sizeof(cmd), 0, 0); | |
| 1995/0329 | } | |
| 1995/0712/sys/src/9/pc/scsi.c:388,390 – 1995/0722/sys/src/9/pc/scsi.c:391,437 | ||
| 1994/0908 | return STcheck; } | |
| 1995/0722 | 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; } | |
| 1995/0722/sys/src/9/pc/scsi.c:30,36 – 1995/0723/sys/src/9/pc/scsi.c:30,36 (short | long) | ||
| 1994/0908 | Target target[NTarget]; } Ctlr; | |
| 1995/0723 | static Ctlr* scsi[MaxScsi]; | |
| 1994/0908 | ||
| 1995/0328 | typedef struct Link Link; | |
| 1995/0722 | typedef struct Link | |
| 1995/0722/sys/src/9/pc/scsi.c:260,275 – 1995/0723/sys/src/9/pc/scsi.c:260,276 | ||
| 1994/0908 | cmd[0] = 0x25; cmd[1] = lun<<5; | |
| 1995/0723 | nbytes = 8; d = scsialloc(nbytes); | |
| 1994/0908 | if(d == 0) | |
| 1995/0723 | error(Enomem); | |
| 1994/0908 |
| |
| 1995/0405 |
| |
| 1995/0723 | s = scsiexec(t, SCSIread, cmd, sizeof(cmd), d, &nbytes); if(s == STok) { | |
| 1995/0405 | *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); | |
| 1994/0908 | } | |
| 1995/0723 | scsifree(d); | |
| 1995/0405 | return s; | |
| 1993/0915 | } | |
| 1994/0908 | ||
| 1995/0722/sys/src/9/pc/scsi.c:394,419 – 1995/0723/sys/src/9/pc/scsi.c:395,419 | ||
| 1995/0722 | int scsidiskinfo(Target *t, char lun, uchar *data) { | |
| 1995/0723 | int s, nbytes; uchar cmd[10], *d; | |
| 1995/0722 |
| |
| 1995/0723 | nbytes = 4; | |
| 1995/0722 |
| |
| 1995/0723 | memset(cmd, 0, sizeof(cmd)); cmd[0] = 0x43; cmd[1] = lun<<5; cmd[7] = nbytes>>8; cmd[8] = nbytes>>0; | |
| 1995/0722 |
| |
| 1995/0723 | d = scsialloc(nbytes); if(d == 0) error(Enomem); | |
| 1995/0722 |
| |
| 1995/0723 | memset(d, 0, nbytes); s = scsiexec(t, SCSIread, cmd, sizeof(cmd), d, &nbytes); memmove(data, d, 4); scsifree(d); | |
| 1995/0722 | return s; } | |
| 1995/0722/sys/src/9/pc/scsi.c:421,427 – 1995/0723/sys/src/9/pc/scsi.c:421,427 | ||
| 1995/0722 | scsitrackinfo(Target *t, char lun, int track, uchar *data) { int s, nbytes; | |
| 1995/0723 | uchar cmd[10], *d; | |
| 1995/0722 | nbytes = 12; | |
| 1995/0722/sys/src/9/pc/scsi.c:432,437 – 1995/0723/sys/src/9/pc/scsi.c:432,503 | ||
| 1995/0722 | cmd[7] = nbytes>>8; cmd[8] = nbytes>>0; | |
| 1995/0723 | 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); | |
| 1995/0722 | return s; | |
| 1995/0723 | } 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; | |
| 1995/0722 | } | |
| 1995/0723/sys/src/9/pc/scsi.c:267,274 – 1995/0724/sys/src/9/pc/scsi.c:267,274 (short | long) | ||
| 1994/0908 | ||
| 1995/0723 | s = scsiexec(t, SCSIread, cmd, sizeof(cmd), d, &nbytes); if(s == STok) { | |
| 1995/0405 |
| |
| 1995/0724 | *size = nhgetl(d+0); *bsize = nhgetl(d+4); | |
| 1994/0908 | } | |
| 1995/0723 | scsifree(d); | |
| 1995/0405 | return s; | |
| 1995/0723/sys/src/9/pc/scsi.c:286,293 – 1995/0724/sys/src/9/pc/scsi.c:286,292 | ||
| 1994/0908 | if(dir == SCSIread) cmd[0] = 0x08; cmd[1] = (lun<<5) | bno >> 16; | |
| 1995/0724 | hnputs(cmd+2, bno); | |
| 1994/0908 | cmd[4] = n; cdbsiz = 6; } | |
| 1995/0723/sys/src/9/pc/scsi.c:296,307 – 1995/0724/sys/src/9/pc/scsi.c:295,302 | ||
| 1994/0908 | if(dir == SCSIread) cmd[0] = 0x28; cmd[1] = (lun<<5); | |
| 1995/0724 | hnputl(cmd+2, bno); hnputs(cmd+7, n); | |
| 1994/0908 | cdbsiz = 10; } nbytes = n*bsize; | |
| 1995/0723/sys/src/9/pc/scsi.c:403,410 – 1995/0724/sys/src/9/pc/scsi.c:398,404 | ||
| 1995/0723 | memset(cmd, 0, sizeof(cmd)); cmd[0] = 0x43; cmd[1] = lun<<5; | |
| 1995/0724 | hnputs(cmd+7, nbytes); | |
| 1995/0722 | ||
| 1995/0723 | d = scsialloc(nbytes); if(d == 0) | |
| 1995/0723/sys/src/9/pc/scsi.c:429,436 – 1995/0724/sys/src/9/pc/scsi.c:423,429 | ||
| 1995/0722 | cmd[0] = 0xe5; cmd[1] = lun<<5; cmd[5] = track; | |
| 1995/0724 | hnputs(cmd+7, nbytes); | |
| 1995/0722 | ||
| 1995/0723 | d = scsialloc(nbytes); if(d == 0) | |
| 1995/0723/sys/src/9/pc/scsi.c:464,472 – 1995/0724/sys/src/9/pc/scsi.c:457,463 | ||
| 1995/0723 | memset(d, 0, nbytes); d[3] = 8; | |
| 1995/0724 | hnputl(d+8, size); | |
| 1995/0723 | s = scsiexec(t, SCSIwrite, cmd, sizeof(cmd), d, &nbytes); scsifree(d); | |
| 1995/0723/sys/src/9/pc/scsi.c:483,496 – 1995/0724/sys/src/9/pc/scsi.c:474,481 | ||
| 1995/0723 | cmd[0] = 0xd8; cmd[1] = (lun<<5); | |
| 1995/0724 | hnputl(cmd+2, bno); hnputl(cmd+6, n); | |
| 1995/0723 | nbytes = n*bsize; s = scsiexec(t, SCSIread, cmd, sizeof(cmd), b, &nbytes); | |
| 1995/0724/sys/src/9/pc/scsi.c:206,212 – 1995/0725/sys/src/9/pc/scsi.c:206,213 (short | long) | ||
| 1995/0403 | continue; *rt = t; *inq = t->inq; | |
| 1995/0725 | if(id) sprint(id, "scsi%d: unit %d", ctlr, unit); | |
| 1995/0403 | return devno; } | |
| 1994/0908 | } | |
| 1995/0725/sys/src/9/pc/scsi.c:466,472 – 1995/0726/sys/src/9/pc/scsi.c:466,472 (short | long) | ||
| 1995/0723 | } int | |
| 1995/0726 | scsireadcdda(Target *t, char lun, int dir, void *b, long n, long bsize, long bno) | |
| 1995/0723 | { uchar cmd[10]; int s, nbytes; | |
| 1995/0726/sys/src/9/pc/scsi.c:371,379 – 1995/0808/sys/src/9/pc/scsi.c:371,380 (short | long) | ||
| 1995/0405 | } | |
| 1994/0908 | /* | |
| 1995/0808 | * Unit is becoming ready, rather than not ready | |
| 1994/0908 | */ | |
| 1995/0808 | if((sense[2] & 0x0F) != 0x02 && (sense[12] != 0x04 || sense[13] != 0x01)) | |
| 1994/0908 | break; delay(5000); | |
| 1995/0726/sys/src/9/pc/scsi.c:389,404 – 1995/0808/sys/src/9/pc/scsi.c:390,406 | ||
| 1994/0908 | } | |
| 1995/0722 | int | |
| 1995/0808 | scsidiskinfo(Target *t, char lun, int track, uchar *data) | |
| 1995/0722 | { | |
| 1995/0723 | int s, nbytes; uchar cmd[10], *d; | |
| 1995/0722 | ||
| 1995/0723 |
| |
| 1995/0808 | nbytes = 12; | |
| 1995/0722 | ||
| 1995/0723 | memset(cmd, 0, sizeof(cmd)); cmd[0] = 0x43; cmd[1] = lun<<5; | |
| 1995/0808 | cmd[6] = track; | |
| 1995/0724 | hnputs(cmd+7, nbytes); | |
| 1995/0722 | ||
| 1995/0723 | d = scsialloc(nbytes); | |
| 1995/0726/sys/src/9/pc/scsi.c:407,413 – 1995/0808/sys/src/9/pc/scsi.c:409,415 | ||
| 1995/0722 | ||
| 1995/0723 | memset(d, 0, nbytes); s = scsiexec(t, SCSIread, cmd, sizeof(cmd), d, &nbytes); | |
| 1995/0808 | memmove(data, d, 12); | |
| 1995/0723 | scsifree(d); | |
| 1995/0722 | return s; } | |
| 1995/0726/sys/src/9/pc/scsi.c:466,472 – 1995/0808/sys/src/9/pc/scsi.c:468,474 | ||
| 1995/0723 | } int | |
| 1995/0726 |
| |
| 1995/0808 | scsireadcdda(Target *t, char lun, int, void *b, long n, long bsize, long bno) | |
| 1995/0723 | { uchar cmd[10]; int s, nbytes; | |
| 1995/0808/sys/src/9/pc/scsi.c:339,345 – 1996/0210/sys/src/9/pc/scsi.c:339,345 (short | long) | ||
| 1994/0908 | ||
| 1995/0405 | sense = malloc(*nbytes); | |
| 1994/0908 |
| |
| 1996/0210 | for(try = 0; try < 20; try++) { | |
| 1994/0908 | memset(cmd, 0, sizeof(cmd)); cmd[0] = CMDreqsense; cmd[1] = lun<<5; | |
| 1995/0808/sys/src/9/pc/scsi.c:354,385 – 1996/0210/sys/src/9/pc/scsi.c:354,394 | ||
| 1995/0405 | *nbytes = sense[0x07]+8; memmove(data, sense, *nbytes); | |
| 1994/0908 |
| |
| 1995/0405 |
| |
| 1994/0908 |
| |
| 1995/0405 |
| |
| 1996/0210 | switch(sense[2] & 0x0F){ | |
| 1994/0908 |
| |
| 1995/0405 |
| |
| 1996/0210 | case 6: /* unit attention */ if(sense[12] != 0x29) /* power on, reset */ goto buggery; /*FALLTHROUGH*/ case 0: /* no sense */ case 1: /* recovered error */ | |
| 1995/0405 | free(sense); | |
| 1994/0908 | return STok; | |
| 1995/0405 |
| |
| 1994/0908 |
| |
| 1995/0808 |
| |
| 1994/0908 |
| |
| 1995/0808 |
| |
| 1994/0908 |
| |
| 1996/0210 | case 2: /* not ready */ if(sense[12] == 0x3A) /* medium not present */ goto buggery; /*FALLTHROUGH*/ | |
| 1994/0908 |
| |
| 1996/0210 | 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; } | |
| 1994/0908 | } | |
| 1996/0210 | buggery: | |
| 1995/0405 | if(quiet == 0){ s = key[sense[2]&0x0F]; print("scsi%d: unit %d reqsense: '%s' code #%2.2ux #%2.2ux\n", | |
| 1996/0210/sys/src/9/pc/scsi.c:78,84 – 1996/0607/sys/src/9/pc/scsi.c:78,84 (short | long) | ||
| 1995/0328 | if((ctlr->io = (*lp->reset)(ctlrno, ctlr)) == 0) | |
| 1994/0908 | break; | |
| 1995/0513 |
| |
| 1996/0607 | print("scsi#%d: %s: port 0x%luX irq %d", | |
| 1994/0908 | ctlrno, ctlr->type, ctlr->port, ctlr->irq, ctlr->mem, ctlr->size); | |
| 1995/0328 | if(ctlr->mem) | |
| 1996/0210/sys/src/9/pc/scsi.c:106,112 – 1996/0607/sys/src/9/pc/scsi.c:106,134 | ||
| 1994/0908 | int | |
| 1995/0324 | scsiexec(Target *t, int rw, uchar *cmd, int cbytes, void *data, int *dbytes) | |
| 1993/0915 | { | |
| 1995/0324 |
| |
| 1996/0607 | 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; | |
| 1994/0908 | } | |
| 1993/0915 | ||
| 1994/0908 | Target* | |
| 1996/0210/sys/src/9/pc/scsi.c:143,149 – 1996/0607/sys/src/9/pc/scsi.c:165,171 | ||
| 1995/0405 | nbytes = Nscratch; s = scsireqsense(t, 0, t->scratch, &nbytes, 0); if(s != STok){ | |
| 1995/0324 |
| |
| 1996/0607 | print("scsi#%d: unit %d unavailable, status %d\n", t->ctlrno, i, s); | |
| 1994/0908 | continue; } | |
| 1996/0210/sys/src/9/pc/scsi.c:154,164 – 1996/0607/sys/src/9/pc/scsi.c:176,186 | ||
| 1995/0324 | memset(t->inq, 0, Ninq); | |
| 1994/0908 | nbytes = Ninq; | |
| 1995/0329 | s = scsiinquiry(t, 0, t->inq, &nbytes); | |
| 1994/0908 |
| |
| 1995/0324 |
| |
| 1996/0607 | if(s != STok) { print("scsi#%d: unit %d inquire failed, status %d\n", t->ctlrno, i, s); | |
| 1994/0908 | continue; } | |
| 1995/0405 |
| |
| 1996/0607 | print("scsi#%d: unit %d: %s\n", t->ctlrno, i, t->inq+8); | |
| 1995/0324 | t->ok = 1; | |
| 1994/0908 | } | |
| 1993/0915 | } | |
| 1996/0210/sys/src/9/pc/scsi.c:264,270 – 1996/0607/sys/src/9/pc/scsi.c:286,292 | ||
| 1995/0723 | nbytes = 8; d = scsialloc(nbytes); | |
| 1994/0908 | if(d == 0) | |
| 1995/0723 |
| |
| 1996/0607 | return -1; | |
| 1994/0908 | ||
| 1995/0723 | s = scsiexec(t, SCSIread, cmd, sizeof(cmd), d, &nbytes); if(s == STok) { | |
| 1996/0210/sys/src/9/pc/scsi.c:302,311 – 1996/0607/sys/src/9/pc/scsi.c:324,333 | ||
| 1994/0908 | } nbytes = n*bsize; s = scsiexec(t, dir, cmd, cdbsiz, b, &nbytes); | |
| 1996/0607 | if(s != STok) { | |
| 1995/0405 | nbytes = Nscratch; scsireqsense(t, lun, t->scratch, &nbytes, 0); | |
| 1994/0908 |
| |
| 1996/0607 | return scsierrstr(s); | |
| 1994/0908 | } return nbytes; } | |
| 1996/0210/sys/src/9/pc/scsi.c:391,397 – 1996/0607/sys/src/9/pc/scsi.c:413,419 | ||
| 1996/0210 | buggery: | |
| 1995/0405 | if(quiet == 0){ s = key[sense[2]&0x0F]; | |
| 1996/0607 | print("scsi#%d: unit %d reqsense: '%s' code #%2.2ux #%2.2ux\n", | |
| 1995/0405 | t->ctlrno, t->target, s, sense[12], sense[13]); } free(sense); | |
| 1996/0210/sys/src/9/pc/scsi.c:414,420 – 1996/0607/sys/src/9/pc/scsi.c:436,442 | ||
| 1995/0722 | ||
| 1995/0723 | d = scsialloc(nbytes); if(d == 0) | |
| 1996/0607 | return scsierrstr(STnomem); | |
| 1995/0722 | ||
| 1995/0723 | memset(d, 0, nbytes); s = scsiexec(t, SCSIread, cmd, sizeof(cmd), d, &nbytes); | |
| 1996/0210/sys/src/9/pc/scsi.c:439,445 – 1996/0607/sys/src/9/pc/scsi.c:461,467 | ||
| 1995/0722 | ||
| 1995/0723 | d = scsialloc(nbytes); if(d == 0) | |
| 1996/0607 | return scsierrstr(STnomem); | |
| 1995/0723 | memset(d, 0, nbytes); s = scsiexec(t, SCSIread, cmd, sizeof(cmd), d, &nbytes); | |
| 1996/0210/sys/src/9/pc/scsi.c:465,471 – 1996/0607/sys/src/9/pc/scsi.c:487,493 | ||
| 1995/0723 | d = scsialloc(nbytes); if(d == 0) | |
| 1996/0607 | return scsierrstr(STnomem); | |
| 1995/0723 | memset(d, 0, nbytes); d[3] = 8; | |
| 1996/0210/sys/src/9/pc/scsi.c:491,500 – 1996/0607/sys/src/9/pc/scsi.c:513,577 | ||
| 1995/0723 | nbytes = n*bsize; s = scsiexec(t, SCSIread, cmd, sizeof(cmd), b, &nbytes); | |
| 1996/0607 | if(s != STok) { | |
| 1995/0723 | nbytes = Nscratch; scsireqsense(t, lun, t->scratch, &nbytes, 0); | |
| 1996/0607 | return scsierrstr(s); | |
| 1995/0723 | } return nbytes; | |
| 1996/0607 | } 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; | |
| 1995/0722 | } | |
| 1996/0607/sys/src/9/pc/scsi.c:286,292 – 1996/0620/sys/src/9/pc/scsi.c:286,292 (short | long) | ||
| 1995/0723 | nbytes = 8; d = scsialloc(nbytes); | |
| 1994/0908 | if(d == 0) | |
| 1996/0607 |
| |
| 1996/0620 | return scsierrstr(STnomem); | |
| 1994/0908 | ||
| 1995/0723 | s = scsiexec(t, SCSIread, cmd, sizeof(cmd), d, &nbytes); if(s == STok) { | |
| 1996/0620/sys/src/9/pc/scsi.c:290,297 – 1996/0622/sys/src/9/pc/scsi.c:290,297 (short | long) | ||
| 1994/0908 | ||
| 1995/0723 | s = scsiexec(t, SCSIread, cmd, sizeof(cmd), d, &nbytes); if(s == STok) { | |
| 1995/0724 |
| |
| 1996/0622 | *size = (d[0]<<24)|(d[1]<<16)|(d[2]<<8)|d[3]; *bsize = (d[4]<<24)|(d[5]<<16)|(d[6]<<8)|d[7]; | |
| 1994/0908 | } | |
| 1995/0723 | scsifree(d); | |
| 1995/0405 | return s; | |
| 1996/0620/sys/src/9/pc/scsi.c:303,316 – 1996/0622/sys/src/9/pc/scsi.c:303,317 | ||
| 1994/0908 | uchar cmd[10]; int s, cdbsiz, nbytes; | |
| 1995/0724 |
| |
| 1996/0622 | cmd[2] = bno>>8; cmd[3] = bno; | |
| 1994/0908 | cmd[4] = n; | |
| 1996/0622 | cmd[5] = 0; | |
| 1994/0908 | cdbsiz = 6; } else { | |
| 1996/0620/sys/src/9/pc/scsi.c:318,325 – 1996/0622/sys/src/9/pc/scsi.c:319,331 | ||
| 1994/0908 | if(dir == SCSIread) cmd[0] = 0x28; cmd[1] = (lun<<5); | |
| 1995/0724 |
| |
| 1996/0622 | 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; | |
| 1994/0908 | cdbsiz = 10; } nbytes = n*bsize; | |
| 1996/0620/sys/src/9/pc/scsi.c:432,438 – 1996/0622/sys/src/9/pc/scsi.c:438,445 | ||
| 1995/0723 | cmd[0] = 0x43; cmd[1] = lun<<5; | |
| 1995/0808 | cmd[6] = track; | |
| 1995/0724 |
| |
| 1996/0622 | cmd[7] = nbytes>>8; cmd[8] = nbytes; | |
| 1995/0722 | ||
| 1995/0723 | d = scsialloc(nbytes); if(d == 0) | |
| 1996/0620/sys/src/9/pc/scsi.c:457,463 – 1996/0622/sys/src/9/pc/scsi.c:464,471 | ||
| 1995/0722 | cmd[0] = 0xe5; cmd[1] = lun<<5; cmd[5] = track; | |
| 1995/0724 |
| |
| 1996/0622 | cmd[7] = nbytes>>8; cmd[8] = nbytes; | |
| 1995/0722 | ||
| 1995/0723 | d = scsialloc(nbytes); if(d == 0) | |
| 1996/0620/sys/src/9/pc/scsi.c:491,497 – 1996/0622/sys/src/9/pc/scsi.c:499,508 | ||
| 1995/0723 | memset(d, 0, nbytes); d[3] = 8; | |
| 1995/0724 |
| |
| 1996/0622 | d[8] = size>>24; d[9] = size>>16; d[10] = size>>8; d[11] = size; | |
| 1995/0723 | s = scsiexec(t, SCSIwrite, cmd, sizeof(cmd), d, &nbytes); scsifree(d); | |
| 1996/0620/sys/src/9/pc/scsi.c:508,515 – 1996/0622/sys/src/9/pc/scsi.c:519,530 | ||
| 1995/0723 | cmd[0] = 0xd8; cmd[1] = (lun<<5); | |
| 1995/0724 |
| |
| 1996/0622 | cmd[2] = bno>>24; cmd[3] = bno>>16; cmd[4] = bno>>8; cmd[5] = bno; cmd[6] = n>>8; cmd[7] = n; | |
| 1995/0723 | nbytes = n*bsize; s = scsiexec(t, SCSIread, cmd, sizeof(cmd), b, &nbytes); | |
| 1996/0622/sys/src/9/pc/scsi.c:362,379 – 1996/1018/sys/src/9/pc/scsi.c:362,381 (short | long) | ||
| 1995/0405 | scsireqsense(Target *t, char lun, void *data, int *nbytes, int quiet) | |
| 1994/0908 | { char *s; | |
| 1995/0405 |
| |
| 1996/1018 | int n, status, try; | |
| 1994/0908 | uchar cmd[6], *sense; | |
| 1995/0405 |
| |
| 1996/1018 | n = *nbytes; sense = malloc(n); | |
| 1994/0908 | ||
| 1996/0210 | for(try = 0; try < 20; try++) { | |
| 1994/0908 | memset(cmd, 0, sizeof(cmd)); cmd[0] = CMDreqsense; cmd[1] = lun<<5; | |
| 1995/0405 |
| |
| 1996/1018 | cmd[4] = n; memset(sense, 0, n); | |
| 1994/0908 | ||
| 1996/1018 | *nbytes = n; | |
| 1995/0405 | status = scsiexec(t, SCSIread, cmd, sizeof(cmd), sense, nbytes); if(status != STok){ free(sense); | |
| 1996/1018/sys/src/9/pc/scsi.c:103,108 – 1996/1022/sys/src/9/pc/scsi.c:103,111 (short | long) | ||
| 1994/0908 | free(ctlr); | |
| 1993/0915 | } | |
| 1996/1022 | static uchar lastcmd[16]; static int lastcmdsz; | |
| 1994/0908 | int | |
| 1995/0324 | scsiexec(Target *t, int rw, uchar *cmd, int cbytes, void *data, int *dbytes) | |
| 1993/0915 | { | |
| 1996/1018/sys/src/9/pc/scsi.c:115,120 – 1996/1022/sys/src/9/pc/scsi.c:118,128 | ||
| 1996/0607 | */ switch(s = (*scsi[t->ctlrno]->io)(t, rw, cmd, cbytes, data, dbytes)){ | |
| 1996/1022 | case STcheck: memmove(lastcmd, cmd, cbytes); lastcmdsz = cbytes; /*FALLTHROUGH*/ | |
| 1996/0607 | default: /* * It's more complicated than this. There are conditions which | |
| 1996/1018/sys/src/9/pc/scsi.c:323,328 – 1996/1022/sys/src/9/pc/scsi.c:331,337 | ||
| 1996/0622 | cmd[3] = bno>>16; cmd[4] = bno>>8; cmd[5] = bno; | |
| 1996/1022 | cmd[6] = 0; | |
| 1996/0622 | cmd[7] = n>>8; cmd[8] = n; cmd[9] = 0; | |
| 1996/1018/sys/src/9/pc/scsi.c:423,428 – 1996/1022/sys/src/9/pc/scsi.c:432,443 | ||
| 1995/0405 | s = key[sense[2]&0x0F]; | |
| 1996/0607 | print("scsi#%d: unit %d reqsense: '%s' code #%2.2ux #%2.2ux\n", | |
| 1995/0405 | t->ctlrno, t->target, s, sense[12], sense[13]); | |
| 1996/1022 | 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"); | |
| 1995/0405 | } free(sense); | |
| 1994/0908 | return STcheck; | |
| 1996/1022/sys/src/9/pc/scsi.c:540,547 – 1996/1224/sys/src/9/pc/scsi.c:540,547 (short | long) | ||
| 1996/0622 | cmd[3] = bno>>16; cmd[4] = bno>>8; cmd[5] = bno; | |
| 1996/1224 | cmd[8] = n>>8; cmd[9] = n; | |
| 1995/0723 | nbytes = n*bsize; s = scsiexec(t, SCSIread, cmd, sizeof(cmd), b, &nbytes); | |
| 1996/1224/sys/src/9/pc/scsi.c:75,81 – 1997/0327/sys/src/9/pc/scsi.c:75,81 (short | long) | ||
| 1995/0328 | for(lp = link; lp; lp = lp->link){ if(strcmp(lp->type, ctlr->type)) | |
| 1994/0908 | continue; | |
| 1995/0328 |
| |
| 1997/0327 | if((ctlr->io = lp->reset(ctlrno, ctlr)) == 0) | |
| 1994/0908 | break; | |
| 1996/0607 | print("scsi#%d: %s: port 0x%luX irq %d", | |
| 1996/1224/sys/src/9/pc/scsi.c:116,122 – 1997/0327/sys/src/9/pc/scsi.c:116,122 | ||
| 1996/0607 | * There should be no calls to 'error()' below this * which percolate back up. */ | |
| 1997/0327 | switch(s = scsi[t->ctlrno]->io(t, rw, cmd, cbytes, data, dbytes)){ | |
| 1996/0607 | ||
| 1996/1022 | case STcheck: memmove(lastcmd, cmd, cbytes); | |
| 1996/1224/sys/src/9/pc/scsi.c:245,251 – 1997/0327/sys/src/9/pc/scsi.c:245,250 | ||
| 1994/0908 | return -1; | |
| 1995/0404 | } | |
| 1996/1224/sys/src/9/pc/scsi.c:540,547 – 1997/0327/sys/src/9/pc/scsi.c:539,546 | ||
| 1996/0622 | cmd[3] = bno>>16; cmd[4] = bno>>8; cmd[5] = bno; | |
| 1996/1224 |
| |
| 1997/0327 | cmd[6] = n>>8; cmd[7] = n; | |
| 1995/0723 | nbytes = n*bsize; s = scsiexec(t, SCSIread, cmd, sizeof(cmd), b, &nbytes); | |
| 1997/0327/sys/src/9/pc/scsi.c:539,546 – 1997/0628/sys/src/9/pc/scsi.c:539,548 (short | long) | ||
| 1996/0622 | cmd[3] = bno>>16; cmd[4] = bno>>8; cmd[5] = bno; | |
| 1997/0327 |
| |
| 1997/0628 | cmd[6] = n>>24; cmd[7] = n>>16; cmd[8] = n>>8; cmd[9] = n; | |
| 1995/0723 | nbytes = n*bsize; s = scsiexec(t, SCSIread, cmd, sizeof(cmd), b, &nbytes); | |
| 1997/0628/sys/src/9/pc/scsi.c:320,327 – 1997/0629/sys/src/9/pc/scsi.c:320,326 (short | long) | ||
| 1994/0908 | cmd[4] = n; | |
| 1996/0622 | cmd[5] = 0; | |
| 1994/0908 | cdbsiz = 6; | |
| 1997/0629 | } else { | |
| 1994/0908 | cmd[0] = 0x2A; if(dir == SCSIread) cmd[0] = 0x28; | |
| Too many diffs (26 > 25). Stopping. | ||