summaryrefslogtreecommitdiffstats
path: root/sys/i386
diff options
context:
space:
mode:
Diffstat (limited to 'sys/i386')
-rw-r--r--sys/i386/scsi/aic7xxx.c114
1 files changed, 67 insertions, 47 deletions
diff --git a/sys/i386/scsi/aic7xxx.c b/sys/i386/scsi/aic7xxx.c
index 631f60a..cdcbf09 100644
--- a/sys/i386/scsi/aic7xxx.c
+++ b/sys/i386/scsi/aic7xxx.c
@@ -24,7 +24,7 @@
*
* commenced: Sun Sep 27 18:14:01 PDT 1992
*
- * $Id: aic7xxx.c,v 1.15 1995/02/22 01:43:24 gibbs Exp $
+ * $Id: aic7xxx.c,v 1.16 1995/03/07 08:59:28 gibbs Exp $
*/
/*
* TODO:
@@ -78,7 +78,7 @@ int ahc_unit = 0;
#define AHC_SHOWCMDS 0x0002
#define AHC_SHOWSCBS 0x0004
/*#define AHC_DEBUG*/
-int ahc_debug = AHC_SHOWCMDS;
+int ahc_debug = AHC_SHOWMISC;
/**** bit definitions for SCSIDEF ****/
#define HSCSIID 0x07 /* our SCSI ID */
@@ -543,7 +543,7 @@ ahc_print_active_scb(ahc)
int cur_scb_offset;
u_long iobase = ahc->baseport;
PAUSE_SEQUENCER(ahc);
- cur_scb_offset = inb(SCBPTR + port);
+ cur_scb_offset = inb(SCBPTR + iobase);
UNPAUSE_SEQUENCER(ahc);
ahc_print_scb(ahc->scbarray[cur_scb_offset]);
}
@@ -694,6 +694,7 @@ ahc_attach(unit)
ahc->sc_link.adapter_unit = unit;
ahc->sc_link.adapter_targ = ahc->our_id;
ahc->sc_link.adapter = &ahc_switch;
+ ahc->sc_link.opennings = 2;
ahc->sc_link.device = &ahc_dev;
ahc->sc_link.flags = DEBUGLEVEL;
ahc->sc_link.fordriver = 0;
@@ -859,22 +860,27 @@ ahcintr(unit)
/* See if we initiated Sync Negotiation */
if(ahc->sdtrpending & (0x01 << scsi_id))
{
- /*
- * Negate the flag and don't send
- * an SDTR back to the target
+ /*
+ * Don't send an SDTR back to
+ * the target
*/
- ahc->needsdtr &= ~(0x01 << scsi_id);
- ahc->sdtrpending &= ~(0x01 << scsi_id);
-
outb(HA_RETURN_1 + iobase, 0);
}
else{
/*
* Send our own SDTR in reply
*/
- printf("Sending SDTR!!\n");
+#ifdef AHC_DEBUG
+ if(ahc_debug & AHC_SHOWMISC)
+ printf("Sending SDTR!!\n");
+#endif
outb(HA_RETURN_1 + iobase, SEND_SDTR);
}
+ /*
+ * Negate the flags
+ */
+ ahc->needsdtr &= ~(0x01 << scsi_id);
+ ahc->sdtrpending &= ~(0x01 << scsi_id);
break;
}
case MSG_WDTR:
@@ -894,12 +900,9 @@ ahcintr(unit)
if(ahc->wdtrpending & (0x01 << scsi_id))
{
/*
- * Negate the flag and don't
- * send a WDTR back to the
+ * Don't send a WDTR back to the
* target, since we asked first.
*/
- ahc->needwdtr &= ~(0x01 << scsi_id);
- ahc->wdtrpending &= ~(0x01 << scsi_id);
outb(HA_RETURN_1 + iobase, 0);
switch(bus_width)
{
@@ -941,8 +944,10 @@ ahcintr(unit)
outb(HA_RETURN_1 + iobase,
bus_width | SEND_WDTR);
}
+ ahc->needwdtr &= ~(0x01 << scsi_id);
+ ahc->wdtrpending &= ~(0x01 << scsi_id);
outb(HA_TARG_SCRATCH + iobase + scsi_id, scratch);
- outb(SCSIRATE + iobase, scratch);
+ outb(SCSIRATE + iobase, scratch);
break;
}
case MSG_REJECT:
@@ -970,6 +975,7 @@ ahcintr(unit)
/* note 8bit xfers and clear flag */
targ_scratch &= 0x7f;
ahc->needwdtr &= ~mask;
+ ahc->wdtrpending &= ~mask;
printf("ahc%d: target %d refusing "
"WIDE negotiation. Using "
"8bit transfers\n",
@@ -979,16 +985,23 @@ ahcintr(unit)
/* note asynch xfers and clear flag */
targ_scratch &= 0xf0;
ahc->needsdtr &= ~mask;
+ ahc->sdtrpending &= ~mask;
printf("ahc%d: target %d refusing "
"syncronous negotiation. Using "
"asyncronous transfers\n",
unit, scsi_id);
}
- else
+ else {
/*
* Otherwise, we ignore it.
*/
+#ifdef AHC_DEBUG
+ if(ahc_debug & AHC_SHOWMISC)
+ printf("Ignored message "
+ "reject!!\n");
+#endif
break;
+ }
outb(HA_TARG_SCRATCH + iobase + scsi_id,
targ_scratch);
outb(SCSIRATE + iobase, targ_scratch);
@@ -1058,8 +1071,7 @@ ahcintr(unit)
#endif
bzero(scb, SCB_DOWN_SIZE);
scb->flags |= SCB_SENSE;
- scb->control = SCB_NEEDDMA |
- (control & SCB_TE);
+ scb->control = control & SCB_TE;
sc->op_code = REQUEST_SENSE;
sc->byte2 = xs->sc_link->lun << 5;
sc->length = sizeof(struct scsi_sense_data);
@@ -1124,22 +1136,22 @@ ahcintr(unit)
break;
}
clear:
- /*
- * Clear the upper byte that holds SEQINT status
- * codes and clear the SEQINT bit.
- */
- outb(CLRINT + iobase, CLRSEQINT);
-
- /*
- * The sequencer is paused immediately on
- * a SEQINT, so we should restart it when
- * we leave this section.
- */
- UNPAUSE_SEQUENCER(ahc);
+ /*
+ * Clear the upper byte that holds SEQINT status
+ * codes and clear the SEQINT bit.
+ */
+ outb(CLRINT + iobase, CLRSEQINT);
+
+ /*
+ * The sequencer is paused immediately on
+ * a SEQINT, so we should restart it when
+ * we leave this section.
+ */
+ UNPAUSE_SEQUENCER(ahc);
}
- if (intstat & SCSIINT) {
+ if (intstat & SCSIINT) {
int scb_index = inb(SCBPTR + iobase);
status = inb(SSTAT1 + iobase);
@@ -1211,7 +1223,6 @@ clear:
outb(CLRSINT1 + iobase, BUSFREE); /* CLRBUSFREE */
#endif
}
-
else {
printf("ahc%d: Unknown SCSIINT. Status = 0x%x\n",
unit, status);
@@ -1297,6 +1308,9 @@ ahc_done(unit, scb)
printf("ahc%d: target %d Tagged Queuing Device\n",
unit, xs->sc_link->target);
ahc->tagenable |= mask;
+#ifdef QUEUE_FULL_SUPPORTED
+ xs->sc_link->opennings += 2; */
+#endif
}
}
ahc_free_scb(unit, scb, xs->flags);
@@ -1312,7 +1326,7 @@ ahc_init(unit)
{
struct ahc_data *ahc = ahcdata[unit];
u_long iobase = ahc->baseport;
- u_char scsi_conf;
+ u_char scsi_conf, sblkctl;
int intdef, i;
/*
@@ -1354,21 +1368,18 @@ ahc_init(unit)
};
/* Determine channel configuration and who we are on the scsi bus. */
- switch ( inb(SBLKCTL + iobase) ) {
+ switch ( (sblkctl = inb(SBLKCTL + iobase) & 0x0f) ) {
case 0:
- case 0xc0: /* 294x Adaptors have the top two bits set */
ahc->our_id = (inb(HA_SCSICONF + iobase) & HSCSIID);
printf("Single Channel, SCSI Id=%d, ", ahc->our_id);
break;
case 2:
- case 0xc2:
ahc->our_id = (inb(HA_SCSICONF + 1 + iobase) & HWSCSIID);
printf("Wide Channel, SCSI Id=%d, ", ahc->our_id);
ahc->type |= AHC_WIDE;
outb(HA_FLAGS + iobase, WIDE_BUS);
break;
case 8:
- case 0xc8:
ahc->our_id = (inb(HA_SCSICONF + iobase) & HSCSIID);
ahc->our_id_b = (inb(HA_SCSICONF + 1 + iobase) & HSCSIID);
printf("Twin Channel, A SCSI Id=%d, B SCSI Id=%d, ",
@@ -1380,7 +1391,10 @@ ahc_init(unit)
printf(" Unsupported adapter type. Ignoring\n");
return(-1);
}
-
+ /*
+ * Take the bus led out of diagnostic mode
+ */
+ outb(SBLKCTL + iobase, sblkctl);
/*
* Number of SCBs that will be used. Rev E aic7770s and
* aic7870s have 16. The rest have 4.
@@ -1393,7 +1407,7 @@ ahc_init(unit)
* Anything below a Rev E will have a
* R/O autoflush diable configuration bit.
*/
- u_char sblkctl, sblkctl_orig;
+ u_char sblkctl_orig;
sblkctl_orig = inb(SBLKCTL + iobase);
sblkctl = sblkctl_orig ^ AUTOFLUSHDIS;
outb(SBLKCTL + iobase, sblkctl);
@@ -1415,9 +1429,9 @@ ahc_init(unit)
printf("aic7870, ");
printf("%d SCBs\n", ahc->maxscbs);
if(!(ahc->type & AHC_294)){
- /* The 294x cards are PCI, so we get their interrupt from the PCI
- * BIOS. It doesn't look like the ISA mapped interrupt is reported
- * correctly this way either.
+ /*
+ * The 294x cards are PCI, so we get their interrupt from the PCI
+ * BIOS.
*/
intdef = inb(INTDEF + iobase);
@@ -1508,6 +1522,11 @@ ahc_init(unit)
ahc->sdtrpending = 0;
ahc->wdtrpending = 0;
ahc->tagenable = 0;
+
+#ifdef AHC_DEBUG
+ printf("NEEDSDTR == 0x%x\nNEEDWDTR == 0x%x\n", ahc->needsdtr,
+ ahc->needwdtr);
+#endif
/*
* Set the number of availible SCBs
*/
@@ -1533,7 +1552,7 @@ ahc_init(unit)
/* Reset the bus */
outb(SCSISEQ + iobase, SCSIRSTO);
- DELAY(500);
+ DELAY(1000);
outb(SCSISEQ + iobase, 0);
UNPAUSE_SEQUENCER(ahc);
@@ -1615,7 +1634,6 @@ ahc_scsi_cmd(xs)
}
SC_DEBUG(xs->sc_link, SDEV_DB3, ("start scb(%x)\n", scb));
scb->xs = xs;
-
if (flags & SCSI_RESET) {
/* XXX: Needs Implementation */
printf("ahc0: SCSI_RESET called.\n");
@@ -1901,9 +1919,9 @@ ahc_poll(int unit, int wait)
u_long stport = INTSTAT + iobase;
while (--wait) {
+ DELAY(10000);
if (inb(stport) & INT_PEND)
break;
- DELAY(1000);
} if (wait == 0) {
printf("ahc%d: board not responding\n", unit);
return (EIO);
@@ -1996,7 +2014,7 @@ ahc_abort_scb( unit, ahc, scb )
/* Reset the bus */
outb(SCSISEQ + iobase, SCSIRSTO);
- DELAY(100);
+ DELAY(1000);
outb(SCSISEQ + iobase, 0);
goto done;
}
@@ -2034,9 +2052,11 @@ ahc_timeout(void *arg1)
,scb->xs->sc_link->device->name
,scb->xs->sc_link->dev_unit);
#ifdef AHC_DEBUG
+#ifdef SCSIDEBUG
if (ahc_debug & AHC_SHOWCMDS) {
- show_scsi_cmd(ecb->xs);
+ show_scsi_cmd(scb->xs);
}
+#endif
if (ahc_debug & AHC_SHOWSCBS)
ahc_print_active_scb(unit);
#endif /*AHC_DEBUG */
OpenPOWER on IntegriCloud