diff options
author | James Smart <James.Smart@Emulex.Com> | 2009-05-22 14:51:39 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2009-06-08 12:21:29 -0400 |
commit | da0436e915a5c17ee79e72c1bf978a4ebb1cbf4d (patch) | |
tree | 7784646b7627117fa7849a901c85294fae905505 /drivers/scsi/lpfc/lpfc_mem.c | |
parent | 3772a99175f5378b5001e8da364341a8b8226a4a (diff) |
[SCSI] lpfc 8.3.2 : Addition of SLI4 Interface - Base Support
Adds new hardware and interface definitions.
Adds new interface routines - utilizing the reorganized layout of the
driver. Adds SLI-4 specific functions for attachment, initialization,
teardown, etc.
Signed-off-by: James Smart <james.smart@emulex.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_mem.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_mem.c | 204 |
1 files changed, 161 insertions, 43 deletions
diff --git a/drivers/scsi/lpfc/lpfc_mem.c b/drivers/scsi/lpfc/lpfc_mem.c index 35a976733398..516f4802f84e 100644 --- a/drivers/scsi/lpfc/lpfc_mem.c +++ b/drivers/scsi/lpfc/lpfc_mem.c | |||
@@ -28,8 +28,10 @@ | |||
28 | 28 | ||
29 | #include <scsi/scsi.h> | 29 | #include <scsi/scsi.h> |
30 | 30 | ||
31 | #include "lpfc_hw4.h" | ||
31 | #include "lpfc_hw.h" | 32 | #include "lpfc_hw.h" |
32 | #include "lpfc_sli.h" | 33 | #include "lpfc_sli.h" |
34 | #include "lpfc_sli4.h" | ||
33 | #include "lpfc_nl.h" | 35 | #include "lpfc_nl.h" |
34 | #include "lpfc_disc.h" | 36 | #include "lpfc_disc.h" |
35 | #include "lpfc_scsi.h" | 37 | #include "lpfc_scsi.h" |
@@ -45,7 +47,7 @@ | |||
45 | * @phba: HBA to allocate pools for | 47 | * @phba: HBA to allocate pools for |
46 | * | 48 | * |
47 | * Description: Creates and allocates PCI pools lpfc_scsi_dma_buf_pool, | 49 | * Description: Creates and allocates PCI pools lpfc_scsi_dma_buf_pool, |
48 | * lpfc_mbuf_pool, lpfc_hbq_pool. Creates and allocates kmalloc-backed mempools | 50 | * lpfc_mbuf_pool, lpfc_hrb_pool. Creates and allocates kmalloc-backed mempools |
49 | * for LPFC_MBOXQ_t and lpfc_nodelist. Also allocates the VPI bitmask. | 51 | * for LPFC_MBOXQ_t and lpfc_nodelist. Also allocates the VPI bitmask. |
50 | * | 52 | * |
51 | * Notes: Not interrupt-safe. Must be called with no locks held. If any | 53 | * Notes: Not interrupt-safe. Must be called with no locks held. If any |
@@ -56,19 +58,30 @@ | |||
56 | * -ENOMEM on failure (if any memory allocations fail) | 58 | * -ENOMEM on failure (if any memory allocations fail) |
57 | **/ | 59 | **/ |
58 | int | 60 | int |
59 | lpfc_mem_alloc(struct lpfc_hba * phba) | 61 | lpfc_mem_alloc(struct lpfc_hba *phba, int align) |
60 | { | 62 | { |
61 | struct lpfc_dma_pool *pool = &phba->lpfc_mbuf_safety_pool; | 63 | struct lpfc_dma_pool *pool = &phba->lpfc_mbuf_safety_pool; |
62 | int longs; | 64 | int longs; |
63 | int i; | 65 | int i; |
64 | 66 | ||
65 | phba->lpfc_scsi_dma_buf_pool = pci_pool_create("lpfc_scsi_dma_buf_pool", | 67 | if (phba->sli_rev == LPFC_SLI_REV4) |
66 | phba->pcidev, phba->cfg_sg_dma_buf_size, 8, 0); | 68 | phba->lpfc_scsi_dma_buf_pool = |
69 | pci_pool_create("lpfc_scsi_dma_buf_pool", | ||
70 | phba->pcidev, | ||
71 | phba->cfg_sg_dma_buf_size, | ||
72 | phba->cfg_sg_dma_buf_size, | ||
73 | 0); | ||
74 | else | ||
75 | phba->lpfc_scsi_dma_buf_pool = | ||
76 | pci_pool_create("lpfc_scsi_dma_buf_pool", | ||
77 | phba->pcidev, phba->cfg_sg_dma_buf_size, | ||
78 | align, 0); | ||
67 | if (!phba->lpfc_scsi_dma_buf_pool) | 79 | if (!phba->lpfc_scsi_dma_buf_pool) |
68 | goto fail; | 80 | goto fail; |
69 | 81 | ||
70 | phba->lpfc_mbuf_pool = pci_pool_create("lpfc_mbuf_pool", phba->pcidev, | 82 | phba->lpfc_mbuf_pool = pci_pool_create("lpfc_mbuf_pool", phba->pcidev, |
71 | LPFC_BPL_SIZE, 8,0); | 83 | LPFC_BPL_SIZE, |
84 | align, 0); | ||
72 | if (!phba->lpfc_mbuf_pool) | 85 | if (!phba->lpfc_mbuf_pool) |
73 | goto fail_free_dma_buf_pool; | 86 | goto fail_free_dma_buf_pool; |
74 | 87 | ||
@@ -97,23 +110,31 @@ lpfc_mem_alloc(struct lpfc_hba * phba) | |||
97 | sizeof(struct lpfc_nodelist)); | 110 | sizeof(struct lpfc_nodelist)); |
98 | if (!phba->nlp_mem_pool) | 111 | if (!phba->nlp_mem_pool) |
99 | goto fail_free_mbox_pool; | 112 | goto fail_free_mbox_pool; |
100 | 113 | phba->lpfc_hrb_pool = pci_pool_create("lpfc_hrb_pool", | |
101 | phba->lpfc_hbq_pool = pci_pool_create("lpfc_hbq_pool",phba->pcidev, | 114 | phba->pcidev, |
102 | LPFC_BPL_SIZE, 8, 0); | 115 | LPFC_HDR_BUF_SIZE, align, 0); |
103 | if (!phba->lpfc_hbq_pool) | 116 | if (!phba->lpfc_hrb_pool) |
104 | goto fail_free_nlp_mem_pool; | 117 | goto fail_free_nlp_mem_pool; |
118 | phba->lpfc_drb_pool = pci_pool_create("lpfc_drb_pool", | ||
119 | phba->pcidev, | ||
120 | LPFC_DATA_BUF_SIZE, align, 0); | ||
121 | if (!phba->lpfc_drb_pool) | ||
122 | goto fail_free_hbq_pool; | ||
105 | 123 | ||
106 | /* vpi zero is reserved for the physical port so add 1 to max */ | 124 | /* vpi zero is reserved for the physical port so add 1 to max */ |
107 | longs = ((phba->max_vpi + 1) + BITS_PER_LONG - 1) / BITS_PER_LONG; | 125 | longs = ((phba->max_vpi + 1) + BITS_PER_LONG - 1) / BITS_PER_LONG; |
108 | phba->vpi_bmask = kzalloc(longs * sizeof(unsigned long), GFP_KERNEL); | 126 | phba->vpi_bmask = kzalloc(longs * sizeof(unsigned long), GFP_KERNEL); |
109 | if (!phba->vpi_bmask) | 127 | if (!phba->vpi_bmask) |
110 | goto fail_free_hbq_pool; | 128 | goto fail_free_dbq_pool; |
111 | 129 | ||
112 | return 0; | 130 | return 0; |
113 | 131 | ||
132 | fail_free_dbq_pool: | ||
133 | pci_pool_destroy(phba->lpfc_drb_pool); | ||
134 | phba->lpfc_drb_pool = NULL; | ||
114 | fail_free_hbq_pool: | 135 | fail_free_hbq_pool: |
115 | lpfc_sli_hbqbuf_free_all(phba); | 136 | pci_pool_destroy(phba->lpfc_hrb_pool); |
116 | pci_pool_destroy(phba->lpfc_hbq_pool); | 137 | phba->lpfc_hrb_pool = NULL; |
117 | fail_free_nlp_mem_pool: | 138 | fail_free_nlp_mem_pool: |
118 | mempool_destroy(phba->nlp_mem_pool); | 139 | mempool_destroy(phba->nlp_mem_pool); |
119 | phba->nlp_mem_pool = NULL; | 140 | phba->nlp_mem_pool = NULL; |
@@ -136,27 +157,73 @@ lpfc_mem_alloc(struct lpfc_hba * phba) | |||
136 | } | 157 | } |
137 | 158 | ||
138 | /** | 159 | /** |
139 | * lpfc_mem_free - Frees all PCI and memory allocated by lpfc_mem_alloc | 160 | * lpfc_mem_free - Frees memory allocated by lpfc_mem_alloc |
140 | * @phba: HBA to free memory for | 161 | * @phba: HBA to free memory for |
141 | * | 162 | * |
142 | * Description: Frees PCI pools lpfc_scsi_dma_buf_pool, lpfc_mbuf_pool, | 163 | * Description: Free the memory allocated by lpfc_mem_alloc routine. This |
143 | * lpfc_hbq_pool. Frees kmalloc-backed mempools for LPFC_MBOXQ_t and | 164 | * routine is a the counterpart of lpfc_mem_alloc. |
144 | * lpfc_nodelist. Also frees the VPI bitmask | ||
145 | * | 165 | * |
146 | * Returns: None | 166 | * Returns: None |
147 | **/ | 167 | **/ |
148 | void | 168 | void |
149 | lpfc_mem_free(struct lpfc_hba * phba) | 169 | lpfc_mem_free(struct lpfc_hba *phba) |
150 | { | 170 | { |
151 | struct lpfc_sli *psli = &phba->sli; | ||
152 | struct lpfc_dma_pool *pool = &phba->lpfc_mbuf_safety_pool; | ||
153 | LPFC_MBOXQ_t *mbox, *next_mbox; | ||
154 | struct lpfc_dmabuf *mp; | ||
155 | int i; | 171 | int i; |
172 | struct lpfc_dma_pool *pool = &phba->lpfc_mbuf_safety_pool; | ||
156 | 173 | ||
174 | /* Free VPI bitmask memory */ | ||
157 | kfree(phba->vpi_bmask); | 175 | kfree(phba->vpi_bmask); |
176 | |||
177 | /* Free HBQ pools */ | ||
158 | lpfc_sli_hbqbuf_free_all(phba); | 178 | lpfc_sli_hbqbuf_free_all(phba); |
179 | pci_pool_destroy(phba->lpfc_drb_pool); | ||
180 | phba->lpfc_drb_pool = NULL; | ||
181 | pci_pool_destroy(phba->lpfc_hrb_pool); | ||
182 | phba->lpfc_hrb_pool = NULL; | ||
183 | |||
184 | /* Free NLP memory pool */ | ||
185 | mempool_destroy(phba->nlp_mem_pool); | ||
186 | phba->nlp_mem_pool = NULL; | ||
187 | |||
188 | /* Free mbox memory pool */ | ||
189 | mempool_destroy(phba->mbox_mem_pool); | ||
190 | phba->mbox_mem_pool = NULL; | ||
191 | |||
192 | /* Free MBUF memory pool */ | ||
193 | for (i = 0; i < pool->current_count; i++) | ||
194 | pci_pool_free(phba->lpfc_mbuf_pool, pool->elements[i].virt, | ||
195 | pool->elements[i].phys); | ||
196 | kfree(pool->elements); | ||
197 | |||
198 | pci_pool_destroy(phba->lpfc_mbuf_pool); | ||
199 | phba->lpfc_mbuf_pool = NULL; | ||
159 | 200 | ||
201 | /* Free DMA buffer memory pool */ | ||
202 | pci_pool_destroy(phba->lpfc_scsi_dma_buf_pool); | ||
203 | phba->lpfc_scsi_dma_buf_pool = NULL; | ||
204 | |||
205 | return; | ||
206 | } | ||
207 | |||
208 | /** | ||
209 | * lpfc_mem_free_all - Frees all PCI and driver memory | ||
210 | * @phba: HBA to free memory for | ||
211 | * | ||
212 | * Description: Free memory from PCI and driver memory pools and also those | ||
213 | * used : lpfc_scsi_dma_buf_pool, lpfc_mbuf_pool, lpfc_hrb_pool. Frees | ||
214 | * kmalloc-backed mempools for LPFC_MBOXQ_t and lpfc_nodelist. Also frees | ||
215 | * the VPI bitmask. | ||
216 | * | ||
217 | * Returns: None | ||
218 | **/ | ||
219 | void | ||
220 | lpfc_mem_free_all(struct lpfc_hba *phba) | ||
221 | { | ||
222 | struct lpfc_sli *psli = &phba->sli; | ||
223 | LPFC_MBOXQ_t *mbox, *next_mbox; | ||
224 | struct lpfc_dmabuf *mp; | ||
225 | |||
226 | /* Free memory used in mailbox queue back to mailbox memory pool */ | ||
160 | list_for_each_entry_safe(mbox, next_mbox, &psli->mboxq, list) { | 227 | list_for_each_entry_safe(mbox, next_mbox, &psli->mboxq, list) { |
161 | mp = (struct lpfc_dmabuf *) (mbox->context1); | 228 | mp = (struct lpfc_dmabuf *) (mbox->context1); |
162 | if (mp) { | 229 | if (mp) { |
@@ -166,6 +233,7 @@ lpfc_mem_free(struct lpfc_hba * phba) | |||
166 | list_del(&mbox->list); | 233 | list_del(&mbox->list); |
167 | mempool_free(mbox, phba->mbox_mem_pool); | 234 | mempool_free(mbox, phba->mbox_mem_pool); |
168 | } | 235 | } |
236 | /* Free memory used in mailbox cmpl list back to mailbox memory pool */ | ||
169 | list_for_each_entry_safe(mbox, next_mbox, &psli->mboxq_cmpl, list) { | 237 | list_for_each_entry_safe(mbox, next_mbox, &psli->mboxq_cmpl, list) { |
170 | mp = (struct lpfc_dmabuf *) (mbox->context1); | 238 | mp = (struct lpfc_dmabuf *) (mbox->context1); |
171 | if (mp) { | 239 | if (mp) { |
@@ -175,8 +243,10 @@ lpfc_mem_free(struct lpfc_hba * phba) | |||
175 | list_del(&mbox->list); | 243 | list_del(&mbox->list); |
176 | mempool_free(mbox, phba->mbox_mem_pool); | 244 | mempool_free(mbox, phba->mbox_mem_pool); |
177 | } | 245 | } |
178 | 246 | /* Free the active mailbox command back to the mailbox memory pool */ | |
247 | spin_lock_irq(&phba->hbalock); | ||
179 | psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; | 248 | psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; |
249 | spin_unlock_irq(&phba->hbalock); | ||
180 | if (psli->mbox_active) { | 250 | if (psli->mbox_active) { |
181 | mbox = psli->mbox_active; | 251 | mbox = psli->mbox_active; |
182 | mp = (struct lpfc_dmabuf *) (mbox->context1); | 252 | mp = (struct lpfc_dmabuf *) (mbox->context1); |
@@ -188,27 +258,14 @@ lpfc_mem_free(struct lpfc_hba * phba) | |||
188 | psli->mbox_active = NULL; | 258 | psli->mbox_active = NULL; |
189 | } | 259 | } |
190 | 260 | ||
191 | for (i = 0; i < pool->current_count; i++) | 261 | /* Free and destroy all the allocated memory pools */ |
192 | pci_pool_free(phba->lpfc_mbuf_pool, pool->elements[i].virt, | 262 | lpfc_mem_free(phba); |
193 | pool->elements[i].phys); | ||
194 | kfree(pool->elements); | ||
195 | |||
196 | pci_pool_destroy(phba->lpfc_hbq_pool); | ||
197 | mempool_destroy(phba->nlp_mem_pool); | ||
198 | mempool_destroy(phba->mbox_mem_pool); | ||
199 | |||
200 | pci_pool_destroy(phba->lpfc_scsi_dma_buf_pool); | ||
201 | pci_pool_destroy(phba->lpfc_mbuf_pool); | ||
202 | |||
203 | phba->lpfc_hbq_pool = NULL; | ||
204 | phba->nlp_mem_pool = NULL; | ||
205 | phba->mbox_mem_pool = NULL; | ||
206 | phba->lpfc_scsi_dma_buf_pool = NULL; | ||
207 | phba->lpfc_mbuf_pool = NULL; | ||
208 | 263 | ||
209 | /* Free the iocb lookup array */ | 264 | /* Free the iocb lookup array */ |
210 | kfree(psli->iocbq_lookup); | 265 | kfree(psli->iocbq_lookup); |
211 | psli->iocbq_lookup = NULL; | 266 | psli->iocbq_lookup = NULL; |
267 | |||
268 | return; | ||
212 | } | 269 | } |
213 | 270 | ||
214 | /** | 271 | /** |
@@ -305,7 +362,7 @@ lpfc_mbuf_free(struct lpfc_hba * phba, void *virt, dma_addr_t dma) | |||
305 | * lpfc_els_hbq_alloc - Allocate an HBQ buffer | 362 | * lpfc_els_hbq_alloc - Allocate an HBQ buffer |
306 | * @phba: HBA to allocate HBQ buffer for | 363 | * @phba: HBA to allocate HBQ buffer for |
307 | * | 364 | * |
308 | * Description: Allocates a DMA-mapped HBQ buffer from the lpfc_hbq_pool PCI | 365 | * Description: Allocates a DMA-mapped HBQ buffer from the lpfc_hrb_pool PCI |
309 | * pool along a non-DMA-mapped container for it. | 366 | * pool along a non-DMA-mapped container for it. |
310 | * | 367 | * |
311 | * Notes: Not interrupt-safe. Must be called with no locks held. | 368 | * Notes: Not interrupt-safe. Must be called with no locks held. |
@@ -323,7 +380,7 @@ lpfc_els_hbq_alloc(struct lpfc_hba *phba) | |||
323 | if (!hbqbp) | 380 | if (!hbqbp) |
324 | return NULL; | 381 | return NULL; |
325 | 382 | ||
326 | hbqbp->dbuf.virt = pci_pool_alloc(phba->lpfc_hbq_pool, GFP_KERNEL, | 383 | hbqbp->dbuf.virt = pci_pool_alloc(phba->lpfc_hrb_pool, GFP_KERNEL, |
327 | &hbqbp->dbuf.phys); | 384 | &hbqbp->dbuf.phys); |
328 | if (!hbqbp->dbuf.virt) { | 385 | if (!hbqbp->dbuf.virt) { |
329 | kfree(hbqbp); | 386 | kfree(hbqbp); |
@@ -334,7 +391,7 @@ lpfc_els_hbq_alloc(struct lpfc_hba *phba) | |||
334 | } | 391 | } |
335 | 392 | ||
336 | /** | 393 | /** |
337 | * lpfc_mem_hbq_free - Frees an HBQ buffer allocated with lpfc_els_hbq_alloc | 394 | * lpfc_els_hbq_free - Frees an HBQ buffer allocated with lpfc_els_hbq_alloc |
338 | * @phba: HBA buffer was allocated for | 395 | * @phba: HBA buffer was allocated for |
339 | * @hbqbp: HBQ container returned by lpfc_els_hbq_alloc | 396 | * @hbqbp: HBQ container returned by lpfc_els_hbq_alloc |
340 | * | 397 | * |
@@ -348,12 +405,73 @@ lpfc_els_hbq_alloc(struct lpfc_hba *phba) | |||
348 | void | 405 | void |
349 | lpfc_els_hbq_free(struct lpfc_hba *phba, struct hbq_dmabuf *hbqbp) | 406 | lpfc_els_hbq_free(struct lpfc_hba *phba, struct hbq_dmabuf *hbqbp) |
350 | { | 407 | { |
351 | pci_pool_free(phba->lpfc_hbq_pool, hbqbp->dbuf.virt, hbqbp->dbuf.phys); | 408 | pci_pool_free(phba->lpfc_hrb_pool, hbqbp->dbuf.virt, hbqbp->dbuf.phys); |
352 | kfree(hbqbp); | 409 | kfree(hbqbp); |
353 | return; | 410 | return; |
354 | } | 411 | } |
355 | 412 | ||
356 | /** | 413 | /** |
414 | * lpfc_sli4_rb_alloc - Allocate an SLI4 Receive buffer | ||
415 | * @phba: HBA to allocate a receive buffer for | ||
416 | * | ||
417 | * Description: Allocates a DMA-mapped receive buffer from the lpfc_hrb_pool PCI | ||
418 | * pool along a non-DMA-mapped container for it. | ||
419 | * | ||
420 | * Notes: Not interrupt-safe. Must be called with no locks held. | ||
421 | * | ||
422 | * Returns: | ||
423 | * pointer to HBQ on success | ||
424 | * NULL on failure | ||
425 | **/ | ||
426 | struct hbq_dmabuf * | ||
427 | lpfc_sli4_rb_alloc(struct lpfc_hba *phba) | ||
428 | { | ||
429 | struct hbq_dmabuf *dma_buf; | ||
430 | |||
431 | dma_buf = kmalloc(sizeof(struct hbq_dmabuf), GFP_KERNEL); | ||
432 | if (!dma_buf) | ||
433 | return NULL; | ||
434 | |||
435 | dma_buf->hbuf.virt = pci_pool_alloc(phba->lpfc_hrb_pool, GFP_KERNEL, | ||
436 | &dma_buf->hbuf.phys); | ||
437 | if (!dma_buf->hbuf.virt) { | ||
438 | kfree(dma_buf); | ||
439 | return NULL; | ||
440 | } | ||
441 | dma_buf->dbuf.virt = pci_pool_alloc(phba->lpfc_drb_pool, GFP_KERNEL, | ||
442 | &dma_buf->dbuf.phys); | ||
443 | if (!dma_buf->dbuf.virt) { | ||
444 | pci_pool_free(phba->lpfc_hrb_pool, dma_buf->hbuf.virt, | ||
445 | dma_buf->hbuf.phys); | ||
446 | kfree(dma_buf); | ||
447 | return NULL; | ||
448 | } | ||
449 | dma_buf->size = LPFC_BPL_SIZE; | ||
450 | return dma_buf; | ||
451 | } | ||
452 | |||
453 | /** | ||
454 | * lpfc_sli4_rb_free - Frees a receive buffer | ||
455 | * @phba: HBA buffer was allocated for | ||
456 | * @dmab: DMA Buffer container returned by lpfc_sli4_hbq_alloc | ||
457 | * | ||
458 | * Description: Frees both the container and the DMA-mapped buffers returned by | ||
459 | * lpfc_sli4_rb_alloc. | ||
460 | * | ||
461 | * Notes: Can be called with or without locks held. | ||
462 | * | ||
463 | * Returns: None | ||
464 | **/ | ||
465 | void | ||
466 | lpfc_sli4_rb_free(struct lpfc_hba *phba, struct hbq_dmabuf *dmab) | ||
467 | { | ||
468 | pci_pool_free(phba->lpfc_hrb_pool, dmab->hbuf.virt, dmab->hbuf.phys); | ||
469 | pci_pool_free(phba->lpfc_drb_pool, dmab->dbuf.virt, dmab->dbuf.phys); | ||
470 | kfree(dmab); | ||
471 | return; | ||
472 | } | ||
473 | |||
474 | /** | ||
357 | * lpfc_in_buf_free - Free a DMA buffer | 475 | * lpfc_in_buf_free - Free a DMA buffer |
358 | * @phba: HBA buffer is associated with | 476 | * @phba: HBA buffer is associated with |
359 | * @mp: Buffer to free | 477 | * @mp: Buffer to free |