aboutsummaryrefslogtreecommitdiff
path: root/drivers/scsi/aacraid/commsup.c
diff options
context:
space:
mode:
authorMark Haverkamp <markh@osdl.org>2005-08-03 15:38:51 -0700
committerJames Bottomley <jejb@mulgrave.(none)>2005-08-05 16:49:46 -0500
commitbed30de47b034b5f28fb7db2fae4860b9d9c0622 (patch)
tree1dd29e4f8ae3122d8cc642523a6f0cd2ca70bfd3 /drivers/scsi/aacraid/commsup.c
parentfc789a93994858b5e5a46afb96d0dcf6cc1b6f08 (diff)
[SCSI] aacraid: interupt mitigation
Received from Mark Salyzyn from Adaptec: If more than two commands are outstanding to the controller, there is no need to notify the adapter via a PCI bus transaction of additional commands added into the queue; it will get to them when it works through the produce/consumer indexes. This reduced the PCI traffic in the driver to submit a command to the queue to near zero allowing a significant number of commands to be turned around with no need to block for the PCI bridge to flush the notify request to the adapter. Interrupt mitigation has always been present in the driver; it was turned off because of a bug that prevented one from realizing the usefulness of the feature. This bug is fixed in this patch. Signed-off-by: Mark Haverkamp <markh@osdl.org> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/aacraid/commsup.c')
-rw-r--r--drivers/scsi/aacraid/commsup.c20
1 files changed, 17 insertions, 3 deletions
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
index 5322865942e..a1d303f0348 100644
--- a/drivers/scsi/aacraid/commsup.c
+++ b/drivers/scsi/aacraid/commsup.c
@@ -254,6 +254,7 @@ static void fib_dealloc(struct fib * fibptr)
static int aac_get_entry (struct aac_dev * dev, u32 qid, struct aac_entry **entry, u32 * index, unsigned long *nonotify)
{
struct aac_queue * q;
+ unsigned long idx;
/*
* All of the queues wrap when they reach the end, so we check
@@ -263,10 +264,23 @@ static int aac_get_entry (struct aac_dev * dev, u32 qid, struct aac_entry **entr
*/
q = &dev->queues->queue[qid];
-
- *index = le32_to_cpu(*(q->headers.producer));
- if ((*index - 2) == le32_to_cpu(*(q->headers.consumer)))
+
+ idx = *index = le32_to_cpu(*(q->headers.producer));
+ /* Interrupt Moderation, only interrupt for first two entries */
+ if (idx != le32_to_cpu(*(q->headers.consumer))) {
+ if (--idx == 0) {
+ if (qid == AdapHighCmdQueue)
+ idx = ADAP_HIGH_CMD_ENTRIES;
+ else if (qid == AdapNormCmdQueue)
+ idx = ADAP_NORM_CMD_ENTRIES;
+ else if (qid == AdapHighRespQueue)
+ idx = ADAP_HIGH_RESP_ENTRIES;
+ else if (qid == AdapNormRespQueue)
+ idx = ADAP_NORM_RESP_ENTRIES;
+ }
+ if (idx != le32_to_cpu(*(q->headers.consumer)))
*nonotify = 1;
+ }
if (qid == AdapHighCmdQueue) {
if (*index >= ADAP_HIGH_CMD_ENTRIES)