diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index 07def72610044a1f731d10b12338f0d4c95352c7..85b85ae198f46755c7c95eadd8df20f91ccbcc60 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/drivers/scsi/aacraid/aacraid.h @@ -1073,6 +1073,7 @@ struct aac_dev (dev)->a_ops.adapter_comm(dev, comm) #define FIB_CONTEXT_FLAG_TIMED_OUT (0x00000001) +#define FIB_CONTEXT_FLAG (0x00000002) /* * Define the command values diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index e82d89ccaf15fbe781b864b99a494f98fc3ca405..3a3017d8dc65d1ad396817fff79fc53f78e67d23 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c @@ -171,6 +171,7 @@ struct fib *aac_fib_alloc(struct aac_dev *dev) * each I/O */ fibptr->hw_fib_va->header.XferState = 0; + fibptr->flags = 0; fibptr->callback = NULL; fibptr->callback_data = NULL; @@ -402,6 +403,7 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size, * will have a debug mode where the adapter can notify the host * it had a problem and the host can log that fact. */ + fibptr->flags = 0; if (wait && !reply) { return -EINVAL; } else if (!wait && reply) { @@ -450,10 +452,10 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size, if (!wait) { fibptr->callback = callback; fibptr->callback_data = callback_data; + fibptr->flags = FIB_CONTEXT_FLAG; } fibptr->done = 0; - fibptr->flags = 0; FIB_COUNTER_INCREMENT(aac_config.FibsSent); diff --git a/drivers/scsi/aacraid/dpcsup.c b/drivers/scsi/aacraid/dpcsup.c index 4726ab666c520e897fe2ede75b3c5c3a75f34939..d1163ded132bd2ab395d396a89d206e612df4bd9 100644 --- a/drivers/scsi/aacraid/dpcsup.c +++ b/drivers/scsi/aacraid/dpcsup.c @@ -120,6 +120,7 @@ unsigned int aac_response_normal(struct aac_queue * q) * NOTE: we cannot touch the fib after this * call, because it may have been deallocated. */ + fib->flags = 0; fib->callback(fib->callback_data, fib); } else { unsigned long flagv; @@ -229,7 +230,7 @@ unsigned int aac_command_normal(struct aac_queue *q) * all QE there are and wake up all the waiters before exiting. */ -unsigned int aac_intr_normal(struct aac_dev *dev, u32 index) +unsigned int aac_intr_normal(struct aac_dev * dev, u32 index) { dprintk((KERN_INFO "aac_intr_normal(%p,%x)\n", dev, index)); if ((index & 0x00000002L)) { @@ -313,6 +314,7 @@ unsigned int aac_intr_normal(struct aac_dev *dev, u32 index) * NOTE: we cannot touch the fib after this * call, because it may have been deallocated. */ + fib->flags = 0; fib->callback(fib->callback_data, fib); } else { unsigned long flagv; diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c index 742e1a8edc60a5035549aa6cd081824f0f0a233a..6a553ea730db7dfee18e42044276cf1db13dfc2f 100644 --- a/drivers/scsi/aacraid/linit.c +++ b/drivers/scsi/aacraid/linit.c @@ -536,17 +536,33 @@ static int aac_eh_abort(struct scsi_cmnd* cmd) break; case INQUIRY: case READ_CAPACITY: - case TEST_UNIT_READY: /* Mark associated FIB to not complete, eh handler does this */ for (count = 0; count < (host->can_queue + AAC_NUM_MGT_FIB); ++count) { struct fib * fib = &aac->fibs[count]; if (fib->hw_fib_va->header.XferState && + (fib->flags & FIB_CONTEXT_FLAG) && (fib->callback_data == cmd)) { fib->flags |= FIB_CONTEXT_FLAG_TIMED_OUT; cmd->SCp.phase = AAC_OWNER_ERROR_HANDLER; ret = SUCCESS; } } + break; + case TEST_UNIT_READY: + /* Mark associated FIB to not complete, eh handler does this */ + for (count = 0; count < (host->can_queue + AAC_NUM_MGT_FIB); ++count) { + struct scsi_cmnd * command; + struct fib * fib = &aac->fibs[count]; + if ((fib->hw_fib_va->header.XferState & cpu_to_le32(Async | NoResponseExpected)) && + (fib->flags & FIB_CONTEXT_FLAG) && + ((command = fib->callback_data)) && + (command->device == cmd->device)) { + fib->flags |= FIB_CONTEXT_FLAG_TIMED_OUT; + command->SCp.phase = AAC_OWNER_ERROR_HANDLER; + if (command == cmd) + ret = SUCCESS; + } + } } return ret; } @@ -569,6 +585,7 @@ static int aac_eh_reset(struct scsi_cmnd* cmd) for (count = 0; count < (host->can_queue + AAC_NUM_MGT_FIB); ++count) { struct fib * fib = &aac->fibs[count]; if (fib->hw_fib_va->header.XferState && + (fib->flags & FIB_CONTEXT_FLAG) && (fib->callback_data == cmd)) { fib->flags |= FIB_CONTEXT_FLAG_TIMED_OUT; cmd->SCp.phase = AAC_OWNER_ERROR_HANDLER;