diff options
author | James Smart <James.Smart@Emulex.Com> | 2007-06-17 20:56:38 -0400 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.il.steeleye.com> | 2007-06-17 23:27:39 -0400 |
commit | 92d7f7b0cde3ad2260e7462b40867b57efd49851 (patch) | |
tree | fadb1d8f1a817c2f85937b5e9c3b830bdecb5555 /drivers/scsi/lpfc/lpfc_mem.c | |
parent | ed957684294618602b48f1950b0c9bbcb036583f (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.c | 46 |
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 | |||
44 | lpfc_mem_alloc(struct lpfc_hba * phba) | 44 | lpfc_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 | |||
218 | void * | 233 | void * |
219 | lpfc_hbq_alloc(struct lpfc_hba *phba, int mem_flags, dma_addr_t *handle) | 234 | lpfc_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 | ||
248 | void | ||
249 | lpfc_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 | |||