aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_mem.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_mem.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_mem.c31
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
41int 43int
42lpfc_mem_alloc(struct lpfc_hba * phba) 44lpfc_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 *
148lpfc_mbuf_alloc(struct lpfc_hba *phba, int mem_flags, dma_addr_t *handle) 161lpfc_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
163void 179void
164lpfc_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
194void
195lpfc_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}