return 0;
}
-/*
- * Turn a struct scsi_cmnd * into a unique 32 bit 'context'.
- */
-static u32 adpt_cmd_to_context(struct scsi_cmnd *cmd)
-{
- return (u32)cmd->serial_number;
-}
-
-/*
- * Go from a u32 'context' to a struct scsi_cmnd * .
- * This could probably be made more efficient.
- */
-static struct scsi_cmnd *
- adpt_cmd_from_context(adpt_hba * pHba, u32 context)
-{
- struct scsi_cmnd * cmd;
- struct scsi_device * d;
-
- if (context == 0)
- return NULL;
-
- spin_unlock(pHba->host->host_lock);
- shost_for_each_device(d, pHba->host) {
- unsigned long flags;
- spin_lock_irqsave(&d->list_lock, flags);
- list_for_each_entry(cmd, &d->cmd_list, list) {
- if (((u32)cmd->serial_number == context)) {
- spin_unlock_irqrestore(&d->list_lock, flags);
- scsi_device_put(d);
- spin_lock(pHba->host->host_lock);
- return cmd;
- }
- }
- spin_unlock_irqrestore(&d->list_lock, flags);
- }
- spin_lock(pHba->host->host_lock);
-
- return NULL;
-}
-
/*
* Turn a pointer to ioctl reply data into an u32 'context'
*/
u32 msg[5];
int rcode;
- if(cmd->serial_number == 0){
- return FAILED;
- }
pHba = (adpt_hba*) cmd->device->host->hostdata[0];
printk(KERN_INFO"%s: Trying to Abort\n",pHba->name);
if ((dptdevice = (void*) (cmd->device->hostdata)) == NULL) {
msg[0] = FIVE_WORD_MSG_SIZE|SGL_OFFSET_0;
msg[1] = I2O_CMD_SCSI_ABORT<<24|HOST_TID<<12|dptdevice->tid;
msg[2] = 0;
- msg[3]= 0;
- msg[4] = adpt_cmd_to_context(cmd);
+ msg[3]= 0;
+ /* Add 1 to avoid firmware treating it as invalid command */
+ msg[4] = cmd->request->tag + 1;
if (pHba->host)
spin_lock_irq(pHba->host->host_lock);
rcode = adpt_i2o_post_wait(pHba, msg, sizeof(msg), FOREVER);
status = I2O_POST_WAIT_OK;
}
if(!(context & 0x40000000)) {
- cmd = adpt_cmd_from_context(pHba,
- readl(reply+12));
+ /*
+ * The request tag is one less than the command tag
+ * as the firmware might treat a 0 tag as invalid
+ */
+ cmd = scsi_host_find_tag(pHba->host,
+ readl(reply + 12) - 1);
if(cmd != NULL) {
printk(KERN_WARNING"%s: Apparent SCSI cmd in Post Wait Context - cmd=%p context=%x\n", pHba->name, cmd, context);
}
}
adpt_i2o_post_wait_complete(context, status);
} else { // SCSI message
- cmd = adpt_cmd_from_context (pHba, readl(reply+12));
+ /*
+ * The request tag is one less than the command tag
+ * as the firmware might treat a 0 tag as invalid
+ */
+ cmd = scsi_host_find_tag(pHba->host,
+ readl(reply + 12) - 1);
if(cmd != NULL){
scsi_dma_unmap(cmd);
- if(cmd->serial_number != 0) { // If not timedout
- adpt_i2o_to_scsi(reply, cmd);
- }
+ adpt_i2o_to_scsi(reply, cmd);
}
}
writel(m, pHba->reply_port);
// I2O_CMD_SCSI_EXEC
msg[1] = ((0xff<<24)|(HOST_TID<<12)|d->tid);
msg[2] = 0;
- msg[3] = adpt_cmd_to_context(cmd); /* Want SCSI control block back */
+ /* Add 1 to avoid firmware treating it as invalid command */
+ msg[3] = cmd->request->tag + 1;
// Our cards use the transaction context as the tag for queueing
// Adaptec/DPT Private stuff
msg[4] = I2O_CMD_SCSI_EXEC|(DPT_ORGANIZATION_ID<<16);
unsigned long flags;
spin_lock_irqsave(&d->list_lock, flags);
list_for_each_entry(cmd, &d->cmd_list, list) {
- if(cmd->serial_number == 0){
- continue;
- }
cmd->result = (DID_OK << 16) | (QUEUE_FULL <<1);
cmd->scsi_done(cmd);
}