## 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
|