aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_mem.c
diff options
context:
space:
mode:
authorJames Smart <James.Smart@Emulex.Com>2007-06-17 20:56:38 -0400
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2007-06-17 23:27:39 -0400
commit92d7f7b0cde3ad2260e7462b40867b57efd49851 (patch)
treefadb1d8f1a817c2f85937b5e9c3b830bdecb5555 /drivers/scsi/lpfc/lpfc_mem.c
parented957684294618602b48f1950b0c9bbcb036583f (diff)
[SCSI] lpfc: NPIV: add NPIV support on top of SLI-3
NPIV support is added to the driver. It utilizes the interfaces of the fc transport for the creation and deletion of vports. Within the driver, a new Scsi_Host is created for each NPIV instance, and is paired with a new instance of a FC port. This allows N FC Port elements to share a single Adapter. Signed-off-by: James Smart <James.Smart@emulex.com> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_mem.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_mem.c46
1 files changed, 41 insertions, 5 deletions
diff --git a/drivers/scsi/lpfc/lpfc_mem.c b/drivers/scsi/lpfc/lpfc_mem.c
index 435dc2ec9357..6598e89627df 100644
--- a/drivers/scsi/lpfc/lpfc_mem.c
+++ b/drivers/scsi/lpfc/lpfc_mem.c
@@ -44,6 +44,7 @@ int
44lpfc_mem_alloc(struct lpfc_hba * phba) 44lpfc_mem_alloc(struct lpfc_hba * phba)
45{ 45{
46 struct lpfc_dma_pool *pool = &phba->lpfc_mbuf_safety_pool; 46 struct lpfc_dma_pool *pool = &phba->lpfc_mbuf_safety_pool;
47 int longs;
47 int i; 48 int i;
48 49
49 phba->lpfc_scsi_dma_buf_pool = pci_pool_create("lpfc_scsi_dma_buf_pool", 50 phba->lpfc_scsi_dma_buf_pool = pci_pool_create("lpfc_scsi_dma_buf_pool",
@@ -87,8 +88,15 @@ lpfc_mem_alloc(struct lpfc_hba * phba)
87 if (!phba->lpfc_hbq_pool) 88 if (!phba->lpfc_hbq_pool)
88 goto fail_free_nlp_mem_pool; 89 goto fail_free_nlp_mem_pool;
89 90
91 longs = (phba->max_vpi + BITS_PER_LONG - 1) / BITS_PER_LONG;
92 phba->vpi_bmask = kzalloc(longs * sizeof(unsigned long), GFP_KERNEL);
93 if (!phba->vpi_bmask)
94 goto fail_free_hbq_pool;
95
90 return 0; 96 return 0;
91 97
98 fail_free_hbq_pool:
99 lpfc_sli_hbqbuf_free_all(phba);
92 fail_free_nlp_mem_pool: 100 fail_free_nlp_mem_pool:
93 mempool_destroy(phba->nlp_mem_pool); 101 mempool_destroy(phba->nlp_mem_pool);
94 phba->nlp_mem_pool = NULL; 102 phba->nlp_mem_pool = NULL;
@@ -119,9 +127,9 @@ lpfc_mem_free(struct lpfc_hba * phba)
119 struct lpfc_dmabuf *mp; 127 struct lpfc_dmabuf *mp;
120 int i; 128 int i;
121 129
130 kfree(phba->vpi_bmask);
122 lpfc_sli_hbqbuf_free_all(phba); 131 lpfc_sli_hbqbuf_free_all(phba);
123 132
124 spin_lock_irq(&phba->hbalock);
125 list_for_each_entry_safe(mbox, next_mbox, &psli->mboxq, list) { 133 list_for_each_entry_safe(mbox, next_mbox, &psli->mboxq, list) {
126 mp = (struct lpfc_dmabuf *) (mbox->context1); 134 mp = (struct lpfc_dmabuf *) (mbox->context1);
127 if (mp) { 135 if (mp) {
@@ -131,9 +139,17 @@ lpfc_mem_free(struct lpfc_hba * phba)
131 list_del(&mbox->list); 139 list_del(&mbox->list);
132 mempool_free(mbox, phba->mbox_mem_pool); 140 mempool_free(mbox, phba->mbox_mem_pool);
133 } 141 }
142 list_for_each_entry_safe(mbox, next_mbox, &psli->mboxq_cmpl, list) {
143 mp = (struct lpfc_dmabuf *) (mbox->context1);
144 if (mp) {
145 lpfc_mbuf_free(phba, mp->virt, mp->phys);
146 kfree(mp);
147 }
148 list_del(&mbox->list);
149 mempool_free(mbox, phba->mbox_mem_pool);
150 }
134 151
135 psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; 152 psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE;
136 spin_unlock_irq(&phba->hbalock);
137 if (psli->mbox_active) { 153 if (psli->mbox_active) {
138 mbox = psli->mbox_active; 154 mbox = psli->mbox_active;
139 mp = (struct lpfc_dmabuf *) (mbox->context1); 155 mp = (struct lpfc_dmabuf *) (mbox->context1);
@@ -163,7 +179,7 @@ lpfc_mem_free(struct lpfc_hba * phba)
163 phba->lpfc_scsi_dma_buf_pool = NULL; 179 phba->lpfc_scsi_dma_buf_pool = NULL;
164 phba->lpfc_mbuf_pool = NULL; 180 phba->lpfc_mbuf_pool = NULL;
165 181
166 /* Free the iocb lookup array */ 182 /* Free the iocb lookup array */
167 kfree(psli->iocbq_lookup); 183 kfree(psli->iocbq_lookup);
168 psli->iocbq_lookup = NULL; 184 psli->iocbq_lookup = NULL;
169 185
@@ -179,7 +195,7 @@ lpfc_mbuf_alloc(struct lpfc_hba *phba, int mem_flags, dma_addr_t *handle)
179 ret = pci_pool_alloc(phba->lpfc_mbuf_pool, GFP_KERNEL, handle); 195 ret = pci_pool_alloc(phba->lpfc_mbuf_pool, GFP_KERNEL, handle);
180 196
181 spin_lock_irqsave(&phba->hbalock, iflags); 197 spin_lock_irqsave(&phba->hbalock, iflags);
182 if (!ret && ( mem_flags & MEM_PRI) && pool->current_count) { 198 if (!ret && (mem_flags & MEM_PRI) && pool->current_count) {
183 pool->current_count--; 199 pool->current_count--;
184 ret = pool->elements[pool->current_count].virt; 200 ret = pool->elements[pool->current_count].virt;
185 *handle = pool->elements[pool->current_count].phys; 201 *handle = pool->elements[pool->current_count].phys;
@@ -214,7 +230,6 @@ lpfc_mbuf_free(struct lpfc_hba * phba, void *virt, dma_addr_t dma)
214 return; 230 return;
215} 231}
216 232
217
218void * 233void *
219lpfc_hbq_alloc(struct lpfc_hba *phba, int mem_flags, dma_addr_t *handle) 234lpfc_hbq_alloc(struct lpfc_hba *phba, int mem_flags, dma_addr_t *handle)
220{ 235{
@@ -230,3 +245,24 @@ lpfc_hbq_free(struct lpfc_hba *phba, void *virt, dma_addr_t dma)
230 return; 245 return;
231} 246}
232 247
248void
249lpfc_in_buf_free(struct lpfc_hba *phba, struct lpfc_dmabuf *mp)
250{
251 struct hbq_dmabuf *hbq_entry;
252
253 if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) {
254 hbq_entry = container_of(mp, struct hbq_dmabuf, dbuf);
255 if (hbq_entry->tag == -1) {
256 lpfc_hbq_free(phba, hbq_entry->dbuf.virt,
257 hbq_entry->dbuf.phys);
258 kfree(hbq_entry);
259 } else {
260 lpfc_sli_free_hbq(phba, hbq_entry);
261 }
262 } else {
263 lpfc_mbuf_free(phba, mp->virt, mp->phys);
264 kfree(mp);
265 }
266 return;
267}
268