[SCSI] lpfc: NPIV: add SLI-3 interface

NPIV support is only available via new adapter interface extensions,
termed SLI-3. This interface changes some of the basic behaviors such
as command and response ring element sizes and data structures, as
well as a change in buffer posting.  Note: the new firmware extensions
are found only on our mid-range and enterprise 4Gig adapters - so NPIV
support is available only on these newer adapters. The latest firmware
can be downloaded from the Emulex support page.

Signed-off-by: James Smart <James.Smart@emulex.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
diff --git a/drivers/scsi/lpfc/lpfc_mem.c b/drivers/scsi/lpfc/lpfc_mem.c
index 3aa1dff..435dc2e 100644
--- a/drivers/scsi/lpfc/lpfc_mem.c
+++ b/drivers/scsi/lpfc/lpfc_mem.c
@@ -82,8 +82,16 @@
 	if (!phba->nlp_mem_pool)
 		goto fail_free_mbox_pool;
 
+	phba->lpfc_hbq_pool = pci_pool_create("lpfc_hbq_pool",phba->pcidev,
+					      LPFC_BPL_SIZE, 8, 0);
+	if (!phba->lpfc_hbq_pool)
+		goto fail_free_nlp_mem_pool;
+
 	return 0;
 
+ fail_free_nlp_mem_pool:
+	mempool_destroy(phba->nlp_mem_pool);
+	phba->nlp_mem_pool = NULL;
  fail_free_mbox_pool:
 	mempool_destroy(phba->mbox_mem_pool);
 	phba->mbox_mem_pool = NULL;
@@ -111,6 +119,8 @@
 	struct lpfc_dmabuf   *mp;
 	int i;
 
+	lpfc_sli_hbqbuf_free_all(phba);
+
 	spin_lock_irq(&phba->hbalock);
 	list_for_each_entry_safe(mbox, next_mbox, &psli->mboxq, list) {
 		mp = (struct lpfc_dmabuf *) (mbox->context1);
@@ -140,12 +150,14 @@
 						 pool->elements[i].phys);
 	kfree(pool->elements);
 
+	pci_pool_destroy(phba->lpfc_hbq_pool);
 	mempool_destroy(phba->nlp_mem_pool);
 	mempool_destroy(phba->mbox_mem_pool);
 
 	pci_pool_destroy(phba->lpfc_scsi_dma_buf_pool);
 	pci_pool_destroy(phba->lpfc_mbuf_pool);
 
+	phba->lpfc_hbq_pool = NULL;
 	phba->nlp_mem_pool = NULL;
 	phba->mbox_mem_pool = NULL;
 	phba->lpfc_scsi_dma_buf_pool = NULL;
@@ -201,3 +213,20 @@
 	spin_unlock_irqrestore(&phba->hbalock, iflags);
 	return;
 }
+
+
+void *
+lpfc_hbq_alloc(struct lpfc_hba *phba, int mem_flags, dma_addr_t *handle)
+{
+	void *ret;
+	ret = pci_pool_alloc(phba->lpfc_hbq_pool, GFP_ATOMIC, handle);
+	return ret;
+}
+
+void
+lpfc_hbq_free(struct lpfc_hba *phba, void *virt, dma_addr_t dma)
+{
+	pci_pool_free(phba->lpfc_hbq_pool, virt, dma);
+	return;
+}
+