## diffname power/scsi.c 1992/1208
## diff -e /dev/null /n/bootesdump/1992/1208/sys/src/9/power/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"
enum
{
Rownid = 0x00, /* own ID/CDB size register */
Eaf = 0x08, /* enable advanced features */
Fs16MHz = 0x80, /* frequency select */
Rcontrol = 0x01, /* control register */
Hsp = 0x01, /* halt on scsi parity error */
Idi = 0x04, /* intermediate disconnect interrupt */
Edi = 0x08, /* ending disconnect interrupt */
BurstDma = 0x20, /* burst mode dma */
Rtimeout = 0x02, /* timeout period register */
Rcdb = 0x03, /* CDB first byte */
Rlun = 0x0F, /* target LUN register */
Rcmdphase = 0x10, /* command phase register */
Rsync = 0x11, /* synchronous transfer register */
Rtchi = 0x12, /* transfer count hi register */
Rtcmi = 0x13, /* transfer count mi register */
Rtclo = 0x14, /* transfer count lo register */
Rdestid = 0x15, /* destination ID */
Dpd = 0x40, /* data-phase direction (read) */
Rsrcid = 0x16, /* source ID */
Siv = 0x08, /* source ID is valid */
Er = 0x80, /* enable reselection */
Rstatus = 0x17, /* scsi status register */
Rcmd = 0x18, /* command register */
Rdata = 0x19, /* data register */
Raux = 0x1F, /* auxiliary status register */
Dbr = 0x01, /* data buffer ready */
Intrpend = 0x80, /* interrupt pending */
Creset = 0x00, /* reset */
Catn = 0x02, /* assert ATN */
Cnack = 0x03, /* negate ACK */
CselectATN = 0x06, /* select with ATN */
Cselect = 0x07, /* select without ATN */
CtransferATN = 0x08, /* select with ATN and transfer */
Ctransfer = 0x09, /* select without ATN and transfer */
Ctinfo = 0x20, /* transfer info */
Csbt = 0x80, /* single-byte transfer */
Mcomplete = 0x00, /* complete */
Msaveptr = 0x02, /* save pointers */
Mdisconnect = 0x04, /* disconnect */
Mabort = 0x06, /* abort */
Mreject = 0x07, /* reject */
Mnop = 0x08, /* nop */
Mbdr = 0x0C, /* bus device reset */
Midentify = (0x80|0x40), /* identify|disconnectok */
};
typedef struct Target Target;
struct Target
{
QLock;
Rendez;
ulong flags;
uchar sync;
uchar transfer;
Target *active; /* link on active list */
int target; /* SCSI Unit and logical unit */
int lun;
int status;
struct { /* DMA things */
ulong dmaaddr;
ulong dmalen;
int rflag;
ulong *dmacnt;
uchar *dmafls;
ulong dmamap;
};
uchar cdb[16];
int clen;
uchar *addr;
uchar *data;
Target *base;
Target *ctlr;
};
enum
{
NCtlr = 2,
NTarget = 8,
CtlrID = 0,
Fbusy = 0x0001,
Fidentified = 0x0002,
Fdisconnected = 0x0004,
Freselect = 0x0008,
Fcomplete = 0x0010,
Fsyncxfer = 0x0100,
Freadxfer = 0x0200,
Fdmaxfer = 0x0400,
Fretry = 0x1000,
Fidentifying = 0x2000,
};
static Target target[NCtlr][NTarget];
static void dmamap(Target*);
/*
* Set up and start a data transfer.
* We don't load the command phase here as
* we may be continuing a stopped operation.
*/
static void
start(Target *tp)
{
ulong count;
Target *dev = tp->ctlr;
/*
* Set up the chip for the transfer.
* First the LUN and transfer mode.
*/
*dev->addr = Rlun;
*dev->data = tp->lun;
*dev->addr = Rsync;
*dev->data = tp->sync;
/*
* Set up transfer count and targetID+direction.
* No need to set the address register here, we're
* already pointing to the right one.
*/
count = tp->dmalen;
*dev->data = (count>>16) & 0xFF;
*dev->data = (count>>8) & 0xFF;
*dev->data = count & 0xFF;
if(tp->rflag == 0)
*dev->data = Dpd|tp->target;
else
*dev->data = tp->target;
/*
* Load the command into the chip.
*/
*dev->addr = Rownid;
*dev->data = tp->clen;
*dev->addr = Rcdb;
print("start %d cdb: ", tp->target);
for(count = 0; count < tp->clen; count++) {
*dev->data = tp->cdb[count];
print("%2.2lux ", tp->cdb[count]);
}
print("\n");
dmamap(tp);
/*
* Select and transfer.
*/
*dev->addr = Rcmd;
*dev->data = tp->transfer;
}
/*
* Arbitrate for the bus and start a data transfer.
* If this is the first time through for the target,
* i.e. we haven't identified yet, just set up for
* selection so we can try a synchronous negotiation.
*/
static void
arbitrate(Target *dev)
{
Target *tp;
tp = dev->active;
*dev->addr = Rcmdphase;
*dev->data = 0x00;
if(tp->flags & Fidentified) {
start(tp);
return;
}
/*
* Fretry means that we will try this request again,
* but without initialising the command phase, so we will
* continue from where we left off.
*/
tp->flags |= Fidentifying|Fretry;
*dev->addr = Rlun;
*dev->data = tp->lun;
*dev->addr = Rdestid;
*dev->data = tp->target;
*dev->addr = Rcmd;
*dev->data = CselectATN;
}
static int
done(void *arg)
{
return (((Target*)arg)->flags & Fbusy) == 0;
}
static int
scsiio(int nbus, int unit, int rw, uchar *cmd, int cbytes, void *data, int dbytes)
{
ulong s;
int status;
Target *ctlr, **l, *f, *tp;
tp = &target[nbus][unit];
ctlr = tp->ctlr;
qlock(tp);
tp->flags |= Fbusy;
tp->rflag = rw;
tp->dmaaddr = (ulong)data;
tp->dmalen = dbytes;
tp->status = 0x6002;
memmove(tp->cdb, cmd, cbytes);
tp->clen = cbytes;
s = splhi();
qlock(ctlr);
/*
* Link the target onto the end of the
* ctlr active list and start the request if
* the controller is idle.
*/
tp->active = 0;
l = &ctlr->active;
for(f = *l; f; f = f->active)
l = &f->active;
*l = tp;
if((ctlr->flags & Fbusy) == 0){
ctlr->flags |= Fbusy;
arbitrate(ctlr);
}
qunlock(ctlr);
splx(s);
/*
* Wait for the request to complete
* and return the status.
*/
sleep(tp, done, tp);
status = tp->status;
qunlock(tp);
print("status: #%4.4lux\n", status);
return status;
}
int
scsiexec(Scsi *p, int read)
{
int rw, s;
ulong clen, dlen;
clen = p->cmd.lim - p->cmd.base;
dlen = p->data.lim - p->data.base;
rw = 1;
if(read == ScsiIn)
rw = 0;
if(p->target == CtlrID)
return 0x6002;
s = scsiio(1, p->target, rw, p->cmd.base, clen, p->data.base, dlen);
p->status = s;
return s;
}
/*
* Target request complete.
* Only called from interrupt level,
* i.e. ctlr is 'locked'.
*/
static void
complete(Target *ctlr)
{
Target *tp;
tp = ctlr->active;
tp->flags &= (Fretry|Fidentified|Fbusy);
/*
* Retry (continue) the operation if necessary
* (used for initial identify), otherwise unlink from
* the ctlr active list.
*/
if(tp->flags & Fretry){
tp->flags &= ~Fretry;
start(tp);
return;
}
ctlr->active = tp->active;
/*
* All done with this target, wakeup scsiio.
* If there are other targets queued, start
* one up.
*/
tp->flags &= Fidentified;
*tp->dmafls = 1;
wakeup(tp);
if(ctlr->active){
arbitrate(ctlr);
return;
}
ctlr->flags &= ~Fbusy;
}
/*
* A target has disconnected.
* Unlink it from the active list and
* start another if possible.
* Only called from interrupt level,
* i.e. ctlr is 'locked'.
*/
static void
disconnect(Target *ctlr)
{
Target *tp;
tp = ctlr->active;
tp->flags |= Fdisconnected;
ctlr->active = tp->active;
if(ctlr->active){
arbitrate(ctlr);
return;
}
ctlr->flags &= ~Fbusy;
}
/*
* A target reselected, put it back
* on the ctlr active list. We mark the ctlr
* busy, it's the responsibility of the caller
* to restart the transfer.
* Only called from interrupt level,
* i.e. ctlr is 'locked'.
*/
static void
reselect(Target *ctlr, uchar id)
{
Target *tp;
tp = &ctlr->base[id];
tp->active = ctlr->active;
ctlr->active = tp;
ctlr->flags |= Fbusy;
tp->flags &= ~Fdisconnected;
}
static int
identify(Target *tp, uchar status)
{
int i, n;
Target *dev;
static uchar msgout[6] = {
0x00, 0x01, 0x03, 0x01, 0x3F, 0x0C
};
uchar msgin[16];
dev = tp->ctlr;
switch(status){
case 0x11: /* select complete */
delay(7);
*dev->addr = Rcmd;
*dev->data = Catn;
break;
case 0x8E: /* service required - MSGOUT */
/*
* Send a synchronous data transfer request.
* The target may act strangely here and not respond
* correctly.
*/
tp->sync = 0x00; /* asynchronous transfer mode */
tp->flags |= Fidentified;
*dev->addr = Rtchi;
*dev->data = 0x00;
*dev->data = 0x00;
*dev->data = sizeof(msgout);
*dev->addr = Rcmd;
*dev->data = Ctinfo;
msgout[0] = Midentify|tp->lun;
*dev->addr = Rdata;
n = 0;
while(n < sizeof(msgout)) {
/*
* Wait until the chip says ready.
* If an interrupt is indicated, something
* went wrong, so get out of here and let
* the interrupt happen.
*/
if(*dev->addr & Intrpend)
return 0;
if(*dev->addr & Dbr){
*dev->data = msgout[n];
n++;
}
}
break;
case 0x1F: /* transfer complete - MSGIN */
case 0x4F: /* unexpected MSGIN */
/*
* Collect the response. The first 3 bytes
* of an extended message are:
* 0. extended message code (0x01)
* 1. extended message length (0x03)
* 2. sync. tranfer req. code (0x01)
* Only other defined code with length >1 is
* 'modify data pointer', which has length 7;
* we better not receive anything much longer...
* Adjust the number of bytes to collect once we see
* how long the response is (byte 2).
* If we collect anything other than an extended message
* or sync. transfer req. response, toss it
* and assume async.
*/
*dev->addr = Rtchi;
*dev->data = 0x00;
*dev->data = 0x00;
*dev->data = 5;
*dev->addr = Rcmd;
*dev->data = Ctinfo;
*dev->addr = Rdata;
for(i = sizeof(msgin)-1, n = 0; n < i; n++){
while((*dev->addr & Dbr) == 0){
if(*dev->addr & Intrpend)
return 0;
}
msgin[n] = *dev->data;
if(n == 1)
i = msgin[1] + 2;
}
if(msgin[2] == 0x01 && (n = msgin[3]) && n != 0xFF){
if(n < 0x40)
n = 0x02;
else if(n < 0x80)
n = 0x04;
else
n = 0;
n |= msgin[4]<<4;
tp->sync = n;
}
break;
case 0x4E:
*dev->addr = Rcmd;
*dev->data = Csbt|Ctinfo;
*dev->addr = Rdata;
while((*dev->addr & Dbr) == 0){
if(*dev->addr & Intrpend)
return 0;
}
*dev->data = Mnop;
break;
case 0x20: /* transfer info paused */
delay(7);
*dev->addr = Rcmd;
*dev->data = Cnack;
break;
case 0x1A:
case 0x8A:
/*
* Fretry should be set, so we will
* pick up from here.
*/
*dev->addr = Rcmdphase;
*dev->data = 0x30; /* command phase has begun */
complete(dev);
break;
default:
return 1;
}
return 0;
}
static void
saveptr(Target *tp)
{
ulong count;
Target *dev;
*tp->dmafls = 1;
dev = tp->ctlr;
/*
* The transfer count register contains the
* number of bytes NOT transferred.
*/
*dev->addr = Rtchi;
count = (*dev->data & 0xFF)<<16;
count += (*dev->data & 0xFF)<<8;
count += (*dev->data & 0xFF);
tp->dmaaddr += tp->dmalen - count;
tp->dmalen = count;
*dev->addr = Rcmd;
*dev->data = tp->transfer;
}
int
scsistatus(Target *ctlr)
{
ulong status;
*ctlr->addr = Rlun;
status = *ctlr->data & 0xFF; /* target status */
status |= *ctlr->data<<8; /* command phase */
return status;
}
void
scsiintr(int ctlrno)
{
uchar status, x;
Target *ctlr, *tp;
ctlr = &target[ctlrno][CtlrID];
tp = ctlr->active;
*ctlr->addr = Rstatus;
status = *ctlr->data;
print("scsiintr: #%2.2lux\n", status);
if(tp == 0)
return;
switch(status){
case 0x42: /* timeout */
tp->flags &= ~Fretry;
scsistatus(ctlr); /* Must read lun register */
complete(ctlr);
return;
case 0x16: /* select-and-transfer complete */
/*
* The target status comes back in the Rlun
* register. Returned status is combined
* with the final command phase, which
* should be 0x60.
*/
tp->status = scsistatus(ctlr); /* target status */
complete(ctlr);
return;
case 0x21: /* save data pointers */
saveptr(tp);
return;
case 0x4B: /* unexpected status phase */
*ctlr->addr = Rcmdphase;
*ctlr->data = 0x46; /* */
*ctlr->addr = Rtchi;
*ctlr->data = 0;
*ctlr->data = 0;
*ctlr->data = 0;
*ctlr->addr = Rcmd;
*ctlr->data = tp->transfer;
return;
case 0x85: /* disconnect */
if(tp->flags & Fidentifying){
*ctlr->addr = Rcmdphase;
*ctlr->data = 0x00; /* complete retry */
complete(ctlr);
return;
}
disconnect(ctlr);
return;
case 0x81:
*ctlr->addr = Rsrcid;
x = *ctlr->data;
if(x & Siv){ /* source ID valid */
reselect(ctlr, x & 0x07);
*ctlr->addr = Rcmdphase;
*ctlr->data = 0x44; /* reselected by target */
start(ctlr->active);
return;
}
break;
default:
if((tp->flags & Fidentifying) && identify(tp, status) == 0)
return;
break;
}
delay(1000);
print("scsi intr status #%.2ux\n", status);
print("scsi aux status #%.2ux\n", *ctlr->addr & 0xFF);
for(*ctlr->addr = 0x00, x = 0x00; x < 0x19; x++){
if((x & 0x07) == 0x07)
print("#%.2ux: #%.2ux\n", x, *ctlr->data & 0xFF);
else
print("#%.2ux: #%.2ux ", x, *ctlr->data & 0xFF);
}
panic("scsiintr\n");
}
void
scsiicltr(int ctlrnr, uchar *data, uchar *addr, ulong *cnt, uchar *fls, ulong map)
{
int i;
uchar status;
Target *ctlr, *tp;
ctlr = &target[ctlrnr][CtlrID];
ctlr->data = data;
ctlr->addr = addr;
ctlr->base = target[ctlrnr];
if(*ctlr->addr & Intrpend) {
*ctlr->addr = Rstatus;
status = *ctlr->data;
USED(status);
}
/*
* Give the chip a soft reset. This will
* cause an interrupt. Wait for it and clear it.
*/
*ctlr->addr = Rownid;
*ctlr->data = Fs16MHz|Eaf|CtlrID;
*ctlr->addr = Rcmd;
*ctlr->data = Creset;
while((*ctlr->addr & Intrpend) == 0)
delay(250);
*ctlr->addr = Rstatus;
status = *ctlr->data;
USED(status);
/*
* Freselect means enable the chip to
* respond to reselects.
*/
ctlr->flags = /*Freselect|*/Fidentified;
*ctlr->addr = Rcontrol;
*ctlr->data = BurstDma|Edi|Idi|Hsp;
*ctlr->addr = Rtimeout;
*ctlr->data = 40; /* 200ms */
*ctlr->addr = Rsrcid;
if(ctlr->flags & Freselect)
*ctlr->data = Er;
else
*ctlr->data = 0x00;
for(i = 0; i < NTarget; i++){
if(i == CtlrID)
continue;
tp = &target[ctlrnr][i];
tp->lun = 0;
tp->target = i;
tp->ctlr = ctlr;
tp->dmacnt = cnt;
tp->dmafls = fls;
tp->dmamap = map;
if(ctlr->flags & Freselect){
tp->flags = 0;
tp->transfer = CtransferATN;
}
else {
tp->flags = Fidentified;
tp->transfer = Ctransfer;
}
}
}
/*
* Called at boot time.
* Initialise the hardware.
* There will be an interrupt in reponse
* to the reset.
*/
void
resetscsi(void)
{
uchar m3;
print("scsi init\n");
/*
* Reset both scsi busses
*/
m3 = MODEREG->promenet;
m3 &= ~((1<<6)|(1<<7));
MODEREG->promenet = m3 | (1<<6) | (1<<7);
delay(500);
MODEREG->promenet = m3;
delay(100);
scsiicltr(0, SCSI0DATA, SCSI0ADDR, SCSI0CNT, SCSI0FLS, 0x1fc0);
scsiicltr(1, SCSI1DATA, SCSI1ADDR, SCSI1CNT, SCSI1FLS, 0x1f80);
}
static void
dmamap(Target *tp)
{
ulong y, len, addr, index, off;
*tp->dmafls = 1;
len = tp->dmalen;
if(len == 0)
return;
addr = tp->dmaaddr;
index = tp->dmamap;
for(y = addr+len+BY2PG; addr < y; addr += BY2PG){
*WRITEMAP = (index<<16)|(addr>>12)&0xFFFF;
index++;
}
off = tp->dmaaddr & (BY2PG-1);
if(tp->rflag == 0)
off |= 1<<15;
*tp->dmacnt = off;
}
/*
* Known to devscsi.c.
*/
int scsidebugs[8];
int scsiownid = CtlrID;
void
initscsi(void)
{
}
.
## diffname power/scsi.c 1992/1209
## diff -e /n/bootesdump/1992/1208/sys/src/9/power/scsi.c /n/bootesdump/1992/1209/sys/src/9/power/scsi.c
715c
.
676a
*ctlr->addr = Rsrcid;
.
675d
669c
ctlr->flags = Freselect|Fidentified;
.
606,607c
ctlr->active->cmdphase = 0x44; /* reselected by target */
.
593,594c
tp->cmdphase = 0x00; /* complete retry */
.
582c
if(phase <= 0x3c)
*ctlr->data = 0x41; /* resume no data */
else
*ctlr->data = 0x46; /* collect status */
.
580c
case 0x4B: /* unexpected status phase */
saveptr(tp);
.
577a
*ctlr->addr = Rcmd;
*ctlr->data = tp->transfer;
.
576c
case 0x21: /* save data pointers */
.
571a
saveptr(tp);
.
558a
case 0x00: /* reset interrupt */
return;
.
554,556d
551a
if(*ctlr->addr & 0x20)
print("busy\n");
*ctlr->addr = Rcmdphase;
phase = *ctlr->data;
.
546c
uchar status, x, phase;
.
526,528c
tp->dmatx += tx;
.
524c
tx = tp->dmalen - count;
tp->dmaaddr += tx;
.
510a
ulong count, tx;
.
509d
495,496c
tp->cmdphase = 0x30; /* command phase has begun */
.
483c
case 0x20: /* transfer info paused */
.
426,427c
case 0x1F: /* transfer complete - MSGIN */
case 0x4F: /* unexpected MSGIN */
.
399c
tp->sync = 0x00; /* asynchronous transfer mode */
.
393c
case 0x8E: /* service required - MSGOUT */
.
387c
case 0x11: /* select complete */
.
282,284c
p->status = scsiio(1, p, rw);
return p->status;
.
272,274d
269,270c
int rw;
.
262c
.
260a
p->data.ptr += tp->dmatx;
.
231a
tp->clen = p->cmd.lim - p->cmd.base;
memmove(tp->cdb, p->cmd.base, tp->clen);
.
229,230d
226,227c
tp->dmaaddr = (ulong)p->data.base;
tp->dmalen = p->data.lim - p->data.base;
tp->dmatx = 0;
.
220c
tp = &target[nbus][p->target];
.
214c
scsiio(int nbus, Scsi *p, int rw)
.
200a
*dev->data = 0x00; /* cmdphase */
.
185,186c
tp->cmdphase = 0x00;
.
162d
157,160c
for(count = 0; count < tp->clen; count++)
*dev->data = tp->cdb[count];
.
153,155c
if(tp->cmdphase < 0x40) {
*dev->addr = Rownid;
*dev->data = tp->clen;
*dev->addr = Rcdb;
.
132c
*dev->data = tp->cmdphase;
.
116,118c
* Set up and start a data transfer. This maybe
* a continuation.
.
75a
ulong dmatx;
.
66a
uchar cmdphase;
.
## diffname power/scsi.c 1992/1210
## diff -e /n/bootesdump/1992/1209/sys/src/9/power/scsi.c /n/bootesdump/1992/1210/sys/src/9/power/scsi.c
260c
tsleep(tp, done, tp, 60*5*1000);
if(!done(tp)) {
print("scsi%d: Timeout! cmd=#%2.2lux\n", nbus, tp->cdb[0]);
scsiregs(ctlr);
}
.
212a
static void
scsiregs(Target *ctlr)
{
int x;
print("scsi aux status #%.2ux\n", *ctlr->addr & 0xFF);
for(*ctlr->addr = 0x00, x = 0x00; x < 0x19; x++){
if((x & 0x07) == 0x07)
print("#%.2ux: #%.2ux\n", x, *ctlr->data & 0xFF);
else
print("#%.2ux: #%.2ux ", x, *ctlr->data & 0xFF);
}
}
.
## diffname power/scsi.c 1992/1213
## diff -e /n/bootesdump/1992/1210/sys/src/9/power/scsi.c /n/bootesdump/1992/1213/sys/src/9/power/scsi.c
301c
p->status = scsiio(0, p, rw);
.
## diffname power/scsi.c 1992/1217
## diff -e /n/bootesdump/1992/1213/sys/src/9/power/scsi.c /n/bootesdump/1992/1217/sys/src/9/power/scsi.c
655c
panic("\nscsiintr");
}
void
scsiintr(int ctlrno)
{
Target *ctlr;
ctlr = &target[ctlrno][CtlrID];
lock(&ctlr->regs);
scsiprocessint(ctlrno, ctlr);
unlock(&ctlr->regs);
.
653c
print("#%.2ux: #%2.2ux ", x, *ctlr->data);
.
651c
print("#%.2ux: #%2.2ux\n", x, *ctlr->data);
.
646,648c
print("scsi%d:\n", ctlrno);
if(tp) print("unit %d cmd #%2.2lux flags #%4.4lux phase #%2.2lux\n",
tp->target, tp->cdb[0], tp->flags, tp->cmdphase);
print("scsi status #%.2ux phase #%2.2lux\n", status, phase);
print("aux status #%2.2ux was #%2.2lux\n", *ctlr->addr, aux);
.
641a
if(tp == 0) {
print("scsi%d: bogus sr #%2.2lux phase #%2.2lux\n",
ctlrno, status, phase);
return;
}
.
639c
reselect(ctlr, sid & 0x07);
ctlr->active->cmdphase = 0x45; /* reselected by target */
start(ctlr->active);
return;
.
631,637c
*ctlr->addr = Rdata;
x = *ctlr->data; /* the identify message */
USED(x);
if((sid & Siv) == 0) { /* source ID valid */
print("scsi%d: invalid src id\n", ctlrno);
break;
.
623c
tp->cmdphase = 0x00; /* complete retry */
.
621c
case 0x85: /* disconnect */
.
613,618c
issue(ctlr, tp->transfer);
.
602,603c
issue(ctlr, tp->transfer);
.
589,594d
581a
switch(status) {
.
578,580c
if((aux&0x40) && status != 0x81)
print("lci but not reconnect #%2.2lux\n", status);
.
574c
*ctlr->addr = Rsrcid;
sid = *ctlr->data;
.
571a
aux = *ctlr->addr;
if((aux&0x80) == 0) {
print("scsi%d: bogus int #%2.2lux\n", ctlrno, *ctlr->addr);
return;
}
if(aux & 0x02)
print("scsi%d: parity error (ignored)\n", ctlrno);
if(aux & 0x10)
print("scsi%d: cip #%2.2lux\n", ctlrno, aux);
.
569,570c
while(*ctlr->addr & 0x20) /* Wait for busy to clear */
;
.
566d
563,564c
Target *tp;
uchar aux, status, sid, phase, x;
.
560,561c
static void
scsiprocessint(int ctlrno, Target *ctlr)
.
541a
*dev->addr = Rtchi;
*dev->data = 0;
*dev->data = 0;
*dev->data = 0;
.
530c
*tp->dmafls = 0;
.
502,505c
case 0x20: /* transfer info paused */
issue(dev, Cnack);
.
492,493c
/*
* The target went to message-out phase, so send
* it a NOP to keep it happy.
* There seems to be no reason for this delay, other than
* that we just end up busy without an interrupt if it
* isn't there.
* I wish I understood this.
*/
delay(10);
*dev->addr = Rstatus;
n = *dev->data;
USED(n);
*dev->addr = Rtchi;
*dev->data = 0x00;
*dev->data = 0x00;
*dev->data = 1;
issue(dev, Ctinfo);
.
466,467c
issue(dev, Ctinfo);
.
424,425c
issue(dev, Ctinfo);
.
407,409c
/*
* This is what WD calls an 'extended interrupt',
* the next interrupt (0x8E) is already in the
* pipe, we don't have to do anything.
*/
.
367,369c
else
ctlr->flags &= ~Fbusy;
.
365c
if(ctlr->active)
.
338c
*tp->dmafls = 0;
.
267c
unlock(&ctlr->regs);
.
249c
lock(&ctlr->regs);
.
243a
tp->lun = p->lun;
.
203,204c
issue(dev, CselectATN);
.
168,169c
issue(dev, tp->transfer);
.
117a
static void
issue(Target *ctlr, uchar cmd)
{
while(*ctlr->addr & Cip)
;
*ctlr->addr = Rcmd;
*ctlr->data = cmd;
}
.
62a
Lock regs;
.
36a
Cip = 0x10, /* command in progress */
.
## diffname power/scsi.c 1994/0513 # deleted
## diff -e /n/bootesdump/1992/1217/sys/src/9/power/scsi.c /n/fornaxdump/1994/0513/sys/src/brazil/power/scsi.c
1,838d
|