summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorgibbs <gibbs@FreeBSD.org>1996-06-23 20:02:37 +0000
committergibbs <gibbs@FreeBSD.org>1996-06-23 20:02:37 +0000
commit9cec97d94271cfa3deaa3d8a79044db0339de0dd (patch)
treeddf9f991a4734df40ca5c98e57bb98e24afeb712 /sys
parentf4993d64b784a15f62d1d2516203cf83ce15dd9e (diff)
downloadFreeBSD-src-9cec97d94271cfa3deaa3d8a79044db0339de0dd.zip
FreeBSD-src-9cec97d94271cfa3deaa3d8a79044db0339de0dd.tar.gz
Fix problem with scb flag handing that crept in with the SCB paging support.
This only affected userland initiated device resets (using the reset command from cdplay for instance). Convert some spaces to tabs.
Diffstat (limited to 'sys')
-rw-r--r--sys/i386/scsi/aic7xxx.c117
1 files changed, 59 insertions, 58 deletions
diff --git a/sys/i386/scsi/aic7xxx.c b/sys/i386/scsi/aic7xxx.c
index ead323b..45ad793 100644
--- a/sys/i386/scsi/aic7xxx.c
+++ b/sys/i386/scsi/aic7xxx.c
@@ -2,7 +2,7 @@
* Generic driver for the aic7xxx based adaptec SCSI controllers
* Product specific probe and attach routines can be found in:
* i386/eisa/aic7770.c 27/284X and aic7770 motherboard controllers
- * pci/aic7870.c 3940, 2940, aic7870 and aic7850 controllers
+ * pci/aic7870.c 3940, 2940, aic7880, aic7870 and aic7850 controllers
*
* Copyright (c) 1994, 1995, 1996 Justin T. Gibbs.
* All rights reserved.
@@ -31,7 +31,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: aic7xxx.c,v 1.73 1996/06/08 06:55:01 gibbs Exp $
+ * $Id: aic7xxx.c,v 1.74 1996/06/09 17:29:35 gibbs Exp $
*/
/*
* TODO:
@@ -537,11 +537,11 @@ ahc_scsirate(ahc, scsirate, period, offset, channel, target )
continue;
}
*scsirate = (ahc_syncrates[i].sxfr) | (offset & 0x0f);
+
/*
* Ensure Ultra mode is set properly for
* this target.
*/
-
ultra_enb_addr = ULTRA_ENB;
if(channel == 'B' || target > 7)
ultra_enb_addr++;
@@ -792,7 +792,7 @@ ahc_run_waiting_queues(ahc)
ahc_send_scb(ahc, scb);
/* Mark this as an active command */
- scb->flags = SCB_ACTIVE;
+ scb->flags ^= SCB_ASSIGNEDQ|SCB_ACTIVE;
AHC_OUTB(ahc, QINFIFO, scb->position);
if (!(scb->xs->flags & SCSI_NOMASK)) {
@@ -815,8 +815,7 @@ ahc_run_waiting_queues(ahc)
break;
/*
- * Advance disc_scb to the next on in the
- * list.
+ * Check the next SCB on in the list.
*/
AHC_OUTB(ahc, SCBPTR, disc_scb);
next_scb = AHC_INB(ahc, SCB_NEXT);
@@ -852,7 +851,7 @@ ahc_run_waiting_queues(ahc)
ahc_page_scb(ahc, out_scbp, scb);
/* Mark this as an active command */
- scb->flags = SCB_ACTIVE;
+ scb->flags ^= SCB_WAITINGQ|SCB_ACTIVE;
/* Queue the command */
AHC_OUTB(ahc, QINFIFO, scb->position);
@@ -1019,11 +1018,12 @@ ahc_intr(arg)
outscb = ahc->assigned_scbs.stqh_first;
STAILQ_REMOVE_HEAD(&ahc->assigned_scbs,
links);
+ outscb->flags ^= SCB_ASSIGNEDQ
+ |SCB_WAITINGQ;
scb->position = outscb->position;
outscb->position = SCB_LIST_NULL;
STAILQ_INSERT_HEAD(&ahc->waiting_scbs,
outscb, links);
- outscb->flags = SCB_WAITINGQ;
AHC_OUTB(ahc, SCBPTR, scb->position);
ahc_send_scb(ahc, scb);
scb->flags &= ~SCB_PAGED_OUT;
@@ -1110,7 +1110,7 @@ ahc_intr(arg)
outscb->position = SCB_LIST_NULL;
STAILQ_INSERT_HEAD(&ahc->waiting_scbs,
outscb, links);
- outscb->flags = SCB_WAITINGQ;
+ outscb->flags |= SCB_WAITINGQ;
ahc_send_scb(ahc, scb);
scb->flags &= ~SCB_PAGED_OUT;
}
@@ -1506,7 +1506,7 @@ pagein_done:
*/
sc_print_addr(xs->sc_link);
printf("Queue Full\n");
- scb->flags = SCB_ASSIGNEDQ;
+ scb->flags |= SCB_ASSIGNEDQ;
STAILQ_INSERT_TAIL(&ahc->assigned_scbs,
scb, links);
break;
@@ -2289,49 +2289,49 @@ static int32_t
ahc_scsi_cmd(xs)
struct scsi_xfer *xs;
{
- struct scb *scb;
- struct ahc_dma_seg *sg;
- int seg; /* scatter gather seg being worked on */
- int thiskv;
- physaddr thisphys, nextphys;
- int bytes_this_seg, bytes_this_page, datalen, flags;
- struct ahc_data *ahc;
+ struct scb *scb;
+ struct ahc_dma_seg *sg;
+ int seg; /* scatter gather seg being worked on */
+ int thiskv;
+ physaddr thisphys, nextphys;
+ int bytes_this_seg, bytes_this_page, datalen, flags;
+ struct ahc_data *ahc;
u_short mask;
- int s;
+ int s;
ahc = (struct ahc_data *)xs->sc_link->adapter_softc;
- mask = (0x01 << (xs->sc_link->target
+ mask = (0x01 << (xs->sc_link->target
#if defined(__FreeBSD__)
| ((u_long)xs->sc_link->fordriver & 0x08)));
#elif defined(__NetBSD__)
| (IS_SCSIBUS_B(ahc, xs->sc_link) ? SELBUSB : 0) ));
#endif
- SC_DEBUG(xs->sc_link, SDEV_DB2, ("ahc_scsi_cmd\n"));
- /*
- * get an scb to use. If the transfer
- * is from a buf (possibly from interrupt time)
- * then we can't allow it to sleep
- */
- flags = xs->flags;
- if (flags & ITSDONE) {
- printf("%s: Already done?", ahc_name(ahc));
- xs->flags &= ~ITSDONE;
- }
- if (!(flags & INUSE)) {
- printf("%s: Not in use?", ahc_name(ahc));
- xs->flags |= INUSE;
- }
- if (!(scb = ahc_get_scb(ahc, flags))) {
- xs->error = XS_DRIVER_STUFFUP;
- return (TRY_AGAIN_LATER);
- }
- SC_DEBUG(xs->sc_link, SDEV_DB3, ("start scb(%p)\n", scb));
- scb->xs = xs;
- if (flags & SCSI_RESET)
+ SC_DEBUG(xs->sc_link, SDEV_DB2, ("ahc_scsi_cmd\n"));
+ /*
+ * get an scb to use. If the transfer
+ * is from a buf (possibly from interrupt time)
+ * then we can't allow it to sleep
+ */
+ flags = xs->flags;
+ if (flags & ITSDONE) {
+ printf("%s: Already done?", ahc_name(ahc));
+ xs->flags &= ~ITSDONE;
+ }
+ if (!(flags & INUSE)) {
+ printf("%s: Not in use?", ahc_name(ahc));
+ xs->flags |= INUSE;
+ }
+ if (!(scb = ahc_get_scb(ahc, flags))) {
+ xs->error = XS_DRIVER_STUFFUP;
+ return (TRY_AGAIN_LATER);
+ }
+ SC_DEBUG(xs->sc_link, SDEV_DB3, ("start scb(%p)\n", scb));
+ scb->xs = xs;
+ if (flags & SCSI_RESET)
scb->flags |= SCB_DEVICE_RESET|SCB_IMMED;
- /*
- * Put all the arguments for the xfer in the scb
- */
+ /*
+ * Put all the arguments for the xfer in the scb
+ */
if(ahc->tagenable & mask) {
scb->control |= TAG_ENB;
@@ -2464,7 +2464,7 @@ ahc_scsi_cmd(xs)
AHC_OUTB(ahc, SCBPTR, curscb);
AHC_OUTB(ahc, QINFIFO, scb->position);
UNPAUSE_SEQUENCER(ahc);
- scb->flags = SCB_ACTIVE;
+ scb->flags |= SCB_ACTIVE;
if (!(flags & SCSI_NOMASK)) {
timeout(ahc_timeout, (caddr_t)scb,
(xs->timeout * hz) / 1000);
@@ -2472,7 +2472,7 @@ ahc_scsi_cmd(xs)
SC_DEBUG(xs->sc_link, SDEV_DB3, ("cmd_sent\n"));
}
else {
- scb->flags = SCB_WAITINGQ;
+ scb->flags |= SCB_WAITINGQ;
STAILQ_INSERT_TAIL(&ahc->waiting_scbs, scb, links);
ahc_run_waiting_queues(ahc);
}
@@ -2512,7 +2512,11 @@ ahc_free_scb(ahc, scb, flags)
opri = splbio();
+ /* Clean up for the next user */
scb->flags = SCB_FREE;
+ scb->control = 0;
+ scb->status = 0;
+
if(scb->position == SCB_LIST_NULL) {
STAILQ_INSERT_HEAD(&ahc->page_scbs, scb, links);
if(!scb->links.stqe_next && !ahc->free_scbs.stqh_first)
@@ -2530,10 +2534,10 @@ ahc_free_scb(ahc, scb, flags)
* or when we start another command.
*/
else if((wscb = ahc->waiting_scbs.stqh_first) != NULL) {
- wscb->position = scb->position;
STAILQ_REMOVE_HEAD(&ahc->waiting_scbs, links);
+ wscb->position = scb->position;
STAILQ_INSERT_HEAD(&ahc->assigned_scbs, wscb, links);
- wscb->flags = SCB_ASSIGNEDQ;
+ wscb->flags ^= SCB_WAITINGQ|SCB_ASSIGNEDQ;
/*
* The "freed" SCB will need to be assigned a slot
@@ -2551,9 +2555,6 @@ ahc_free_scb(ahc, scb, flags)
}
else {
STAILQ_INSERT_HEAD(&ahc->free_scbs, scb, links);
-#ifdef AHC_DEBUG
- ahc->activescbs--;
-#endif
if(!scb->links.stqe_next && !ahc->page_scbs.stqh_first)
/*
* If there were no SCBs availible, wake anybody waiting
@@ -2561,6 +2562,9 @@ ahc_free_scb(ahc, scb, flags)
*/
wakeup((caddr_t)&ahc->free_scbs);
}
+#ifdef AHC_DEBUG
+ ahc->activescbs--;
+#endif
splx(opri);
}
@@ -2590,7 +2594,7 @@ ahc_get_scb(ahc, flags)
else if((scbp = ahc->page_scbs.stqh_first)) {
STAILQ_REMOVE_HEAD(&ahc->page_scbs, links);
}
- else if (ahc->numscbs < ahc->maxscbs) {
+ else if(ahc->numscbs < ahc->maxscbs) {
scbp = (struct scb *) malloc(sizeof(struct scb),
M_TEMP, M_NOWAIT);
if (scbp) {
@@ -2622,17 +2626,14 @@ ahc_get_scb(ahc, flags)
break;
}
- if (scbp) {
- scbp->control = 0;
- scbp->status = 0;
- scbp->flags = 0;
#ifdef AHC_DEBUG
+ if (scbp) {
ahc->activescbs++;
if((ahc_debug & AHC_SHOWSCBCNT)
&& (ahc->activescbs == ahc->maxhscbs))
printf("%s: Max SCBs active\n", ahc_name(ahc));
-#endif
}
+#endif
splx(opri);
@@ -2642,7 +2643,7 @@ ahc_get_scb(ahc, flags)
static void ahc_loadseq(ahc)
struct ahc_data *ahc;
{
- static unsigned char seqprog[] = {
+ static u_char seqprog[] = {
# include "aic7xxx_seq.h"
};
OpenPOWER on IntegriCloud