Merge tag 'omap-for-v5.1/fixes-signed' of git://git.kernel.org/pub/scm/linux/kernel...
[sfrench/cifs-2.6.git] / drivers / scsi / dpt_i2o.c
index 70d1a18278aff984d8e620cb72fb24f909b4fca1..abdc34affdf678e2d0736251b8e0c8d5464f275b 100644 (file)
@@ -588,46 +588,6 @@ static int adpt_show_info(struct seq_file *m, struct Scsi_Host *host)
        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'
  */
@@ -685,9 +645,6 @@ static int adpt_abort(struct scsi_cmnd * cmd)
        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) {
@@ -699,8 +656,9 @@ static int adpt_abort(struct scsi_cmnd * cmd)
        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);
@@ -2198,20 +2156,27 @@ static irqreturn_t adpt_isr(int irq, void *dev_id)
                                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);
@@ -2277,7 +2242,8 @@ static s32 adpt_scsi_to_i2o(adpt_hba* pHba, struct scsi_cmnd* cmd, struct adpt_d
        // 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);
@@ -2693,9 +2659,6 @@ static void adpt_fail_posted_scbs(adpt_hba* pHba)
                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);
                }