[SCSI] lpfc: Fix for "command completion for iotax x?? not found"

From: James Smart <James.Smart@emulex.com>

There were scenarios where the error handlers could reuse an iotag
value of an active io.  Remove all possibility of this by
pre-assigning iotag resources to command resources.

Signed-off-by: James Smart <James.Smart@emulex.com>

Rejections fixed up and
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index 63caf7f..e931ae6 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -122,7 +122,6 @@
 
 	if (elsiocb == NULL)
 		return NULL;
-	memset(elsiocb, 0, sizeof (struct lpfc_iocbq));
 	icmd = &elsiocb->iocb;
 
 	/* fill in BDEs for command */
@@ -133,7 +132,9 @@
 		if (pcmd)
 			kfree(pcmd);
 
-		list_add_tail(&elsiocb->list, lpfc_iocb_list);
+		spin_lock_irq(phba->host->host_lock);
+		lpfc_sli_release_iocbq(phba, elsiocb);
+		spin_unlock_irq(phba->host->host_lock);
 		return NULL;
 	}
 
@@ -150,7 +151,9 @@
 				kfree(prsp);
 			lpfc_mbuf_free(phba, pcmd->virt, pcmd->phys);
 			kfree(pcmd);
-			list_add_tail(&elsiocb->list, lpfc_iocb_list);
+			spin_lock_irq(phba->host->host_lock);
+			lpfc_sli_release_iocbq(phba, elsiocb);
+			spin_unlock_irq(phba->host->host_lock);
 			return NULL;
 		}
 		INIT_LIST_HEAD(&prsp->list);
@@ -164,7 +167,9 @@
 	    pbuflist->virt = lpfc_mbuf_alloc(phba, MEM_PRI,
 					     &pbuflist->phys);
 	if (pbuflist == 0 || pbuflist->virt == 0) {
-		list_add_tail(&elsiocb->list, lpfc_iocb_list);
+		spin_lock_irq(phba->host->host_lock);
+		lpfc_sli_release_iocbq(phba, elsiocb);
+		spin_unlock_irq(phba->host->host_lock);
 		lpfc_mbuf_free(phba, pcmd->virt, pcmd->phys);
 		lpfc_mbuf_free(phba, prsp->virt, prsp->phys);
 		kfree(pcmd);
@@ -596,10 +601,8 @@
 					spin_unlock_irq(phba->host->host_lock);
 					(iocb->iocb_cmpl) (phba, iocb, iocb);
 					spin_lock_irq(phba->host->host_lock);
-				} else {
-					list_add_tail(&iocb->list,
-						      &phba->lpfc_iocb_list);
-				}
+				} else
+					lpfc_sli_release_iocbq(phba, iocb);
 			}
 		}
 	}
@@ -1713,7 +1716,7 @@
 		kfree(buf_ptr);
 	}
 	spin_lock_irq(phba->host->host_lock);
-	list_add_tail(&elsiocb->list, &phba->lpfc_iocb_list);
+	lpfc_sli_release_iocbq(phba, elsiocb);
 	spin_unlock_irq(phba->host->host_lock);
 	return 0;
 }
@@ -2929,9 +2932,8 @@
 			spin_unlock_irq(phba->host->host_lock);
 			(piocb->iocb_cmpl) (phba, piocb, piocb);
 			spin_lock_irq(phba->host->host_lock);
-		} else {
-			list_add_tail(&piocb->list, &phba->lpfc_iocb_list);
-		}
+		} else
+			lpfc_sli_release_iocbq(phba, piocb);
 	}
 	if (phba->sli.ring[LPFC_ELS_RING].txcmplq_cnt) {
 		phba->els_tmofunc.expires = jiffies + HZ * timeout;
@@ -2996,7 +2998,7 @@
 			spin_lock_irq(phba->host->host_lock);
 		}
 		else
-			list_add_tail(&piocb->list, &phba->lpfc_iocb_list);
+			lpfc_sli_release_iocbq(phba, piocb);
 	}
 
 	list_for_each_entry_safe(piocb, tmp_iocb, &pring->txcmplq, list) {
@@ -3033,7 +3035,7 @@
 			spin_lock_irq(phba->host->host_lock);
 		}
 		else
-			list_add_tail(&piocb->list, &phba->lpfc_iocb_list);
+			lpfc_sli_release_iocbq(phba, piocb);
 	}
 	spin_unlock_irq(phba->host->host_lock);
 	return;