diff options
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_mem.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_mem.c | 31 |
1 files changed, 29 insertions, 2 deletions
diff --git a/drivers/scsi/lpfc/lpfc_mem.c b/drivers/scsi/lpfc/lpfc_mem.c index ec3bbbde6f7a..3aa1dff15446 100644 --- a/drivers/scsi/lpfc/lpfc_mem.c +++ b/drivers/scsi/lpfc/lpfc_mem.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /******************************************************************* | 1 | /******************************************************************* |
2 | * This file is part of the Emulex Linux Device Driver for * | 2 | * This file is part of the Emulex Linux Device Driver for * |
3 | * Fibre Channel Host Bus Adapters. * | 3 | * Fibre Channel Host Bus Adapters. * |
4 | * Copyright (C) 2004-2005 Emulex. All rights reserved. * | 4 | * Copyright (C) 2004-2006 Emulex. All rights reserved. * |
5 | * EMULEX and SLI are trademarks of Emulex. * | 5 | * EMULEX and SLI are trademarks of Emulex. * |
6 | * www.emulex.com * | 6 | * www.emulex.com * |
7 | * Portions Copyright (C) 2004-2005 Christoph Hellwig * | 7 | * Portions Copyright (C) 2004-2005 Christoph Hellwig * |
@@ -38,6 +38,8 @@ | |||
38 | #define LPFC_MBUF_POOL_SIZE 64 /* max elements in MBUF safety pool */ | 38 | #define LPFC_MBUF_POOL_SIZE 64 /* max elements in MBUF safety pool */ |
39 | #define LPFC_MEM_POOL_SIZE 64 /* max elem in non-DMA safety pool */ | 39 | #define LPFC_MEM_POOL_SIZE 64 /* max elem in non-DMA safety pool */ |
40 | 40 | ||
41 | |||
42 | |||
41 | int | 43 | int |
42 | lpfc_mem_alloc(struct lpfc_hba * phba) | 44 | lpfc_mem_alloc(struct lpfc_hba * phba) |
43 | { | 45 | { |
@@ -84,6 +86,7 @@ lpfc_mem_alloc(struct lpfc_hba * phba) | |||
84 | 86 | ||
85 | fail_free_mbox_pool: | 87 | fail_free_mbox_pool: |
86 | mempool_destroy(phba->mbox_mem_pool); | 88 | mempool_destroy(phba->mbox_mem_pool); |
89 | phba->mbox_mem_pool = NULL; | ||
87 | fail_free_mbuf_pool: | 90 | fail_free_mbuf_pool: |
88 | while (i--) | 91 | while (i--) |
89 | pci_pool_free(phba->lpfc_mbuf_pool, pool->elements[i].virt, | 92 | pci_pool_free(phba->lpfc_mbuf_pool, pool->elements[i].virt, |
@@ -91,8 +94,10 @@ lpfc_mem_alloc(struct lpfc_hba * phba) | |||
91 | kfree(pool->elements); | 94 | kfree(pool->elements); |
92 | fail_free_lpfc_mbuf_pool: | 95 | fail_free_lpfc_mbuf_pool: |
93 | pci_pool_destroy(phba->lpfc_mbuf_pool); | 96 | pci_pool_destroy(phba->lpfc_mbuf_pool); |
97 | phba->lpfc_mbuf_pool = NULL; | ||
94 | fail_free_dma_buf_pool: | 98 | fail_free_dma_buf_pool: |
95 | pci_pool_destroy(phba->lpfc_scsi_dma_buf_pool); | 99 | pci_pool_destroy(phba->lpfc_scsi_dma_buf_pool); |
100 | phba->lpfc_scsi_dma_buf_pool = NULL; | ||
96 | fail: | 101 | fail: |
97 | return -ENOMEM; | 102 | return -ENOMEM; |
98 | } | 103 | } |
@@ -106,6 +111,7 @@ lpfc_mem_free(struct lpfc_hba * phba) | |||
106 | struct lpfc_dmabuf *mp; | 111 | struct lpfc_dmabuf *mp; |
107 | int i; | 112 | int i; |
108 | 113 | ||
114 | spin_lock_irq(&phba->hbalock); | ||
109 | list_for_each_entry_safe(mbox, next_mbox, &psli->mboxq, list) { | 115 | list_for_each_entry_safe(mbox, next_mbox, &psli->mboxq, list) { |
110 | mp = (struct lpfc_dmabuf *) (mbox->context1); | 116 | mp = (struct lpfc_dmabuf *) (mbox->context1); |
111 | if (mp) { | 117 | if (mp) { |
@@ -117,6 +123,7 @@ lpfc_mem_free(struct lpfc_hba * phba) | |||
117 | } | 123 | } |
118 | 124 | ||
119 | psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; | 125 | psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; |
126 | spin_unlock_irq(&phba->hbalock); | ||
120 | if (psli->mbox_active) { | 127 | if (psli->mbox_active) { |
121 | mbox = psli->mbox_active; | 128 | mbox = psli->mbox_active; |
122 | mp = (struct lpfc_dmabuf *) (mbox->context1); | 129 | mp = (struct lpfc_dmabuf *) (mbox->context1); |
@@ -132,12 +139,18 @@ lpfc_mem_free(struct lpfc_hba * phba) | |||
132 | pci_pool_free(phba->lpfc_mbuf_pool, pool->elements[i].virt, | 139 | pci_pool_free(phba->lpfc_mbuf_pool, pool->elements[i].virt, |
133 | pool->elements[i].phys); | 140 | pool->elements[i].phys); |
134 | kfree(pool->elements); | 141 | kfree(pool->elements); |
142 | |||
135 | mempool_destroy(phba->nlp_mem_pool); | 143 | mempool_destroy(phba->nlp_mem_pool); |
136 | mempool_destroy(phba->mbox_mem_pool); | 144 | mempool_destroy(phba->mbox_mem_pool); |
137 | 145 | ||
138 | pci_pool_destroy(phba->lpfc_scsi_dma_buf_pool); | 146 | pci_pool_destroy(phba->lpfc_scsi_dma_buf_pool); |
139 | pci_pool_destroy(phba->lpfc_mbuf_pool); | 147 | pci_pool_destroy(phba->lpfc_mbuf_pool); |
140 | 148 | ||
149 | phba->nlp_mem_pool = NULL; | ||
150 | phba->mbox_mem_pool = NULL; | ||
151 | phba->lpfc_scsi_dma_buf_pool = NULL; | ||
152 | phba->lpfc_mbuf_pool = NULL; | ||
153 | |||
141 | /* Free the iocb lookup array */ | 154 | /* Free the iocb lookup array */ |
142 | kfree(psli->iocbq_lookup); | 155 | kfree(psli->iocbq_lookup); |
143 | psli->iocbq_lookup = NULL; | 156 | psli->iocbq_lookup = NULL; |
@@ -148,20 +161,23 @@ void * | |||
148 | lpfc_mbuf_alloc(struct lpfc_hba *phba, int mem_flags, dma_addr_t *handle) | 161 | lpfc_mbuf_alloc(struct lpfc_hba *phba, int mem_flags, dma_addr_t *handle) |
149 | { | 162 | { |
150 | struct lpfc_dma_pool *pool = &phba->lpfc_mbuf_safety_pool; | 163 | struct lpfc_dma_pool *pool = &phba->lpfc_mbuf_safety_pool; |
164 | unsigned long iflags; | ||
151 | void *ret; | 165 | void *ret; |
152 | 166 | ||
153 | ret = pci_pool_alloc(phba->lpfc_mbuf_pool, GFP_KERNEL, handle); | 167 | ret = pci_pool_alloc(phba->lpfc_mbuf_pool, GFP_KERNEL, handle); |
154 | 168 | ||
169 | spin_lock_irqsave(&phba->hbalock, iflags); | ||
155 | if (!ret && ( mem_flags & MEM_PRI) && pool->current_count) { | 170 | if (!ret && ( mem_flags & MEM_PRI) && pool->current_count) { |
156 | pool->current_count--; | 171 | pool->current_count--; |
157 | ret = pool->elements[pool->current_count].virt; | 172 | ret = pool->elements[pool->current_count].virt; |
158 | *handle = pool->elements[pool->current_count].phys; | 173 | *handle = pool->elements[pool->current_count].phys; |
159 | } | 174 | } |
175 | spin_unlock_irqrestore(&phba->hbalock, iflags); | ||
160 | return ret; | 176 | return ret; |
161 | } | 177 | } |
162 | 178 | ||
163 | void | 179 | void |
164 | lpfc_mbuf_free(struct lpfc_hba * phba, void *virt, dma_addr_t dma) | 180 | __lpfc_mbuf_free(struct lpfc_hba * phba, void *virt, dma_addr_t dma) |
165 | { | 181 | { |
166 | struct lpfc_dma_pool *pool = &phba->lpfc_mbuf_safety_pool; | 182 | struct lpfc_dma_pool *pool = &phba->lpfc_mbuf_safety_pool; |
167 | 183 | ||
@@ -174,3 +190,14 @@ lpfc_mbuf_free(struct lpfc_hba * phba, void *virt, dma_addr_t dma) | |||
174 | } | 190 | } |
175 | return; | 191 | return; |
176 | } | 192 | } |
193 | |||
194 | void | ||
195 | lpfc_mbuf_free(struct lpfc_hba * phba, void *virt, dma_addr_t dma) | ||
196 | { | ||
197 | unsigned long iflags; | ||
198 | |||
199 | spin_lock_irqsave(&phba->hbalock, iflags); | ||
200 | __lpfc_mbuf_free(phba, virt, dma); | ||
201 | spin_unlock_irqrestore(&phba->hbalock, iflags); | ||
202 | return; | ||
203 | } | ||