lpfc_mem.c revision 8568a4d2495ebcf5da38a2141c7633399143b1a5
1dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>/*******************************************************************
2dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com> * This file is part of the Emulex Linux Device Driver for         *
3c44ce1737438d20ac58e808897e3f8eb015c66d3James.Smart@Emulex.Com * Fibre Channel Host Bus Adapters.                                *
4d8e93df13c8f7bde45a7756944aab528c58df4cfJames Smart * Copyright (C) 2004-2009 Emulex.  All rights reserved.           *
5c44ce1737438d20ac58e808897e3f8eb015c66d3James.Smart@Emulex.Com * EMULEX and SLI are trademarks of Emulex.                        *
6dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com> * www.emulex.com                                                  *
7c44ce1737438d20ac58e808897e3f8eb015c66d3James.Smart@Emulex.Com * Portions Copyright (C) 2004-2005 Christoph Hellwig              *
8dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com> *                                                                 *
9dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com> * This program is free software; you can redistribute it and/or   *
10c44ce1737438d20ac58e808897e3f8eb015c66d3James.Smart@Emulex.Com * modify it under the terms of version 2 of the GNU General       *
11c44ce1737438d20ac58e808897e3f8eb015c66d3James.Smart@Emulex.Com * Public License as published by the Free Software Foundation.    *
12c44ce1737438d20ac58e808897e3f8eb015c66d3James.Smart@Emulex.Com * This program is distributed in the hope that it will be useful. *
13c44ce1737438d20ac58e808897e3f8eb015c66d3James.Smart@Emulex.Com * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND          *
14c44ce1737438d20ac58e808897e3f8eb015c66d3James.Smart@Emulex.Com * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,  *
15c44ce1737438d20ac58e808897e3f8eb015c66d3James.Smart@Emulex.Com * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, ARE      *
16c44ce1737438d20ac58e808897e3f8eb015c66d3James.Smart@Emulex.Com * DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH DISCLAIMERS ARE HELD *
17c44ce1737438d20ac58e808897e3f8eb015c66d3James.Smart@Emulex.Com * TO BE LEGALLY INVALID.  See the GNU General Public License for  *
18c44ce1737438d20ac58e808897e3f8eb015c66d3James.Smart@Emulex.Com * more details, a copy of which can be found in the file COPYING  *
19c44ce1737438d20ac58e808897e3f8eb015c66d3James.Smart@Emulex.Com * included with this package.                                     *
20dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com> *******************************************************************/
21dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>
22dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>#include <linux/mempool.h>
23dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>#include <linux/pci.h>
24dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>#include <linux/interrupt.h>
25dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>
26f888ba3ce77c66bece3d804caf7d559838209a4aJames.Smart@Emulex.Com#include <scsi/scsi_device.h>
27f888ba3ce77c66bece3d804caf7d559838209a4aJames.Smart@Emulex.Com#include <scsi/scsi_transport_fc.h>
28f888ba3ce77c66bece3d804caf7d559838209a4aJames.Smart@Emulex.Com
29918865230e55b1fece2d8edec39d46c00626590bJames.Smart@Emulex.Com#include <scsi/scsi.h>
30918865230e55b1fece2d8edec39d46c00626590bJames.Smart@Emulex.Com
31da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart#include "lpfc_hw4.h"
32dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>#include "lpfc_hw.h"
33dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>#include "lpfc_sli.h"
34da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart#include "lpfc_sli4.h"
35ea2151b4e142fa2de0319d9dd80413a997bf435aJames Smart#include "lpfc_nl.h"
36dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>#include "lpfc_disc.h"
37dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>#include "lpfc_scsi.h"
38dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>#include "lpfc.h"
39dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>#include "lpfc_crtn.h"
40dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>
41dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>#define LPFC_MBUF_POOL_SIZE     64      /* max elements in MBUF safety pool */
42dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>#define LPFC_MEM_POOL_SIZE      64      /* max elem in non-DMA safety pool */
43dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>
442e0fef85e098f6794956b8b80b111179fbb4cbb7James Smart
45e59058c44025d71c9b7f260076a932935d3bba95James Smart/**
463621a710a7dbb2d22a8e95d94bcf0c2d13ef57fcJames Smart * lpfc_mem_alloc - create and allocate all PCI and memory pools
47e59058c44025d71c9b7f260076a932935d3bba95James Smart * @phba: HBA to allocate pools for
48e59058c44025d71c9b7f260076a932935d3bba95James Smart *
49e59058c44025d71c9b7f260076a932935d3bba95James Smart * Description: Creates and allocates PCI pools lpfc_scsi_dma_buf_pool,
50da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart * lpfc_mbuf_pool, lpfc_hrb_pool.  Creates and allocates kmalloc-backed mempools
51e59058c44025d71c9b7f260076a932935d3bba95James Smart * for LPFC_MBOXQ_t and lpfc_nodelist.  Also allocates the VPI bitmask.
52e59058c44025d71c9b7f260076a932935d3bba95James Smart *
53e59058c44025d71c9b7f260076a932935d3bba95James Smart * Notes: Not interrupt-safe.  Must be called with no locks held.  If any
54e59058c44025d71c9b7f260076a932935d3bba95James Smart * allocation fails, frees all successfully allocated memory before returning.
55e59058c44025d71c9b7f260076a932935d3bba95James Smart *
56e59058c44025d71c9b7f260076a932935d3bba95James Smart * Returns:
57e59058c44025d71c9b7f260076a932935d3bba95James Smart *   0 on success
58e59058c44025d71c9b7f260076a932935d3bba95James Smart *   -ENOMEM on failure (if any memory allocations fail)
59e59058c44025d71c9b7f260076a932935d3bba95James Smart **/
60dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>int
61da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smartlpfc_mem_alloc(struct lpfc_hba *phba, int align)
62dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>{
63dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>	struct lpfc_dma_pool *pool = &phba->lpfc_mbuf_safety_pool;
6492d7f7b0cde3ad2260e7462b40867b57efd49851James Smart	int longs;
65dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>	int i;
66dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>
67da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	if (phba->sli_rev == LPFC_SLI_REV4)
68da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart		phba->lpfc_scsi_dma_buf_pool =
69da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart			pci_pool_create("lpfc_scsi_dma_buf_pool",
70da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart				phba->pcidev,
71da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart				phba->cfg_sg_dma_buf_size,
72da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart				phba->cfg_sg_dma_buf_size,
73da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart				0);
74da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	else
75da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart		phba->lpfc_scsi_dma_buf_pool =
76da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart			pci_pool_create("lpfc_scsi_dma_buf_pool",
77da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart				phba->pcidev, phba->cfg_sg_dma_buf_size,
78da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart				align, 0);
79dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>	if (!phba->lpfc_scsi_dma_buf_pool)
80dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>		goto fail;
81dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>
82dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>	phba->lpfc_mbuf_pool = pci_pool_create("lpfc_mbuf_pool", phba->pcidev,
83da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart							LPFC_BPL_SIZE,
84da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart							align, 0);
85dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>	if (!phba->lpfc_mbuf_pool)
86dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>		goto fail_free_dma_buf_pool;
87dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>
88dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>	pool->elements = kmalloc(sizeof(struct lpfc_dmabuf) *
89dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>					 LPFC_MBUF_POOL_SIZE, GFP_KERNEL);
90a96e0c7798057dd8055d0263c076fed975c10237Mariusz Kozlowski	if (!pool->elements)
91a96e0c7798057dd8055d0263c076fed975c10237Mariusz Kozlowski		goto fail_free_lpfc_mbuf_pool;
92a96e0c7798057dd8055d0263c076fed975c10237Mariusz Kozlowski
93dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>	pool->max_count = 0;
94dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>	pool->current_count = 0;
95dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>	for ( i = 0; i < LPFC_MBUF_POOL_SIZE; i++) {
96dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>		pool->elements[i].virt = pci_pool_alloc(phba->lpfc_mbuf_pool,
97dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>				       GFP_KERNEL, &pool->elements[i].phys);
98dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>		if (!pool->elements[i].virt)
99dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>			goto fail_free_mbuf_pool;
100dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>		pool->max_count++;
101dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>		pool->current_count++;
102dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>	}
103dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>
1040eaae62abaa1ad1f231932b6cdd9fb1b91df6651Matthew Dobson	phba->mbox_mem_pool = mempool_create_kmalloc_pool(LPFC_MEM_POOL_SIZE,
1050eaae62abaa1ad1f231932b6cdd9fb1b91df6651Matthew Dobson							 sizeof(LPFC_MBOXQ_t));
106dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>	if (!phba->mbox_mem_pool)
107dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>		goto fail_free_mbuf_pool;
108dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>
1090eaae62abaa1ad1f231932b6cdd9fb1b91df6651Matthew Dobson	phba->nlp_mem_pool = mempool_create_kmalloc_pool(LPFC_MEM_POOL_SIZE,
1100eaae62abaa1ad1f231932b6cdd9fb1b91df6651Matthew Dobson						sizeof(struct lpfc_nodelist));
111dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>	if (!phba->nlp_mem_pool)
112dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>		goto fail_free_mbox_pool;
1138568a4d2495ebcf5da38a2141c7633399143b1a5James Smart
1148568a4d2495ebcf5da38a2141c7633399143b1a5James Smart	if (phba->sli_rev == LPFC_SLI_REV4) {
1158568a4d2495ebcf5da38a2141c7633399143b1a5James Smart		phba->lpfc_hrb_pool = pci_pool_create("lpfc_hrb_pool",
116da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart					      phba->pcidev,
117da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart					      LPFC_HDR_BUF_SIZE, align, 0);
1188568a4d2495ebcf5da38a2141c7633399143b1a5James Smart		if (!phba->lpfc_hrb_pool)
1198568a4d2495ebcf5da38a2141c7633399143b1a5James Smart			goto fail_free_nlp_mem_pool;
1208568a4d2495ebcf5da38a2141c7633399143b1a5James Smart
1218568a4d2495ebcf5da38a2141c7633399143b1a5James Smart		phba->lpfc_drb_pool = pci_pool_create("lpfc_drb_pool",
122da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart					      phba->pcidev,
123da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart					      LPFC_DATA_BUF_SIZE, align, 0);
1248568a4d2495ebcf5da38a2141c7633399143b1a5James Smart		if (!phba->lpfc_drb_pool)
1258568a4d2495ebcf5da38a2141c7633399143b1a5James Smart			goto fail_free_hrb_pool;
1268568a4d2495ebcf5da38a2141c7633399143b1a5James Smart		phba->lpfc_hbq_pool = NULL;
1278568a4d2495ebcf5da38a2141c7633399143b1a5James Smart	} else {
1288568a4d2495ebcf5da38a2141c7633399143b1a5James Smart		phba->lpfc_hbq_pool = pci_pool_create("lpfc_hbq_pool",
1298568a4d2495ebcf5da38a2141c7633399143b1a5James Smart			phba->pcidev, LPFC_BPL_SIZE, align, 0);
1308568a4d2495ebcf5da38a2141c7633399143b1a5James Smart		if (!phba->lpfc_hbq_pool)
1318568a4d2495ebcf5da38a2141c7633399143b1a5James Smart			goto fail_free_nlp_mem_pool;
1328568a4d2495ebcf5da38a2141c7633399143b1a5James Smart		phba->lpfc_hrb_pool = NULL;
1338568a4d2495ebcf5da38a2141c7633399143b1a5James Smart		phba->lpfc_drb_pool = NULL;
1348568a4d2495ebcf5da38a2141c7633399143b1a5James Smart	}
135858c9f6c19c6f9bf86cbbc64ce0d17c61d6131b8James Smart	/* vpi zero is reserved for the physical port so add 1 to max */
136858c9f6c19c6f9bf86cbbc64ce0d17c61d6131b8James Smart	longs = ((phba->max_vpi + 1) + BITS_PER_LONG - 1) / BITS_PER_LONG;
13792d7f7b0cde3ad2260e7462b40867b57efd49851James Smart	phba->vpi_bmask = kzalloc(longs * sizeof(unsigned long), GFP_KERNEL);
13892d7f7b0cde3ad2260e7462b40867b57efd49851James Smart	if (!phba->vpi_bmask)
139da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart		goto fail_free_dbq_pool;
14092d7f7b0cde3ad2260e7462b40867b57efd49851James Smart
141dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>	return 0;
142dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>
143da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart fail_free_dbq_pool:
144da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	pci_pool_destroy(phba->lpfc_drb_pool);
145da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	phba->lpfc_drb_pool = NULL;
1468568a4d2495ebcf5da38a2141c7633399143b1a5James Smart fail_free_hrb_pool:
147da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	pci_pool_destroy(phba->lpfc_hrb_pool);
148da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	phba->lpfc_hrb_pool = NULL;
149ed957684294618602b48f1950b0c9bbcb036583fJames Smart fail_free_nlp_mem_pool:
150ed957684294618602b48f1950b0c9bbcb036583fJames Smart	mempool_destroy(phba->nlp_mem_pool);
151ed957684294618602b48f1950b0c9bbcb036583fJames Smart	phba->nlp_mem_pool = NULL;
152dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com> fail_free_mbox_pool:
153dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>	mempool_destroy(phba->mbox_mem_pool);
1542e0fef85e098f6794956b8b80b111179fbb4cbb7James Smart	phba->mbox_mem_pool = NULL;
155dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com> fail_free_mbuf_pool:
156a96e0c7798057dd8055d0263c076fed975c10237Mariusz Kozlowski	while (i--)
157dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>		pci_pool_free(phba->lpfc_mbuf_pool, pool->elements[i].virt,
158dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>						 pool->elements[i].phys);
159dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>	kfree(pool->elements);
160a96e0c7798057dd8055d0263c076fed975c10237Mariusz Kozlowski fail_free_lpfc_mbuf_pool:
161dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>	pci_pool_destroy(phba->lpfc_mbuf_pool);
1622e0fef85e098f6794956b8b80b111179fbb4cbb7James Smart	phba->lpfc_mbuf_pool = NULL;
163dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com> fail_free_dma_buf_pool:
164dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>	pci_pool_destroy(phba->lpfc_scsi_dma_buf_pool);
1652e0fef85e098f6794956b8b80b111179fbb4cbb7James Smart	phba->lpfc_scsi_dma_buf_pool = NULL;
166dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com> fail:
167dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>	return -ENOMEM;
168dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>}
169dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>
170e59058c44025d71c9b7f260076a932935d3bba95James Smart/**
171da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart * lpfc_mem_free - Frees memory allocated by lpfc_mem_alloc
172e59058c44025d71c9b7f260076a932935d3bba95James Smart * @phba: HBA to free memory for
173e59058c44025d71c9b7f260076a932935d3bba95James Smart *
174da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart * Description: Free the memory allocated by lpfc_mem_alloc routine. This
175da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart * routine is a the counterpart of lpfc_mem_alloc.
176e59058c44025d71c9b7f260076a932935d3bba95James Smart *
177e59058c44025d71c9b7f260076a932935d3bba95James Smart * Returns: None
178e59058c44025d71c9b7f260076a932935d3bba95James Smart **/
179dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>void
180da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smartlpfc_mem_free(struct lpfc_hba *phba)
181dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>{
182dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>	int i;
183da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	struct lpfc_dma_pool *pool = &phba->lpfc_mbuf_safety_pool;
184dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>
185da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	/* Free VPI bitmask memory */
18692d7f7b0cde3ad2260e7462b40867b57efd49851James Smart	kfree(phba->vpi_bmask);
187da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart
188da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	/* Free HBQ pools */
189ed957684294618602b48f1950b0c9bbcb036583fJames Smart	lpfc_sli_hbqbuf_free_all(phba);
1908568a4d2495ebcf5da38a2141c7633399143b1a5James Smart	if (phba->lpfc_drb_pool)
1918568a4d2495ebcf5da38a2141c7633399143b1a5James Smart		pci_pool_destroy(phba->lpfc_drb_pool);
192da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	phba->lpfc_drb_pool = NULL;
1938568a4d2495ebcf5da38a2141c7633399143b1a5James Smart	if (phba->lpfc_hrb_pool)
1948568a4d2495ebcf5da38a2141c7633399143b1a5James Smart		pci_pool_destroy(phba->lpfc_hrb_pool);
195da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	phba->lpfc_hrb_pool = NULL;
196da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart
1978568a4d2495ebcf5da38a2141c7633399143b1a5James Smart	if (phba->lpfc_hbq_pool)
1988568a4d2495ebcf5da38a2141c7633399143b1a5James Smart		pci_pool_destroy(phba->lpfc_hbq_pool);
1998568a4d2495ebcf5da38a2141c7633399143b1a5James Smart	phba->lpfc_hbq_pool = NULL;
2008568a4d2495ebcf5da38a2141c7633399143b1a5James Smart
201da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	/* Free NLP memory pool */
202da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	mempool_destroy(phba->nlp_mem_pool);
203da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	phba->nlp_mem_pool = NULL;
204da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart
205da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	/* Free mbox memory pool */
206da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	mempool_destroy(phba->mbox_mem_pool);
207da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	phba->mbox_mem_pool = NULL;
208da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart
209da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	/* Free MBUF memory pool */
210da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	for (i = 0; i < pool->current_count; i++)
211da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart		pci_pool_free(phba->lpfc_mbuf_pool, pool->elements[i].virt,
212da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart			      pool->elements[i].phys);
213da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	kfree(pool->elements);
214da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart
215da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	pci_pool_destroy(phba->lpfc_mbuf_pool);
216da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	phba->lpfc_mbuf_pool = NULL;
217ed957684294618602b48f1950b0c9bbcb036583fJames Smart
218da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	/* Free DMA buffer memory pool */
219da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	pci_pool_destroy(phba->lpfc_scsi_dma_buf_pool);
220da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	phba->lpfc_scsi_dma_buf_pool = NULL;
221da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart
222da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	return;
223da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart}
224da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart
225da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart/**
226da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart * lpfc_mem_free_all - Frees all PCI and driver memory
227da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart * @phba: HBA to free memory for
228da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart *
229da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart * Description: Free memory from PCI and driver memory pools and also those
230da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart * used : lpfc_scsi_dma_buf_pool, lpfc_mbuf_pool, lpfc_hrb_pool. Frees
231da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart * kmalloc-backed mempools for LPFC_MBOXQ_t and lpfc_nodelist. Also frees
232da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart * the VPI bitmask.
233da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart *
234da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart * Returns: None
235da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart **/
236da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smartvoid
237da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smartlpfc_mem_free_all(struct lpfc_hba *phba)
238da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart{
239da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	struct lpfc_sli *psli = &phba->sli;
240da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	LPFC_MBOXQ_t *mbox, *next_mbox;
241da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	struct lpfc_dmabuf   *mp;
242da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart
243da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	/* Free memory used in mailbox queue back to mailbox memory pool */
244dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>	list_for_each_entry_safe(mbox, next_mbox, &psli->mboxq, list) {
245dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>		mp = (struct lpfc_dmabuf *) (mbox->context1);
246dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>		if (mp) {
247dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>			lpfc_mbuf_free(phba, mp->virt, mp->phys);
248dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>			kfree(mp);
249dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>		}
250dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>		list_del(&mbox->list);
251dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>		mempool_free(mbox, phba->mbox_mem_pool);
252dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>	}
253da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	/* Free memory used in mailbox cmpl list back to mailbox memory pool */
25492d7f7b0cde3ad2260e7462b40867b57efd49851James Smart	list_for_each_entry_safe(mbox, next_mbox, &psli->mboxq_cmpl, list) {
25592d7f7b0cde3ad2260e7462b40867b57efd49851James Smart		mp = (struct lpfc_dmabuf *) (mbox->context1);
25692d7f7b0cde3ad2260e7462b40867b57efd49851James Smart		if (mp) {
25792d7f7b0cde3ad2260e7462b40867b57efd49851James Smart			lpfc_mbuf_free(phba, mp->virt, mp->phys);
25892d7f7b0cde3ad2260e7462b40867b57efd49851James Smart			kfree(mp);
25992d7f7b0cde3ad2260e7462b40867b57efd49851James Smart		}
26092d7f7b0cde3ad2260e7462b40867b57efd49851James Smart		list_del(&mbox->list);
26192d7f7b0cde3ad2260e7462b40867b57efd49851James Smart		mempool_free(mbox, phba->mbox_mem_pool);
26292d7f7b0cde3ad2260e7462b40867b57efd49851James Smart	}
263da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	/* Free the active mailbox command back to the mailbox memory pool */
264da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	spin_lock_irq(&phba->hbalock);
265dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>	psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE;
266da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	spin_unlock_irq(&phba->hbalock);
267dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>	if (psli->mbox_active) {
268dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>		mbox = psli->mbox_active;
269dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>		mp = (struct lpfc_dmabuf *) (mbox->context1);
270dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>		if (mp) {
271dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>			lpfc_mbuf_free(phba, mp->virt, mp->phys);
272dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>			kfree(mp);
273dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>		}
274dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>		mempool_free(mbox, phba->mbox_mem_pool);
275dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>		psli->mbox_active = NULL;
276dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>	}
277dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>
278da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	/* Free and destroy all the allocated memory pools */
279da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	lpfc_mem_free(phba);
2802e0fef85e098f6794956b8b80b111179fbb4cbb7James Smart
281e59058c44025d71c9b7f260076a932935d3bba95James Smart	/* Free the iocb lookup array */
2829f49d3b05f092b89e774be20c654ceb0c64a7d19James Smart	kfree(psli->iocbq_lookup);
2839f49d3b05f092b89e774be20c654ceb0c64a7d19James Smart	psli->iocbq_lookup = NULL;
284da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart
285da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	return;
286dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>}
287dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>
288e59058c44025d71c9b7f260076a932935d3bba95James Smart/**
2893621a710a7dbb2d22a8e95d94bcf0c2d13ef57fcJames Smart * lpfc_mbuf_alloc - Allocate an mbuf from the lpfc_mbuf_pool PCI pool
290e59058c44025d71c9b7f260076a932935d3bba95James Smart * @phba: HBA which owns the pool to allocate from
291e59058c44025d71c9b7f260076a932935d3bba95James Smart * @mem_flags: indicates if this is a priority (MEM_PRI) allocation
292e59058c44025d71c9b7f260076a932935d3bba95James Smart * @handle: used to return the DMA-mapped address of the mbuf
293e59058c44025d71c9b7f260076a932935d3bba95James Smart *
294e59058c44025d71c9b7f260076a932935d3bba95James Smart * Description: Allocates a DMA-mapped buffer from the lpfc_mbuf_pool PCI pool.
295e59058c44025d71c9b7f260076a932935d3bba95James Smart * Allocates from generic pci_pool_alloc function first and if that fails and
296e59058c44025d71c9b7f260076a932935d3bba95James Smart * mem_flags has MEM_PRI set (the only defined flag), returns an mbuf from the
297e59058c44025d71c9b7f260076a932935d3bba95James Smart * HBA's pool.
298e59058c44025d71c9b7f260076a932935d3bba95James Smart *
299e59058c44025d71c9b7f260076a932935d3bba95James Smart * Notes: Not interrupt-safe.  Must be called with no locks held.  Takes
300e59058c44025d71c9b7f260076a932935d3bba95James Smart * phba->hbalock.
301e59058c44025d71c9b7f260076a932935d3bba95James Smart *
302e59058c44025d71c9b7f260076a932935d3bba95James Smart * Returns:
303e59058c44025d71c9b7f260076a932935d3bba95James Smart *   pointer to the allocated mbuf on success
304e59058c44025d71c9b7f260076a932935d3bba95James Smart *   NULL on failure
305e59058c44025d71c9b7f260076a932935d3bba95James Smart **/
306dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>void *
307dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>lpfc_mbuf_alloc(struct lpfc_hba *phba, int mem_flags, dma_addr_t *handle)
308dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>{
309dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>	struct lpfc_dma_pool *pool = &phba->lpfc_mbuf_safety_pool;
3102e0fef85e098f6794956b8b80b111179fbb4cbb7James Smart	unsigned long iflags;
311dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>	void *ret;
312dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>
313dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>	ret = pci_pool_alloc(phba->lpfc_mbuf_pool, GFP_KERNEL, handle);
314dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>
3152e0fef85e098f6794956b8b80b111179fbb4cbb7James Smart	spin_lock_irqsave(&phba->hbalock, iflags);
31692d7f7b0cde3ad2260e7462b40867b57efd49851James Smart	if (!ret && (mem_flags & MEM_PRI) && pool->current_count) {
317dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>		pool->current_count--;
318dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>		ret = pool->elements[pool->current_count].virt;
319dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>		*handle = pool->elements[pool->current_count].phys;
320dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>	}
3212e0fef85e098f6794956b8b80b111179fbb4cbb7James Smart	spin_unlock_irqrestore(&phba->hbalock, iflags);
322dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>	return ret;
323dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>}
324dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>
325e59058c44025d71c9b7f260076a932935d3bba95James Smart/**
3263621a710a7dbb2d22a8e95d94bcf0c2d13ef57fcJames Smart * __lpfc_mbuf_free - Free an mbuf from the lpfc_mbuf_pool PCI pool (locked)
327e59058c44025d71c9b7f260076a932935d3bba95James Smart * @phba: HBA which owns the pool to return to
328e59058c44025d71c9b7f260076a932935d3bba95James Smart * @virt: mbuf to free
329e59058c44025d71c9b7f260076a932935d3bba95James Smart * @dma: the DMA-mapped address of the lpfc_mbuf_pool to be freed
330e59058c44025d71c9b7f260076a932935d3bba95James Smart *
331e59058c44025d71c9b7f260076a932935d3bba95James Smart * Description: Returns an mbuf lpfc_mbuf_pool to the lpfc_mbuf_safety_pool if
332e59058c44025d71c9b7f260076a932935d3bba95James Smart * it is below its max_count, frees the mbuf otherwise.
333e59058c44025d71c9b7f260076a932935d3bba95James Smart *
334e59058c44025d71c9b7f260076a932935d3bba95James Smart * Notes: Must be called with phba->hbalock held to synchronize access to
335e59058c44025d71c9b7f260076a932935d3bba95James Smart * lpfc_mbuf_safety_pool.
336e59058c44025d71c9b7f260076a932935d3bba95James Smart *
337e59058c44025d71c9b7f260076a932935d3bba95James Smart * Returns: None
338e59058c44025d71c9b7f260076a932935d3bba95James Smart **/
339dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>void
3402e0fef85e098f6794956b8b80b111179fbb4cbb7James Smart__lpfc_mbuf_free(struct lpfc_hba * phba, void *virt, dma_addr_t dma)
341dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>{
342dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>	struct lpfc_dma_pool *pool = &phba->lpfc_mbuf_safety_pool;
343dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>
344dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>	if (pool->current_count < pool->max_count) {
345dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>		pool->elements[pool->current_count].virt = virt;
346dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>		pool->elements[pool->current_count].phys = dma;
347dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>		pool->current_count++;
348dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>	} else {
349dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>		pci_pool_free(phba->lpfc_mbuf_pool, virt, dma);
350dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>	}
351dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>	return;
352dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>}
3532e0fef85e098f6794956b8b80b111179fbb4cbb7James Smart
354e59058c44025d71c9b7f260076a932935d3bba95James Smart/**
3553621a710a7dbb2d22a8e95d94bcf0c2d13ef57fcJames Smart * lpfc_mbuf_free - Free an mbuf from the lpfc_mbuf_pool PCI pool (unlocked)
356e59058c44025d71c9b7f260076a932935d3bba95James Smart * @phba: HBA which owns the pool to return to
357e59058c44025d71c9b7f260076a932935d3bba95James Smart * @virt: mbuf to free
358e59058c44025d71c9b7f260076a932935d3bba95James Smart * @dma: the DMA-mapped address of the lpfc_mbuf_pool to be freed
359e59058c44025d71c9b7f260076a932935d3bba95James Smart *
360e59058c44025d71c9b7f260076a932935d3bba95James Smart * Description: Returns an mbuf lpfc_mbuf_pool to the lpfc_mbuf_safety_pool if
361e59058c44025d71c9b7f260076a932935d3bba95James Smart * it is below its max_count, frees the mbuf otherwise.
362e59058c44025d71c9b7f260076a932935d3bba95James Smart *
363e59058c44025d71c9b7f260076a932935d3bba95James Smart * Notes: Takes phba->hbalock.  Can be called with or without other locks held.
364e59058c44025d71c9b7f260076a932935d3bba95James Smart *
365e59058c44025d71c9b7f260076a932935d3bba95James Smart * Returns: None
366e59058c44025d71c9b7f260076a932935d3bba95James Smart **/
3672e0fef85e098f6794956b8b80b111179fbb4cbb7James Smartvoid
3682e0fef85e098f6794956b8b80b111179fbb4cbb7James Smartlpfc_mbuf_free(struct lpfc_hba * phba, void *virt, dma_addr_t dma)
3692e0fef85e098f6794956b8b80b111179fbb4cbb7James Smart{
3702e0fef85e098f6794956b8b80b111179fbb4cbb7James Smart	unsigned long iflags;
3712e0fef85e098f6794956b8b80b111179fbb4cbb7James Smart
3722e0fef85e098f6794956b8b80b111179fbb4cbb7James Smart	spin_lock_irqsave(&phba->hbalock, iflags);
3732e0fef85e098f6794956b8b80b111179fbb4cbb7James Smart	__lpfc_mbuf_free(phba, virt, dma);
3742e0fef85e098f6794956b8b80b111179fbb4cbb7James Smart	spin_unlock_irqrestore(&phba->hbalock, iflags);
3752e0fef85e098f6794956b8b80b111179fbb4cbb7James Smart	return;
3762e0fef85e098f6794956b8b80b111179fbb4cbb7James Smart}
377ed957684294618602b48f1950b0c9bbcb036583fJames Smart
378e59058c44025d71c9b7f260076a932935d3bba95James Smart/**
3793621a710a7dbb2d22a8e95d94bcf0c2d13ef57fcJames Smart * lpfc_els_hbq_alloc - Allocate an HBQ buffer
380e59058c44025d71c9b7f260076a932935d3bba95James Smart * @phba: HBA to allocate HBQ buffer for
381e59058c44025d71c9b7f260076a932935d3bba95James Smart *
382da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart * Description: Allocates a DMA-mapped HBQ buffer from the lpfc_hrb_pool PCI
383e59058c44025d71c9b7f260076a932935d3bba95James Smart * pool along a non-DMA-mapped container for it.
384e59058c44025d71c9b7f260076a932935d3bba95James Smart *
385e59058c44025d71c9b7f260076a932935d3bba95James Smart * Notes: Not interrupt-safe.  Must be called with no locks held.
386e59058c44025d71c9b7f260076a932935d3bba95James Smart *
387e59058c44025d71c9b7f260076a932935d3bba95James Smart * Returns:
388e59058c44025d71c9b7f260076a932935d3bba95James Smart *   pointer to HBQ on success
389e59058c44025d71c9b7f260076a932935d3bba95James Smart *   NULL on failure
390e59058c44025d71c9b7f260076a932935d3bba95James Smart **/
39151ef4c26891a734bc8416b639ad460a8162926bcJames Smartstruct hbq_dmabuf *
39251ef4c26891a734bc8416b639ad460a8162926bcJames Smartlpfc_els_hbq_alloc(struct lpfc_hba *phba)
393ed957684294618602b48f1950b0c9bbcb036583fJames Smart{
39451ef4c26891a734bc8416b639ad460a8162926bcJames Smart	struct hbq_dmabuf *hbqbp;
39551ef4c26891a734bc8416b639ad460a8162926bcJames Smart
39651ef4c26891a734bc8416b639ad460a8162926bcJames Smart	hbqbp = kmalloc(sizeof(struct hbq_dmabuf), GFP_KERNEL);
39751ef4c26891a734bc8416b639ad460a8162926bcJames Smart	if (!hbqbp)
39851ef4c26891a734bc8416b639ad460a8162926bcJames Smart		return NULL;
39951ef4c26891a734bc8416b639ad460a8162926bcJames Smart
4008568a4d2495ebcf5da38a2141c7633399143b1a5James Smart	hbqbp->dbuf.virt = pci_pool_alloc(phba->lpfc_hbq_pool, GFP_KERNEL,
40151ef4c26891a734bc8416b639ad460a8162926bcJames Smart					  &hbqbp->dbuf.phys);
40251ef4c26891a734bc8416b639ad460a8162926bcJames Smart	if (!hbqbp->dbuf.virt) {
40351ef4c26891a734bc8416b639ad460a8162926bcJames Smart		kfree(hbqbp);
40451ef4c26891a734bc8416b639ad460a8162926bcJames Smart		return NULL;
40551ef4c26891a734bc8416b639ad460a8162926bcJames Smart	}
40651ef4c26891a734bc8416b639ad460a8162926bcJames Smart	hbqbp->size = LPFC_BPL_SIZE;
40751ef4c26891a734bc8416b639ad460a8162926bcJames Smart	return hbqbp;
408ed957684294618602b48f1950b0c9bbcb036583fJames Smart}
409ed957684294618602b48f1950b0c9bbcb036583fJames Smart
410e59058c44025d71c9b7f260076a932935d3bba95James Smart/**
411da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart * lpfc_els_hbq_free - Frees an HBQ buffer allocated with lpfc_els_hbq_alloc
412e59058c44025d71c9b7f260076a932935d3bba95James Smart * @phba: HBA buffer was allocated for
413e59058c44025d71c9b7f260076a932935d3bba95James Smart * @hbqbp: HBQ container returned by lpfc_els_hbq_alloc
414e59058c44025d71c9b7f260076a932935d3bba95James Smart *
415e59058c44025d71c9b7f260076a932935d3bba95James Smart * Description: Frees both the container and the DMA-mapped buffer returned by
416e59058c44025d71c9b7f260076a932935d3bba95James Smart * lpfc_els_hbq_alloc.
417e59058c44025d71c9b7f260076a932935d3bba95James Smart *
418e59058c44025d71c9b7f260076a932935d3bba95James Smart * Notes: Can be called with or without locks held.
419e59058c44025d71c9b7f260076a932935d3bba95James Smart *
420e59058c44025d71c9b7f260076a932935d3bba95James Smart * Returns: None
421e59058c44025d71c9b7f260076a932935d3bba95James Smart **/
422ed957684294618602b48f1950b0c9bbcb036583fJames Smartvoid
42351ef4c26891a734bc8416b639ad460a8162926bcJames Smartlpfc_els_hbq_free(struct lpfc_hba *phba, struct hbq_dmabuf *hbqbp)
424ed957684294618602b48f1950b0c9bbcb036583fJames Smart{
4258568a4d2495ebcf5da38a2141c7633399143b1a5James Smart	pci_pool_free(phba->lpfc_hbq_pool, hbqbp->dbuf.virt, hbqbp->dbuf.phys);
42651ef4c26891a734bc8416b639ad460a8162926bcJames Smart	kfree(hbqbp);
427ed957684294618602b48f1950b0c9bbcb036583fJames Smart	return;
428ed957684294618602b48f1950b0c9bbcb036583fJames Smart}
429ed957684294618602b48f1950b0c9bbcb036583fJames Smart
430e59058c44025d71c9b7f260076a932935d3bba95James Smart/**
431da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart * lpfc_sli4_rb_alloc - Allocate an SLI4 Receive buffer
432da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart * @phba: HBA to allocate a receive buffer for
433da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart *
434da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart * Description: Allocates a DMA-mapped receive buffer from the lpfc_hrb_pool PCI
435da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart * pool along a non-DMA-mapped container for it.
436da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart *
437da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart * Notes: Not interrupt-safe.  Must be called with no locks held.
438da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart *
439da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart * Returns:
440da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart *   pointer to HBQ on success
441da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart *   NULL on failure
442da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart **/
443da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smartstruct hbq_dmabuf *
444da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smartlpfc_sli4_rb_alloc(struct lpfc_hba *phba)
445da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart{
446da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	struct hbq_dmabuf *dma_buf;
447da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart
448da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	dma_buf = kmalloc(sizeof(struct hbq_dmabuf), GFP_KERNEL);
449da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	if (!dma_buf)
450da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart		return NULL;
451da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart
452da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	dma_buf->hbuf.virt = pci_pool_alloc(phba->lpfc_hrb_pool, GFP_KERNEL,
453da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart					    &dma_buf->hbuf.phys);
454da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	if (!dma_buf->hbuf.virt) {
455da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart		kfree(dma_buf);
456da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart		return NULL;
457da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	}
458da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	dma_buf->dbuf.virt = pci_pool_alloc(phba->lpfc_drb_pool, GFP_KERNEL,
459da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart					    &dma_buf->dbuf.phys);
460da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	if (!dma_buf->dbuf.virt) {
461da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart		pci_pool_free(phba->lpfc_hrb_pool, dma_buf->hbuf.virt,
462da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart			      dma_buf->hbuf.phys);
463da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart		kfree(dma_buf);
464da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart		return NULL;
465da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	}
466da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	dma_buf->size = LPFC_BPL_SIZE;
467da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	return dma_buf;
468da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart}
469da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart
470da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart/**
471da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart * lpfc_sli4_rb_free - Frees a receive buffer
472da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart * @phba: HBA buffer was allocated for
473da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart * @dmab: DMA Buffer container returned by lpfc_sli4_hbq_alloc
474da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart *
475da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart * Description: Frees both the container and the DMA-mapped buffers returned by
476da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart * lpfc_sli4_rb_alloc.
477da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart *
478da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart * Notes: Can be called with or without locks held.
479da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart *
480da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart * Returns: None
481da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart **/
482da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smartvoid
483da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smartlpfc_sli4_rb_free(struct lpfc_hba *phba, struct hbq_dmabuf *dmab)
484da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart{
485da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	pci_pool_free(phba->lpfc_hrb_pool, dmab->hbuf.virt, dmab->hbuf.phys);
486da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	pci_pool_free(phba->lpfc_drb_pool, dmab->dbuf.virt, dmab->dbuf.phys);
487da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	kfree(dmab);
488da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	return;
489da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart}
490da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart
491da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart/**
4923621a710a7dbb2d22a8e95d94bcf0c2d13ef57fcJames Smart * lpfc_in_buf_free - Free a DMA buffer
493e59058c44025d71c9b7f260076a932935d3bba95James Smart * @phba: HBA buffer is associated with
494e59058c44025d71c9b7f260076a932935d3bba95James Smart * @mp: Buffer to free
495e59058c44025d71c9b7f260076a932935d3bba95James Smart *
496e59058c44025d71c9b7f260076a932935d3bba95James Smart * Description: Frees the given DMA buffer in the appropriate way given if the
497e59058c44025d71c9b7f260076a932935d3bba95James Smart * HBA is running in SLI3 mode with HBQs enabled.
498e59058c44025d71c9b7f260076a932935d3bba95James Smart *
499e59058c44025d71c9b7f260076a932935d3bba95James Smart * Notes: Takes phba->hbalock.  Can be called with or without other locks held.
500e59058c44025d71c9b7f260076a932935d3bba95James Smart *
501e59058c44025d71c9b7f260076a932935d3bba95James Smart * Returns: None
502e59058c44025d71c9b7f260076a932935d3bba95James Smart **/
50392d7f7b0cde3ad2260e7462b40867b57efd49851James Smartvoid
50492d7f7b0cde3ad2260e7462b40867b57efd49851James Smartlpfc_in_buf_free(struct lpfc_hba *phba, struct lpfc_dmabuf *mp)
50592d7f7b0cde3ad2260e7462b40867b57efd49851James Smart{
50692d7f7b0cde3ad2260e7462b40867b57efd49851James Smart	struct hbq_dmabuf *hbq_entry;
5073163f725a5d071eea1830bbbfab78cfe3fc9baafJames Smart	unsigned long flags;
50892d7f7b0cde3ad2260e7462b40867b57efd49851James Smart
5097f5f3d0d02aa2f124e764aee5c775589ce72fd42James Smart	if (!mp)
5107f5f3d0d02aa2f124e764aee5c775589ce72fd42James Smart		return;
5117f5f3d0d02aa2f124e764aee5c775589ce72fd42James Smart
51292d7f7b0cde3ad2260e7462b40867b57efd49851James Smart	if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) {
5133163f725a5d071eea1830bbbfab78cfe3fc9baafJames Smart		/* Check whether HBQ is still in use */
5143163f725a5d071eea1830bbbfab78cfe3fc9baafJames Smart		spin_lock_irqsave(&phba->hbalock, flags);
5153163f725a5d071eea1830bbbfab78cfe3fc9baafJames Smart		if (!phba->hbq_in_use) {
5163163f725a5d071eea1830bbbfab78cfe3fc9baafJames Smart			spin_unlock_irqrestore(&phba->hbalock, flags);
5173163f725a5d071eea1830bbbfab78cfe3fc9baafJames Smart			return;
5183163f725a5d071eea1830bbbfab78cfe3fc9baafJames Smart		}
51992d7f7b0cde3ad2260e7462b40867b57efd49851James Smart		hbq_entry = container_of(mp, struct hbq_dmabuf, dbuf);
5203163f725a5d071eea1830bbbfab78cfe3fc9baafJames Smart		list_del(&hbq_entry->dbuf.list);
52192d7f7b0cde3ad2260e7462b40867b57efd49851James Smart		if (hbq_entry->tag == -1) {
52251ef4c26891a734bc8416b639ad460a8162926bcJames Smart			(phba->hbqs[LPFC_ELS_HBQ].hbq_free_buffer)
52351ef4c26891a734bc8416b639ad460a8162926bcJames Smart				(phba, hbq_entry);
52492d7f7b0cde3ad2260e7462b40867b57efd49851James Smart		} else {
52592d7f7b0cde3ad2260e7462b40867b57efd49851James Smart			lpfc_sli_free_hbq(phba, hbq_entry);
52692d7f7b0cde3ad2260e7462b40867b57efd49851James Smart		}
5273163f725a5d071eea1830bbbfab78cfe3fc9baafJames Smart		spin_unlock_irqrestore(&phba->hbalock, flags);
52892d7f7b0cde3ad2260e7462b40867b57efd49851James Smart	} else {
52992d7f7b0cde3ad2260e7462b40867b57efd49851James Smart		lpfc_mbuf_free(phba, mp->virt, mp->phys);
53092d7f7b0cde3ad2260e7462b40867b57efd49851James Smart		kfree(mp);
53192d7f7b0cde3ad2260e7462b40867b57efd49851James Smart	}
53292d7f7b0cde3ad2260e7462b40867b57efd49851James Smart	return;
53392d7f7b0cde3ad2260e7462b40867b57efd49851James Smart}
534