patch-2.4.5 linux/drivers/scsi/aic7xxx/aic7xxx_inline.h
Next file: linux/drivers/scsi/aic7xxx/aic7xxx_linux.c
Previous file: linux/drivers/scsi/aic7xxx/aic7xxx.seq
Back to the patch index
Back to the overall index
- Lines: 156
- Date:
Fri May 4 15:16:28 2001
- Orig file:
v2.4.4/linux/drivers/scsi/aic7xxx/aic7xxx_inline.h
- Orig date:
Sun Mar 4 14:30:18 2001
diff -u --recursive --new-file v2.4.4/linux/drivers/scsi/aic7xxx/aic7xxx_inline.h linux/drivers/scsi/aic7xxx/aic7xxx_inline.h
@@ -28,7 +28,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: //depot/src/aic7xxx/aic7xxx_inline.h#15 $
+ * $Id: //depot/src/aic7xxx/aic7xxx_inline.h#21 $
*
* $FreeBSD: src/sys/dev/aic7xxx/aic7xxx_inline.h,v 1.8 2000/11/12 05:19:46 gibbs Exp $
*/
@@ -37,10 +37,10 @@
#define _AIC7XXX_INLINE_H_
/************************* Sequencer Execution Control ************************/
-static __inline int sequencer_paused(struct ahc_softc *ahc);
+static __inline int ahc_is_paused(struct ahc_softc *ahc);
static __inline void ahc_pause_bug_fix(struct ahc_softc *ahc);
-static __inline void pause_sequencer(struct ahc_softc *ahc);
-static __inline void unpause_sequencer(struct ahc_softc *ahc);
+static __inline void ahc_pause(struct ahc_softc *ahc);
+static __inline void ahc_unpause(struct ahc_softc *ahc);
/*
* Work around any chip bugs related to halting sequencer execution.
@@ -62,7 +62,7 @@
* Returns non-zero status if the sequencer is stopped.
*/
static __inline int
-sequencer_paused(struct ahc_softc *ahc)
+ahc_is_paused(struct ahc_softc *ahc)
{
return ((ahc_inb(ahc, HCNTRL) & PAUSE) != 0);
}
@@ -75,7 +75,7 @@
* for critical sections.
*/
static __inline void
-pause_sequencer(struct ahc_softc *ahc)
+ahc_pause(struct ahc_softc *ahc)
{
ahc_outb(ahc, HCNTRL, ahc->pause);
@@ -83,7 +83,7 @@
* Since the sequencer can disable pausing in a critical section, we
* must loop until it actually stops.
*/
- while (sequencer_paused(ahc) == 0)
+ while (ahc_is_paused(ahc) == 0)
;
ahc_pause_bug_fix(ahc);
@@ -100,7 +100,7 @@
* condition.
*/
static __inline void
-unpause_sequencer(struct ahc_softc *ahc)
+ahc_unpause(struct ahc_softc *ahc)
{
if ((ahc_inb(ahc, INTSTAT) & (SCSIINT | SEQINT | BRKADRINT)) == 0)
ahc_outb(ahc, HCNTRL, ahc->unpause);
@@ -188,12 +188,12 @@
/*********************** Miscelaneous Support Functions ***********************/
-static __inline int ahc_check_residual(struct scb *scb);
+static __inline void ahc_update_residual(struct scb *scb);
static __inline struct ahc_initiator_tinfo *
ahc_fetch_transinfo(struct ahc_softc *ahc,
char channel, u_int our_id,
u_int remote_id,
- struct tmode_tstate **tstate);
+ struct ahc_tmode_tstate **tstate);
static __inline struct scb*
ahc_get_scb(struct ahc_softc *ahc);
static __inline void ahc_free_scb(struct ahc_softc *ahc, struct scb *scb);
@@ -211,15 +211,16 @@
* Determine whether the sequencer reported a residual
* for this SCB/transaction.
*/
-static __inline int
-ahc_check_residual(struct scb *scb)
+static __inline void
+ahc_update_residual(struct scb *scb)
{
- struct status_pkt *sp;
+ uint32_t sgptr;
- sp = &scb->hscb->shared_data.status;
- if ((scb->hscb->sgptr & SG_RESID_VALID) != 0)
- return (1);
- return (0);
+ sgptr = ahc_le32toh(scb->hscb->sgptr);
+ if ((sgptr & SG_RESID_VALID) != 0)
+ ahc_calc_residual(scb);
+ else
+ ahc_set_residual(scb, 0);
}
/*
@@ -228,7 +229,7 @@
*/
static __inline struct ahc_initiator_tinfo *
ahc_fetch_transinfo(struct ahc_softc *ahc, char channel, u_int our_id,
- u_int remote_id, struct tmode_tstate **tstate)
+ u_int remote_id, struct ahc_tmode_tstate **tstate)
{
/*
* Transfer data structures are stored from the perspective
@@ -345,10 +346,10 @@
ahc_outb(ahc, HNSCB_QOFF, ahc->qinfifonext);
} else {
if ((ahc->features & AHC_AUTOPAUSE) == 0)
- pause_sequencer(ahc);
+ ahc_pause(ahc);
ahc_outb(ahc, KERNEL_QINPOS, ahc->qinfifonext);
if ((ahc->features & AHC_AUTOPAUSE) == 0)
- unpause_sequencer(ahc);
+ ahc_unpause(ahc);
}
}
@@ -412,19 +413,28 @@
* completion queues. This avoids a costly PCI bus read in
* most cases.
*/
- intstat = 0;
- if ((queuestat = ahc_check_cmdcmpltqueues(ahc)) != 0)
+ if ((ahc->flags & (AHC_ALL_INTERRUPTS|AHC_EDGE_INTERRUPT)) == 0
+ && (queuestat = ahc_check_cmdcmpltqueues(ahc)) != 0)
intstat = CMDCMPLT;
-
- if ((intstat & INT_PEND) == 0
- || (ahc->flags & AHC_ALL_INTERRUPTS) != 0) {
-
+ else {
intstat = ahc_inb(ahc, INTSTAT);
+ /*
+ * We can't generate queuestat once above
+ * or we are exposed to a race when our
+ * interrupt is shared with another device.
+ * if instat showed a command complete interrupt,
+ * but our first generation of queue stat
+ * "just missed" the delivery of this transaction,
+ * we would clear the command complete interrupt
+ * below without ever servicing the completed
+ * command.
+ */
+ queuestat = ahc_check_cmdcmpltqueues(ahc);
#if AHC_PCI_CONFIG > 0
if (ahc->unsolicited_ints > 500
&& (ahc->chip & AHC_PCI) != 0
&& (ahc_inb(ahc, ERROR) & PCIERRSTAT) != 0)
- ahc_pci_intr(ahc);
+ ahc->bus_intr(ahc);
#endif
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)