Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
lpfc_mem.c
Go to the documentation of this file.
1 /*******************************************************************
2  * This file is part of the Emulex Linux Device Driver for *
3  * Fibre Channel Host Bus Adapters. *
4  * Copyright (C) 2004-2012 Emulex. All rights reserved. *
5  * EMULEX and SLI are trademarks of Emulex. *
6  * www.emulex.com *
7  * Portions Copyright (C) 2004-2005 Christoph Hellwig *
8  * *
9  * This program is free software; you can redistribute it and/or *
10  * modify it under the terms of version 2 of the GNU General *
11  * Public License as published by the Free Software Foundation. *
12  * This program is distributed in the hope that it will be useful. *
13  * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND *
14  * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, *
15  * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, ARE *
16  * DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH DISCLAIMERS ARE HELD *
17  * TO BE LEGALLY INVALID. See the GNU General Public License for *
18  * more details, a copy of which can be found in the file COPYING *
19  * included with this package. *
20  *******************************************************************/
21 
22 #include <linux/mempool.h>
23 #include <linux/slab.h>
24 #include <linux/pci.h>
25 #include <linux/interrupt.h>
26 
27 #include <scsi/scsi_device.h>
28 #include <scsi/scsi_transport_fc.h>
29 
30 #include <scsi/scsi.h>
31 
32 #include "lpfc_hw4.h"
33 #include "lpfc_hw.h"
34 #include "lpfc_sli.h"
35 #include "lpfc_sli4.h"
36 #include "lpfc_nl.h"
37 #include "lpfc_disc.h"
38 #include "lpfc_scsi.h"
39 #include "lpfc.h"
40 #include "lpfc_crtn.h"
41 
42 #define LPFC_MBUF_POOL_SIZE 64 /* max elements in MBUF safety pool */
43 #define LPFC_MEM_POOL_SIZE 64 /* max elem in non-DMA safety pool */
44 
45 
61 int
62 lpfc_mem_alloc(struct lpfc_hba *phba, int align)
63 {
64  struct lpfc_dma_pool *pool = &phba->lpfc_mbuf_safety_pool;
65  int i;
66 
67  if (phba->sli_rev == LPFC_SLI_REV4)
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
76  pci_pool_create("lpfc_scsi_dma_buf_pool",
77  phba->pcidev, phba->cfg_sg_dma_buf_size,
78  align, 0);
79  if (!phba->lpfc_scsi_dma_buf_pool)
80  goto fail;
81 
82  phba->lpfc_mbuf_pool = pci_pool_create("lpfc_mbuf_pool", phba->pcidev,
84  align, 0);
85  if (!phba->lpfc_mbuf_pool)
86  goto fail_free_dma_buf_pool;
87 
88  pool->elements = kmalloc(sizeof(struct lpfc_dmabuf) *
90  if (!pool->elements)
91  goto fail_free_lpfc_mbuf_pool;
92 
93  pool->max_count = 0;
94  pool->current_count = 0;
95  for ( i = 0; i < LPFC_MBUF_POOL_SIZE; i++) {
96  pool->elements[i].virt = pci_pool_alloc(phba->lpfc_mbuf_pool,
97  GFP_KERNEL, &pool->elements[i].phys);
98  if (!pool->elements[i].virt)
99  goto fail_free_mbuf_pool;
100  pool->max_count++;
101  pool->current_count++;
102  }
103 
104  phba->mbox_mem_pool = mempool_create_kmalloc_pool(LPFC_MEM_POOL_SIZE,
105  sizeof(LPFC_MBOXQ_t));
106  if (!phba->mbox_mem_pool)
107  goto fail_free_mbuf_pool;
108 
109  phba->nlp_mem_pool = mempool_create_kmalloc_pool(LPFC_MEM_POOL_SIZE,
110  sizeof(struct lpfc_nodelist));
111  if (!phba->nlp_mem_pool)
112  goto fail_free_mbox_pool;
113 
114  if (phba->sli_rev == LPFC_SLI_REV4) {
115  phba->rrq_pool =
116  mempool_create_kmalloc_pool(LPFC_MEM_POOL_SIZE,
117  sizeof(struct lpfc_node_rrq));
118  if (!phba->rrq_pool)
119  goto fail_free_nlp_mem_pool;
120  phba->lpfc_hrb_pool = pci_pool_create("lpfc_hrb_pool",
121  phba->pcidev,
122  LPFC_HDR_BUF_SIZE, align, 0);
123  if (!phba->lpfc_hrb_pool)
124  goto fail_free_rrq_mem_pool;
125 
126  phba->lpfc_drb_pool = pci_pool_create("lpfc_drb_pool",
127  phba->pcidev,
128  LPFC_DATA_BUF_SIZE, align, 0);
129  if (!phba->lpfc_drb_pool)
130  goto fail_free_hrb_pool;
131  phba->lpfc_hbq_pool = NULL;
132  } else {
133  phba->lpfc_hbq_pool = pci_pool_create("lpfc_hbq_pool",
134  phba->pcidev, LPFC_BPL_SIZE, align, 0);
135  if (!phba->lpfc_hbq_pool)
136  goto fail_free_nlp_mem_pool;
137  phba->lpfc_hrb_pool = NULL;
138  phba->lpfc_drb_pool = NULL;
139  }
140 
141  return 0;
142  fail_free_hrb_pool:
143  pci_pool_destroy(phba->lpfc_hrb_pool);
144  phba->lpfc_hrb_pool = NULL;
145  fail_free_rrq_mem_pool:
146  mempool_destroy(phba->rrq_pool);
147  phba->rrq_pool = NULL;
148  fail_free_nlp_mem_pool:
150  phba->nlp_mem_pool = NULL;
151  fail_free_mbox_pool:
153  phba->mbox_mem_pool = NULL;
154  fail_free_mbuf_pool:
155  while (i--)
156  pci_pool_free(phba->lpfc_mbuf_pool, pool->elements[i].virt,
157  pool->elements[i].phys);
158  kfree(pool->elements);
159  fail_free_lpfc_mbuf_pool:
160  pci_pool_destroy(phba->lpfc_mbuf_pool);
161  phba->lpfc_mbuf_pool = NULL;
162  fail_free_dma_buf_pool:
163  pci_pool_destroy(phba->lpfc_scsi_dma_buf_pool);
165  fail:
166  return -ENOMEM;
167 }
168 
178 void
179 lpfc_mem_free(struct lpfc_hba *phba)
180 {
181  int i;
182  struct lpfc_dma_pool *pool = &phba->lpfc_mbuf_safety_pool;
183 
184  /* Free HBQ pools */
186  if (phba->lpfc_drb_pool)
187  pci_pool_destroy(phba->lpfc_drb_pool);
188  phba->lpfc_drb_pool = NULL;
189  if (phba->lpfc_hrb_pool)
190  pci_pool_destroy(phba->lpfc_hrb_pool);
191  phba->lpfc_hrb_pool = NULL;
192 
193  if (phba->lpfc_hbq_pool)
194  pci_pool_destroy(phba->lpfc_hbq_pool);
195  phba->lpfc_hbq_pool = NULL;
196 
197  if (phba->rrq_pool)
198  mempool_destroy(phba->rrq_pool);
199  phba->rrq_pool = NULL;
200 
201  /* Free NLP memory pool */
203  phba->nlp_mem_pool = NULL;
204 
205  /* Free mbox memory pool */
207  phba->mbox_mem_pool = NULL;
208 
209  /* Free MBUF memory pool */
210  for (i = 0; i < pool->current_count; i++)
211  pci_pool_free(phba->lpfc_mbuf_pool, pool->elements[i].virt,
212  pool->elements[i].phys);
213  kfree(pool->elements);
214 
215  pci_pool_destroy(phba->lpfc_mbuf_pool);
216  phba->lpfc_mbuf_pool = NULL;
217 
218  /* Free DMA buffer memory pool */
219  pci_pool_destroy(phba->lpfc_scsi_dma_buf_pool);
221 
222  return;
223 }
224 
236 void
238 {
239  struct lpfc_sli *psli = &phba->sli;
240  LPFC_MBOXQ_t *mbox, *next_mbox;
241  struct lpfc_dmabuf *mp;
242 
243  /* Free memory used in mailbox queue back to mailbox memory pool */
244  list_for_each_entry_safe(mbox, next_mbox, &psli->mboxq, list) {
245  mp = (struct lpfc_dmabuf *) (mbox->context1);
246  if (mp) {
247  lpfc_mbuf_free(phba, mp->virt, mp->phys);
248  kfree(mp);
249  }
250  list_del(&mbox->list);
251  mempool_free(mbox, phba->mbox_mem_pool);
252  }
253  /* Free memory used in mailbox cmpl list back to mailbox memory pool */
254  list_for_each_entry_safe(mbox, next_mbox, &psli->mboxq_cmpl, list) {
255  mp = (struct lpfc_dmabuf *) (mbox->context1);
256  if (mp) {
257  lpfc_mbuf_free(phba, mp->virt, mp->phys);
258  kfree(mp);
259  }
260  list_del(&mbox->list);
261  mempool_free(mbox, phba->mbox_mem_pool);
262  }
263  /* Free the active mailbox command back to the mailbox memory pool */
264  spin_lock_irq(&phba->hbalock);
265  psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE;
266  spin_unlock_irq(&phba->hbalock);
267  if (psli->mbox_active) {
268  mbox = psli->mbox_active;
269  mp = (struct lpfc_dmabuf *) (mbox->context1);
270  if (mp) {
271  lpfc_mbuf_free(phba, mp->virt, mp->phys);
272  kfree(mp);
273  }
274  mempool_free(mbox, phba->mbox_mem_pool);
275  psli->mbox_active = NULL;
276  }
277 
278  /* Free and destroy all the allocated memory pools */
279  lpfc_mem_free(phba);
280 
281  /* Free the iocb lookup array */
282  kfree(psli->iocbq_lookup);
283  psli->iocbq_lookup = NULL;
284 
285  return;
286 }
287 
306 void *
307 lpfc_mbuf_alloc(struct lpfc_hba *phba, int mem_flags, dma_addr_t *handle)
308 {
309  struct lpfc_dma_pool *pool = &phba->lpfc_mbuf_safety_pool;
310  unsigned long iflags;
311  void *ret;
312 
313  ret = pci_pool_alloc(phba->lpfc_mbuf_pool, GFP_KERNEL, handle);
314 
315  spin_lock_irqsave(&phba->hbalock, iflags);
316  if (!ret && (mem_flags & MEM_PRI) && pool->current_count) {
317  pool->current_count--;
318  ret = pool->elements[pool->current_count].virt;
319  *handle = pool->elements[pool->current_count].phys;
320  }
321  spin_unlock_irqrestore(&phba->hbalock, iflags);
322  return ret;
323 }
324 
339 void
340 __lpfc_mbuf_free(struct lpfc_hba * phba, void *virt, dma_addr_t dma)
341 {
342  struct lpfc_dma_pool *pool = &phba->lpfc_mbuf_safety_pool;
343 
344  if (pool->current_count < pool->max_count) {
345  pool->elements[pool->current_count].virt = virt;
346  pool->elements[pool->current_count].phys = dma;
347  pool->current_count++;
348  } else {
349  pci_pool_free(phba->lpfc_mbuf_pool, virt, dma);
350  }
351  return;
352 }
353 
367 void
368 lpfc_mbuf_free(struct lpfc_hba * phba, void *virt, dma_addr_t dma)
369 {
370  unsigned long iflags;
371 
372  spin_lock_irqsave(&phba->hbalock, iflags);
373  __lpfc_mbuf_free(phba, virt, dma);
374  spin_unlock_irqrestore(&phba->hbalock, iflags);
375  return;
376 }
377 
391 struct hbq_dmabuf *
393 {
394  struct hbq_dmabuf *hbqbp;
395 
396  hbqbp = kzalloc(sizeof(struct hbq_dmabuf), GFP_KERNEL);
397  if (!hbqbp)
398  return NULL;
399 
400  hbqbp->dbuf.virt = pci_pool_alloc(phba->lpfc_hbq_pool, GFP_KERNEL,
401  &hbqbp->dbuf.phys);
402  if (!hbqbp->dbuf.virt) {
403  kfree(hbqbp);
404  return NULL;
405  }
406  hbqbp->size = LPFC_BPL_SIZE;
407  return hbqbp;
408 }
409 
422 void
423 lpfc_els_hbq_free(struct lpfc_hba *phba, struct hbq_dmabuf *hbqbp)
424 {
425  pci_pool_free(phba->lpfc_hbq_pool, hbqbp->dbuf.virt, hbqbp->dbuf.phys);
426  kfree(hbqbp);
427  return;
428 }
429 
443 struct hbq_dmabuf *
445 {
446  struct hbq_dmabuf *dma_buf;
447 
448  dma_buf = kzalloc(sizeof(struct hbq_dmabuf), GFP_KERNEL);
449  if (!dma_buf)
450  return NULL;
451 
452  dma_buf->hbuf.virt = pci_pool_alloc(phba->lpfc_hrb_pool, GFP_KERNEL,
453  &dma_buf->hbuf.phys);
454  if (!dma_buf->hbuf.virt) {
455  kfree(dma_buf);
456  return NULL;
457  }
458  dma_buf->dbuf.virt = pci_pool_alloc(phba->lpfc_drb_pool, GFP_KERNEL,
459  &dma_buf->dbuf.phys);
460  if (!dma_buf->dbuf.virt) {
461  pci_pool_free(phba->lpfc_hrb_pool, dma_buf->hbuf.virt,
462  dma_buf->hbuf.phys);
463  kfree(dma_buf);
464  return NULL;
465  }
466  dma_buf->size = LPFC_BPL_SIZE;
467  return dma_buf;
468 }
469 
482 void
483 lpfc_sli4_rb_free(struct lpfc_hba *phba, struct hbq_dmabuf *dmab)
484 {
485  pci_pool_free(phba->lpfc_hrb_pool, dmab->hbuf.virt, dmab->hbuf.phys);
486  pci_pool_free(phba->lpfc_drb_pool, dmab->dbuf.virt, dmab->dbuf.phys);
487  kfree(dmab);
488  return;
489 }
490 
503 void
504 lpfc_in_buf_free(struct lpfc_hba *phba, struct lpfc_dmabuf *mp)
505 {
506  struct hbq_dmabuf *hbq_entry;
507  unsigned long flags;
508 
509  if (!mp)
510  return;
511 
512  if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) {
513  /* Check whether HBQ is still in use */
514  spin_lock_irqsave(&phba->hbalock, flags);
515  if (!phba->hbq_in_use) {
516  spin_unlock_irqrestore(&phba->hbalock, flags);
517  return;
518  }
519  hbq_entry = container_of(mp, struct hbq_dmabuf, dbuf);
520  list_del(&hbq_entry->dbuf.list);
521  if (hbq_entry->tag == -1) {
522  (phba->hbqs[LPFC_ELS_HBQ].hbq_free_buffer)
523  (phba, hbq_entry);
524  } else {
525  lpfc_sli_free_hbq(phba, hbq_entry);
526  }
527  spin_unlock_irqrestore(&phba->hbalock, flags);
528  } else {
529  lpfc_mbuf_free(phba, mp->virt, mp->phys);
530  kfree(mp);
531  }
532  return;
533 }