lpfc_mem.c revision cff261f6bd03612e792e4c8872c6ad049f743863
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.                                *
421a688cdfa2f48ca9132cf152b0cb7274cb37b98James Smart * Copyright (C) 2004-2012 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>
235a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h>
24dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>#include <linux/pci.h>
25dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>#include <linux/interrupt.h>
26dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>
27f888ba3ce77c66bece3d804caf7d559838209a4aJames.Smart@Emulex.Com#include <scsi/scsi_device.h>
28f888ba3ce77c66bece3d804caf7d559838209a4aJames.Smart@Emulex.Com#include <scsi/scsi_transport_fc.h>
29f888ba3ce77c66bece3d804caf7d559838209a4aJames.Smart@Emulex.Com
30918865230e55b1fece2d8edec39d46c00626590bJames.Smart@Emulex.Com#include <scsi/scsi.h>
31918865230e55b1fece2d8edec39d46c00626590bJames.Smart@Emulex.Com
32da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart#include "lpfc_hw4.h"
33dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>#include "lpfc_hw.h"
34dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>#include "lpfc_sli.h"
35da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart#include "lpfc_sli4.h"
36ea2151b4e142fa2de0319d9dd80413a997bf435aJames Smart#include "lpfc_nl.h"
37dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>#include "lpfc_disc.h"
38dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>#include "lpfc_scsi.h"
39dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>#include "lpfc.h"
40dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>#include "lpfc_crtn.h"
41cff261f6bd03612e792e4c8872c6ad049f743863James Smart#include "lpfc_logmsg.h"
42dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>
43dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>#define LPFC_MBUF_POOL_SIZE     64      /* max elements in MBUF safety pool */
44dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>#define LPFC_MEM_POOL_SIZE      64      /* max elem in non-DMA safety pool */
45dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>
46cff261f6bd03612e792e4c8872c6ad049f743863James Smartint
47cff261f6bd03612e792e4c8872c6ad049f743863James Smartlpfc_mem_alloc_active_rrq_pool_s4(struct lpfc_hba *phba) {
48cff261f6bd03612e792e4c8872c6ad049f743863James Smart	size_t bytes;
49cff261f6bd03612e792e4c8872c6ad049f743863James Smart	int max_xri = phba->sli4_hba.max_cfg_param.max_xri;
50cff261f6bd03612e792e4c8872c6ad049f743863James Smart
51cff261f6bd03612e792e4c8872c6ad049f743863James Smart	if (max_xri <= 0)
52cff261f6bd03612e792e4c8872c6ad049f743863James Smart		return -ENOMEM;
53cff261f6bd03612e792e4c8872c6ad049f743863James Smart	bytes = ((BITS_PER_LONG - 1 + max_xri) / BITS_PER_LONG) *
54cff261f6bd03612e792e4c8872c6ad049f743863James Smart		  sizeof(unsigned long);
55cff261f6bd03612e792e4c8872c6ad049f743863James Smart	phba->cfg_rrq_xri_bitmap_sz = bytes;
56cff261f6bd03612e792e4c8872c6ad049f743863James Smart	phba->active_rrq_pool = mempool_create_kmalloc_pool(LPFC_MEM_POOL_SIZE,
57cff261f6bd03612e792e4c8872c6ad049f743863James Smart							    bytes);
58cff261f6bd03612e792e4c8872c6ad049f743863James Smart	if (!phba->active_rrq_pool)
59cff261f6bd03612e792e4c8872c6ad049f743863James Smart		return -ENOMEM;
60cff261f6bd03612e792e4c8872c6ad049f743863James Smart	else
61cff261f6bd03612e792e4c8872c6ad049f743863James Smart		return 0;
62cff261f6bd03612e792e4c8872c6ad049f743863James Smart}
632e0fef85e098f6794956b8b80b111179fbb4cbb7James Smart
64e59058c44025d71c9b7f260076a932935d3bba95James Smart/**
653621a710a7dbb2d22a8e95d94bcf0c2d13ef57fcJames Smart * lpfc_mem_alloc - create and allocate all PCI and memory pools
66e59058c44025d71c9b7f260076a932935d3bba95James Smart * @phba: HBA to allocate pools for
67e59058c44025d71c9b7f260076a932935d3bba95James Smart *
68e59058c44025d71c9b7f260076a932935d3bba95James Smart * Description: Creates and allocates PCI pools lpfc_scsi_dma_buf_pool,
69da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart * lpfc_mbuf_pool, lpfc_hrb_pool.  Creates and allocates kmalloc-backed mempools
70e59058c44025d71c9b7f260076a932935d3bba95James Smart * for LPFC_MBOXQ_t and lpfc_nodelist.  Also allocates the VPI bitmask.
71e59058c44025d71c9b7f260076a932935d3bba95James Smart *
72e59058c44025d71c9b7f260076a932935d3bba95James Smart * Notes: Not interrupt-safe.  Must be called with no locks held.  If any
73e59058c44025d71c9b7f260076a932935d3bba95James Smart * allocation fails, frees all successfully allocated memory before returning.
74e59058c44025d71c9b7f260076a932935d3bba95James Smart *
75e59058c44025d71c9b7f260076a932935d3bba95James Smart * Returns:
76e59058c44025d71c9b7f260076a932935d3bba95James Smart *   0 on success
77e59058c44025d71c9b7f260076a932935d3bba95James Smart *   -ENOMEM on failure (if any memory allocations fail)
78e59058c44025d71c9b7f260076a932935d3bba95James Smart **/
79dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>int
80da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smartlpfc_mem_alloc(struct lpfc_hba *phba, int align)
81dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>{
82dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>	struct lpfc_dma_pool *pool = &phba->lpfc_mbuf_safety_pool;
83dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>	int i;
84dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>
8596f7077f671254e957a2815e54bb20e8d50f0bbcJames Smart	if (phba->sli_rev == LPFC_SLI_REV4) {
8696f7077f671254e957a2815e54bb20e8d50f0bbcJames Smart		/* Calculate alignment */
8796f7077f671254e957a2815e54bb20e8d50f0bbcJames Smart		if (phba->cfg_sg_dma_buf_size < SLI4_PAGE_SIZE)
8896f7077f671254e957a2815e54bb20e8d50f0bbcJames Smart			i = phba->cfg_sg_dma_buf_size;
8996f7077f671254e957a2815e54bb20e8d50f0bbcJames Smart		else
9096f7077f671254e957a2815e54bb20e8d50f0bbcJames Smart			i = SLI4_PAGE_SIZE;
9196f7077f671254e957a2815e54bb20e8d50f0bbcJames Smart
92da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart		phba->lpfc_scsi_dma_buf_pool =
93da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart			pci_pool_create("lpfc_scsi_dma_buf_pool",
94da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart				phba->pcidev,
95da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart				phba->cfg_sg_dma_buf_size,
9696f7077f671254e957a2815e54bb20e8d50f0bbcJames Smart				i,
97da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart				0);
9896f7077f671254e957a2815e54bb20e8d50f0bbcJames Smart	} else {
99da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart		phba->lpfc_scsi_dma_buf_pool =
100da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart			pci_pool_create("lpfc_scsi_dma_buf_pool",
101da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart				phba->pcidev, phba->cfg_sg_dma_buf_size,
102da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart				align, 0);
10396f7077f671254e957a2815e54bb20e8d50f0bbcJames Smart	}
10496f7077f671254e957a2815e54bb20e8d50f0bbcJames Smart
105dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>	if (!phba->lpfc_scsi_dma_buf_pool)
106dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>		goto fail;
107dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>
108dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>	phba->lpfc_mbuf_pool = pci_pool_create("lpfc_mbuf_pool", phba->pcidev,
109da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart							LPFC_BPL_SIZE,
110da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart							align, 0);
111dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>	if (!phba->lpfc_mbuf_pool)
112dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>		goto fail_free_dma_buf_pool;
113dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>
114dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>	pool->elements = kmalloc(sizeof(struct lpfc_dmabuf) *
115dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>					 LPFC_MBUF_POOL_SIZE, GFP_KERNEL);
116a96e0c7798057dd8055d0263c076fed975c10237Mariusz Kozlowski	if (!pool->elements)
117a96e0c7798057dd8055d0263c076fed975c10237Mariusz Kozlowski		goto fail_free_lpfc_mbuf_pool;
118a96e0c7798057dd8055d0263c076fed975c10237Mariusz Kozlowski
119dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>	pool->max_count = 0;
120dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>	pool->current_count = 0;
121dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>	for ( i = 0; i < LPFC_MBUF_POOL_SIZE; i++) {
122dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>		pool->elements[i].virt = pci_pool_alloc(phba->lpfc_mbuf_pool,
123dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>				       GFP_KERNEL, &pool->elements[i].phys);
124dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>		if (!pool->elements[i].virt)
125dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>			goto fail_free_mbuf_pool;
126dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>		pool->max_count++;
127dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>		pool->current_count++;
128dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>	}
129dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>
1300eaae62abaa1ad1f231932b6cdd9fb1b91df6651Matthew Dobson	phba->mbox_mem_pool = mempool_create_kmalloc_pool(LPFC_MEM_POOL_SIZE,
1310eaae62abaa1ad1f231932b6cdd9fb1b91df6651Matthew Dobson							 sizeof(LPFC_MBOXQ_t));
132dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>	if (!phba->mbox_mem_pool)
133dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>		goto fail_free_mbuf_pool;
134dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>
1350eaae62abaa1ad1f231932b6cdd9fb1b91df6651Matthew Dobson	phba->nlp_mem_pool = mempool_create_kmalloc_pool(LPFC_MEM_POOL_SIZE,
1360eaae62abaa1ad1f231932b6cdd9fb1b91df6651Matthew Dobson						sizeof(struct lpfc_nodelist));
137dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>	if (!phba->nlp_mem_pool)
138dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>		goto fail_free_mbox_pool;
1398568a4d2495ebcf5da38a2141c7633399143b1a5James Smart
1408568a4d2495ebcf5da38a2141c7633399143b1a5James Smart	if (phba->sli_rev == LPFC_SLI_REV4) {
14119ca760979e4be41a3eb215fb8d0e96637161947James Smart		phba->rrq_pool =
14219ca760979e4be41a3eb215fb8d0e96637161947James Smart			mempool_create_kmalloc_pool(LPFC_MEM_POOL_SIZE,
14319ca760979e4be41a3eb215fb8d0e96637161947James Smart						sizeof(struct lpfc_node_rrq));
14419ca760979e4be41a3eb215fb8d0e96637161947James Smart		if (!phba->rrq_pool)
14519ca760979e4be41a3eb215fb8d0e96637161947James Smart			goto fail_free_nlp_mem_pool;
1468568a4d2495ebcf5da38a2141c7633399143b1a5James Smart		phba->lpfc_hrb_pool = pci_pool_create("lpfc_hrb_pool",
147da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart					      phba->pcidev,
148da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart					      LPFC_HDR_BUF_SIZE, align, 0);
1498568a4d2495ebcf5da38a2141c7633399143b1a5James Smart		if (!phba->lpfc_hrb_pool)
15019ca760979e4be41a3eb215fb8d0e96637161947James Smart			goto fail_free_rrq_mem_pool;
1518568a4d2495ebcf5da38a2141c7633399143b1a5James Smart
1528568a4d2495ebcf5da38a2141c7633399143b1a5James Smart		phba->lpfc_drb_pool = pci_pool_create("lpfc_drb_pool",
153da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart					      phba->pcidev,
154da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart					      LPFC_DATA_BUF_SIZE, align, 0);
1558568a4d2495ebcf5da38a2141c7633399143b1a5James Smart		if (!phba->lpfc_drb_pool)
1568568a4d2495ebcf5da38a2141c7633399143b1a5James Smart			goto fail_free_hrb_pool;
1578568a4d2495ebcf5da38a2141c7633399143b1a5James Smart		phba->lpfc_hbq_pool = NULL;
1588568a4d2495ebcf5da38a2141c7633399143b1a5James Smart	} else {
1598568a4d2495ebcf5da38a2141c7633399143b1a5James Smart		phba->lpfc_hbq_pool = pci_pool_create("lpfc_hbq_pool",
1608568a4d2495ebcf5da38a2141c7633399143b1a5James Smart			phba->pcidev, LPFC_BPL_SIZE, align, 0);
1618568a4d2495ebcf5da38a2141c7633399143b1a5James Smart		if (!phba->lpfc_hbq_pool)
1628568a4d2495ebcf5da38a2141c7633399143b1a5James Smart			goto fail_free_nlp_mem_pool;
1638568a4d2495ebcf5da38a2141c7633399143b1a5James Smart		phba->lpfc_hrb_pool = NULL;
1648568a4d2495ebcf5da38a2141c7633399143b1a5James Smart		phba->lpfc_drb_pool = NULL;
1658568a4d2495ebcf5da38a2141c7633399143b1a5James Smart	}
16692d7f7b0cde3ad2260e7462b40867b57efd49851James Smart
167dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>	return 0;
1688568a4d2495ebcf5da38a2141c7633399143b1a5James Smart fail_free_hrb_pool:
169da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	pci_pool_destroy(phba->lpfc_hrb_pool);
170da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	phba->lpfc_hrb_pool = NULL;
17119ca760979e4be41a3eb215fb8d0e96637161947James Smart fail_free_rrq_mem_pool:
17219ca760979e4be41a3eb215fb8d0e96637161947James Smart	mempool_destroy(phba->rrq_pool);
17319ca760979e4be41a3eb215fb8d0e96637161947James Smart	phba->rrq_pool = NULL;
174ed957684294618602b48f1950b0c9bbcb036583fJames Smart fail_free_nlp_mem_pool:
175ed957684294618602b48f1950b0c9bbcb036583fJames Smart	mempool_destroy(phba->nlp_mem_pool);
176ed957684294618602b48f1950b0c9bbcb036583fJames Smart	phba->nlp_mem_pool = NULL;
177dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com> fail_free_mbox_pool:
178dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>	mempool_destroy(phba->mbox_mem_pool);
1792e0fef85e098f6794956b8b80b111179fbb4cbb7James Smart	phba->mbox_mem_pool = NULL;
180dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com> fail_free_mbuf_pool:
181a96e0c7798057dd8055d0263c076fed975c10237Mariusz Kozlowski	while (i--)
182dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>		pci_pool_free(phba->lpfc_mbuf_pool, pool->elements[i].virt,
183dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>						 pool->elements[i].phys);
184dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>	kfree(pool->elements);
185a96e0c7798057dd8055d0263c076fed975c10237Mariusz Kozlowski fail_free_lpfc_mbuf_pool:
186dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>	pci_pool_destroy(phba->lpfc_mbuf_pool);
1872e0fef85e098f6794956b8b80b111179fbb4cbb7James Smart	phba->lpfc_mbuf_pool = NULL;
188dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com> fail_free_dma_buf_pool:
189dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>	pci_pool_destroy(phba->lpfc_scsi_dma_buf_pool);
1902e0fef85e098f6794956b8b80b111179fbb4cbb7James Smart	phba->lpfc_scsi_dma_buf_pool = NULL;
191dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com> fail:
192dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>	return -ENOMEM;
193dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>}
194dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>
195e59058c44025d71c9b7f260076a932935d3bba95James Smart/**
196da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart * lpfc_mem_free - Frees memory allocated by lpfc_mem_alloc
197e59058c44025d71c9b7f260076a932935d3bba95James Smart * @phba: HBA to free memory for
198e59058c44025d71c9b7f260076a932935d3bba95James Smart *
199da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart * Description: Free the memory allocated by lpfc_mem_alloc routine. This
200da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart * routine is a the counterpart of lpfc_mem_alloc.
201e59058c44025d71c9b7f260076a932935d3bba95James Smart *
202e59058c44025d71c9b7f260076a932935d3bba95James Smart * Returns: None
203e59058c44025d71c9b7f260076a932935d3bba95James Smart **/
204dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>void
205da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smartlpfc_mem_free(struct lpfc_hba *phba)
206dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>{
207dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>	int i;
208da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	struct lpfc_dma_pool *pool = &phba->lpfc_mbuf_safety_pool;
209dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>
210da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	/* Free HBQ pools */
211ed957684294618602b48f1950b0c9bbcb036583fJames Smart	lpfc_sli_hbqbuf_free_all(phba);
2128568a4d2495ebcf5da38a2141c7633399143b1a5James Smart	if (phba->lpfc_drb_pool)
2138568a4d2495ebcf5da38a2141c7633399143b1a5James Smart		pci_pool_destroy(phba->lpfc_drb_pool);
214da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	phba->lpfc_drb_pool = NULL;
2158568a4d2495ebcf5da38a2141c7633399143b1a5James Smart	if (phba->lpfc_hrb_pool)
2168568a4d2495ebcf5da38a2141c7633399143b1a5James Smart		pci_pool_destroy(phba->lpfc_hrb_pool);
217da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	phba->lpfc_hrb_pool = NULL;
218da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart
2198568a4d2495ebcf5da38a2141c7633399143b1a5James Smart	if (phba->lpfc_hbq_pool)
2208568a4d2495ebcf5da38a2141c7633399143b1a5James Smart		pci_pool_destroy(phba->lpfc_hbq_pool);
2218568a4d2495ebcf5da38a2141c7633399143b1a5James Smart	phba->lpfc_hbq_pool = NULL;
2228568a4d2495ebcf5da38a2141c7633399143b1a5James Smart
22321a688cdfa2f48ca9132cf152b0cb7274cb37b98James Smart	if (phba->rrq_pool)
22421a688cdfa2f48ca9132cf152b0cb7274cb37b98James Smart		mempool_destroy(phba->rrq_pool);
22521a688cdfa2f48ca9132cf152b0cb7274cb37b98James Smart	phba->rrq_pool = NULL;
22621a688cdfa2f48ca9132cf152b0cb7274cb37b98James Smart
227da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	/* Free NLP memory pool */
228da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	mempool_destroy(phba->nlp_mem_pool);
229da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	phba->nlp_mem_pool = NULL;
230cff261f6bd03612e792e4c8872c6ad049f743863James Smart	if (phba->sli_rev == LPFC_SLI_REV4 && phba->active_rrq_pool) {
231cff261f6bd03612e792e4c8872c6ad049f743863James Smart		mempool_destroy(phba->active_rrq_pool);
232cff261f6bd03612e792e4c8872c6ad049f743863James Smart		phba->active_rrq_pool = NULL;
233cff261f6bd03612e792e4c8872c6ad049f743863James Smart	}
234da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart
235da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	/* Free mbox memory pool */
236da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	mempool_destroy(phba->mbox_mem_pool);
237da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	phba->mbox_mem_pool = NULL;
238da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart
239da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	/* Free MBUF memory pool */
240da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	for (i = 0; i < pool->current_count; i++)
241da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart		pci_pool_free(phba->lpfc_mbuf_pool, pool->elements[i].virt,
242da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart			      pool->elements[i].phys);
243da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	kfree(pool->elements);
244da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart
245da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	pci_pool_destroy(phba->lpfc_mbuf_pool);
246da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	phba->lpfc_mbuf_pool = NULL;
247ed957684294618602b48f1950b0c9bbcb036583fJames Smart
248da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	/* Free DMA buffer memory pool */
249da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	pci_pool_destroy(phba->lpfc_scsi_dma_buf_pool);
250da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	phba->lpfc_scsi_dma_buf_pool = NULL;
251da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart
252da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	return;
253da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart}
254da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart
255da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart/**
256da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart * lpfc_mem_free_all - Frees all PCI and driver memory
257da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart * @phba: HBA to free memory for
258da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart *
259da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart * Description: Free memory from PCI and driver memory pools and also those
260da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart * used : lpfc_scsi_dma_buf_pool, lpfc_mbuf_pool, lpfc_hrb_pool. Frees
261da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart * kmalloc-backed mempools for LPFC_MBOXQ_t and lpfc_nodelist. Also frees
262da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart * the VPI bitmask.
263da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart *
264da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart * Returns: None
265da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart **/
266da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smartvoid
267da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smartlpfc_mem_free_all(struct lpfc_hba *phba)
268da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart{
269da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	struct lpfc_sli *psli = &phba->sli;
270da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	LPFC_MBOXQ_t *mbox, *next_mbox;
271da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	struct lpfc_dmabuf   *mp;
272da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart
273da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	/* Free memory used in mailbox queue back to mailbox memory pool */
274dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>	list_for_each_entry_safe(mbox, next_mbox, &psli->mboxq, list) {
275dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>		mp = (struct lpfc_dmabuf *) (mbox->context1);
276dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>		if (mp) {
277dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>			lpfc_mbuf_free(phba, mp->virt, mp->phys);
278dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>			kfree(mp);
279dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>		}
280dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>		list_del(&mbox->list);
281dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>		mempool_free(mbox, phba->mbox_mem_pool);
282dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>	}
283da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	/* Free memory used in mailbox cmpl list back to mailbox memory pool */
28492d7f7b0cde3ad2260e7462b40867b57efd49851James Smart	list_for_each_entry_safe(mbox, next_mbox, &psli->mboxq_cmpl, list) {
28592d7f7b0cde3ad2260e7462b40867b57efd49851James Smart		mp = (struct lpfc_dmabuf *) (mbox->context1);
28692d7f7b0cde3ad2260e7462b40867b57efd49851James Smart		if (mp) {
28792d7f7b0cde3ad2260e7462b40867b57efd49851James Smart			lpfc_mbuf_free(phba, mp->virt, mp->phys);
28892d7f7b0cde3ad2260e7462b40867b57efd49851James Smart			kfree(mp);
28992d7f7b0cde3ad2260e7462b40867b57efd49851James Smart		}
29092d7f7b0cde3ad2260e7462b40867b57efd49851James Smart		list_del(&mbox->list);
29192d7f7b0cde3ad2260e7462b40867b57efd49851James Smart		mempool_free(mbox, phba->mbox_mem_pool);
29292d7f7b0cde3ad2260e7462b40867b57efd49851James Smart	}
293da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	/* Free the active mailbox command back to the mailbox memory pool */
294da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	spin_lock_irq(&phba->hbalock);
295dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>	psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE;
296da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	spin_unlock_irq(&phba->hbalock);
297dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>	if (psli->mbox_active) {
298dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>		mbox = psli->mbox_active;
299dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>		mp = (struct lpfc_dmabuf *) (mbox->context1);
300dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>		if (mp) {
301dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>			lpfc_mbuf_free(phba, mp->virt, mp->phys);
302dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>			kfree(mp);
303dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>		}
304dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>		mempool_free(mbox, phba->mbox_mem_pool);
305dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>		psli->mbox_active = NULL;
306dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>	}
307dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>
308da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	/* Free and destroy all the allocated memory pools */
309da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	lpfc_mem_free(phba);
3102e0fef85e098f6794956b8b80b111179fbb4cbb7James Smart
311e59058c44025d71c9b7f260076a932935d3bba95James Smart	/* Free the iocb lookup array */
3129f49d3b05f092b89e774be20c654ceb0c64a7d19James Smart	kfree(psli->iocbq_lookup);
3139f49d3b05f092b89e774be20c654ceb0c64a7d19James Smart	psli->iocbq_lookup = NULL;
314da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart
315da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	return;
316dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>}
317dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>
318e59058c44025d71c9b7f260076a932935d3bba95James Smart/**
3193621a710a7dbb2d22a8e95d94bcf0c2d13ef57fcJames Smart * lpfc_mbuf_alloc - Allocate an mbuf from the lpfc_mbuf_pool PCI pool
320e59058c44025d71c9b7f260076a932935d3bba95James Smart * @phba: HBA which owns the pool to allocate from
321e59058c44025d71c9b7f260076a932935d3bba95James Smart * @mem_flags: indicates if this is a priority (MEM_PRI) allocation
322e59058c44025d71c9b7f260076a932935d3bba95James Smart * @handle: used to return the DMA-mapped address of the mbuf
323e59058c44025d71c9b7f260076a932935d3bba95James Smart *
324e59058c44025d71c9b7f260076a932935d3bba95James Smart * Description: Allocates a DMA-mapped buffer from the lpfc_mbuf_pool PCI pool.
325e59058c44025d71c9b7f260076a932935d3bba95James Smart * Allocates from generic pci_pool_alloc function first and if that fails and
326e59058c44025d71c9b7f260076a932935d3bba95James Smart * mem_flags has MEM_PRI set (the only defined flag), returns an mbuf from the
327e59058c44025d71c9b7f260076a932935d3bba95James Smart * HBA's pool.
328e59058c44025d71c9b7f260076a932935d3bba95James Smart *
329e59058c44025d71c9b7f260076a932935d3bba95James Smart * Notes: Not interrupt-safe.  Must be called with no locks held.  Takes
330e59058c44025d71c9b7f260076a932935d3bba95James Smart * phba->hbalock.
331e59058c44025d71c9b7f260076a932935d3bba95James Smart *
332e59058c44025d71c9b7f260076a932935d3bba95James Smart * Returns:
333e59058c44025d71c9b7f260076a932935d3bba95James Smart *   pointer to the allocated mbuf on success
334e59058c44025d71c9b7f260076a932935d3bba95James Smart *   NULL on failure
335e59058c44025d71c9b7f260076a932935d3bba95James Smart **/
336dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>void *
337dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>lpfc_mbuf_alloc(struct lpfc_hba *phba, int mem_flags, dma_addr_t *handle)
338dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>{
339dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>	struct lpfc_dma_pool *pool = &phba->lpfc_mbuf_safety_pool;
3402e0fef85e098f6794956b8b80b111179fbb4cbb7James Smart	unsigned long iflags;
341dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>	void *ret;
342dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>
343dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>	ret = pci_pool_alloc(phba->lpfc_mbuf_pool, GFP_KERNEL, handle);
344dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>
3452e0fef85e098f6794956b8b80b111179fbb4cbb7James Smart	spin_lock_irqsave(&phba->hbalock, iflags);
34692d7f7b0cde3ad2260e7462b40867b57efd49851James Smart	if (!ret && (mem_flags & MEM_PRI) && pool->current_count) {
347dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>		pool->current_count--;
348dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>		ret = pool->elements[pool->current_count].virt;
349dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>		*handle = pool->elements[pool->current_count].phys;
350dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>	}
3512e0fef85e098f6794956b8b80b111179fbb4cbb7James Smart	spin_unlock_irqrestore(&phba->hbalock, iflags);
352dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>	return ret;
353dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>}
354dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>
355e59058c44025d71c9b7f260076a932935d3bba95James Smart/**
3563621a710a7dbb2d22a8e95d94bcf0c2d13ef57fcJames Smart * __lpfc_mbuf_free - Free an mbuf from the lpfc_mbuf_pool PCI pool (locked)
357e59058c44025d71c9b7f260076a932935d3bba95James Smart * @phba: HBA which owns the pool to return to
358e59058c44025d71c9b7f260076a932935d3bba95James Smart * @virt: mbuf to free
359e59058c44025d71c9b7f260076a932935d3bba95James Smart * @dma: the DMA-mapped address of the lpfc_mbuf_pool to be freed
360e59058c44025d71c9b7f260076a932935d3bba95James Smart *
361e59058c44025d71c9b7f260076a932935d3bba95James Smart * Description: Returns an mbuf lpfc_mbuf_pool to the lpfc_mbuf_safety_pool if
362e59058c44025d71c9b7f260076a932935d3bba95James Smart * it is below its max_count, frees the mbuf otherwise.
363e59058c44025d71c9b7f260076a932935d3bba95James Smart *
364e59058c44025d71c9b7f260076a932935d3bba95James Smart * Notes: Must be called with phba->hbalock held to synchronize access to
365e59058c44025d71c9b7f260076a932935d3bba95James Smart * lpfc_mbuf_safety_pool.
366e59058c44025d71c9b7f260076a932935d3bba95James Smart *
367e59058c44025d71c9b7f260076a932935d3bba95James Smart * Returns: None
368e59058c44025d71c9b7f260076a932935d3bba95James Smart **/
369dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>void
3702e0fef85e098f6794956b8b80b111179fbb4cbb7James Smart__lpfc_mbuf_free(struct lpfc_hba * phba, void *virt, dma_addr_t dma)
371dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>{
372dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>	struct lpfc_dma_pool *pool = &phba->lpfc_mbuf_safety_pool;
373dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>
374dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>	if (pool->current_count < pool->max_count) {
375dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>		pool->elements[pool->current_count].virt = virt;
376dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>		pool->elements[pool->current_count].phys = dma;
377dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>		pool->current_count++;
378dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>	} else {
379dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>		pci_pool_free(phba->lpfc_mbuf_pool, virt, dma);
380dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>	}
381dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>	return;
382dea3101e0a5c897d2c9351a7444e139db9f40247<jejb@titanic.il.steeleye.com>}
3832e0fef85e098f6794956b8b80b111179fbb4cbb7James Smart
384e59058c44025d71c9b7f260076a932935d3bba95James Smart/**
3853621a710a7dbb2d22a8e95d94bcf0c2d13ef57fcJames Smart * lpfc_mbuf_free - Free an mbuf from the lpfc_mbuf_pool PCI pool (unlocked)
386e59058c44025d71c9b7f260076a932935d3bba95James Smart * @phba: HBA which owns the pool to return to
387e59058c44025d71c9b7f260076a932935d3bba95James Smart * @virt: mbuf to free
388e59058c44025d71c9b7f260076a932935d3bba95James Smart * @dma: the DMA-mapped address of the lpfc_mbuf_pool to be freed
389e59058c44025d71c9b7f260076a932935d3bba95James Smart *
390e59058c44025d71c9b7f260076a932935d3bba95James Smart * Description: Returns an mbuf lpfc_mbuf_pool to the lpfc_mbuf_safety_pool if
391e59058c44025d71c9b7f260076a932935d3bba95James Smart * it is below its max_count, frees the mbuf otherwise.
392e59058c44025d71c9b7f260076a932935d3bba95James Smart *
393e59058c44025d71c9b7f260076a932935d3bba95James Smart * Notes: Takes phba->hbalock.  Can be called with or without other locks held.
394e59058c44025d71c9b7f260076a932935d3bba95James Smart *
395e59058c44025d71c9b7f260076a932935d3bba95James Smart * Returns: None
396e59058c44025d71c9b7f260076a932935d3bba95James Smart **/
3972e0fef85e098f6794956b8b80b111179fbb4cbb7James Smartvoid
3982e0fef85e098f6794956b8b80b111179fbb4cbb7James Smartlpfc_mbuf_free(struct lpfc_hba * phba, void *virt, dma_addr_t dma)
3992e0fef85e098f6794956b8b80b111179fbb4cbb7James Smart{
4002e0fef85e098f6794956b8b80b111179fbb4cbb7James Smart	unsigned long iflags;
4012e0fef85e098f6794956b8b80b111179fbb4cbb7James Smart
4022e0fef85e098f6794956b8b80b111179fbb4cbb7James Smart	spin_lock_irqsave(&phba->hbalock, iflags);
4032e0fef85e098f6794956b8b80b111179fbb4cbb7James Smart	__lpfc_mbuf_free(phba, virt, dma);
4042e0fef85e098f6794956b8b80b111179fbb4cbb7James Smart	spin_unlock_irqrestore(&phba->hbalock, iflags);
4052e0fef85e098f6794956b8b80b111179fbb4cbb7James Smart	return;
4062e0fef85e098f6794956b8b80b111179fbb4cbb7James Smart}
407ed957684294618602b48f1950b0c9bbcb036583fJames Smart
408e59058c44025d71c9b7f260076a932935d3bba95James Smart/**
4093621a710a7dbb2d22a8e95d94bcf0c2d13ef57fcJames Smart * lpfc_els_hbq_alloc - Allocate an HBQ buffer
410e59058c44025d71c9b7f260076a932935d3bba95James Smart * @phba: HBA to allocate HBQ buffer for
411e59058c44025d71c9b7f260076a932935d3bba95James Smart *
412da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart * Description: Allocates a DMA-mapped HBQ buffer from the lpfc_hrb_pool PCI
413e59058c44025d71c9b7f260076a932935d3bba95James Smart * pool along a non-DMA-mapped container for it.
414e59058c44025d71c9b7f260076a932935d3bba95James Smart *
415e59058c44025d71c9b7f260076a932935d3bba95James Smart * Notes: Not interrupt-safe.  Must be called with no locks held.
416e59058c44025d71c9b7f260076a932935d3bba95James Smart *
417e59058c44025d71c9b7f260076a932935d3bba95James Smart * Returns:
418e59058c44025d71c9b7f260076a932935d3bba95James Smart *   pointer to HBQ on success
419e59058c44025d71c9b7f260076a932935d3bba95James Smart *   NULL on failure
420e59058c44025d71c9b7f260076a932935d3bba95James Smart **/
42151ef4c26891a734bc8416b639ad460a8162926bcJames Smartstruct hbq_dmabuf *
42251ef4c26891a734bc8416b639ad460a8162926bcJames Smartlpfc_els_hbq_alloc(struct lpfc_hba *phba)
423ed957684294618602b48f1950b0c9bbcb036583fJames Smart{
42451ef4c26891a734bc8416b639ad460a8162926bcJames Smart	struct hbq_dmabuf *hbqbp;
42551ef4c26891a734bc8416b639ad460a8162926bcJames Smart
4262e90f4b5a2a0ce5ab72c0c81c74269bd0a62522bJames Smart	hbqbp = kzalloc(sizeof(struct hbq_dmabuf), GFP_KERNEL);
42751ef4c26891a734bc8416b639ad460a8162926bcJames Smart	if (!hbqbp)
42851ef4c26891a734bc8416b639ad460a8162926bcJames Smart		return NULL;
42951ef4c26891a734bc8416b639ad460a8162926bcJames Smart
4308568a4d2495ebcf5da38a2141c7633399143b1a5James Smart	hbqbp->dbuf.virt = pci_pool_alloc(phba->lpfc_hbq_pool, GFP_KERNEL,
43151ef4c26891a734bc8416b639ad460a8162926bcJames Smart					  &hbqbp->dbuf.phys);
43251ef4c26891a734bc8416b639ad460a8162926bcJames Smart	if (!hbqbp->dbuf.virt) {
43351ef4c26891a734bc8416b639ad460a8162926bcJames Smart		kfree(hbqbp);
43451ef4c26891a734bc8416b639ad460a8162926bcJames Smart		return NULL;
43551ef4c26891a734bc8416b639ad460a8162926bcJames Smart	}
43651ef4c26891a734bc8416b639ad460a8162926bcJames Smart	hbqbp->size = LPFC_BPL_SIZE;
43751ef4c26891a734bc8416b639ad460a8162926bcJames Smart	return hbqbp;
438ed957684294618602b48f1950b0c9bbcb036583fJames Smart}
439ed957684294618602b48f1950b0c9bbcb036583fJames Smart
440e59058c44025d71c9b7f260076a932935d3bba95James Smart/**
441da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart * lpfc_els_hbq_free - Frees an HBQ buffer allocated with lpfc_els_hbq_alloc
442e59058c44025d71c9b7f260076a932935d3bba95James Smart * @phba: HBA buffer was allocated for
443e59058c44025d71c9b7f260076a932935d3bba95James Smart * @hbqbp: HBQ container returned by lpfc_els_hbq_alloc
444e59058c44025d71c9b7f260076a932935d3bba95James Smart *
445e59058c44025d71c9b7f260076a932935d3bba95James Smart * Description: Frees both the container and the DMA-mapped buffer returned by
446e59058c44025d71c9b7f260076a932935d3bba95James Smart * lpfc_els_hbq_alloc.
447e59058c44025d71c9b7f260076a932935d3bba95James Smart *
448e59058c44025d71c9b7f260076a932935d3bba95James Smart * Notes: Can be called with or without locks held.
449e59058c44025d71c9b7f260076a932935d3bba95James Smart *
450e59058c44025d71c9b7f260076a932935d3bba95James Smart * Returns: None
451e59058c44025d71c9b7f260076a932935d3bba95James Smart **/
452ed957684294618602b48f1950b0c9bbcb036583fJames Smartvoid
45351ef4c26891a734bc8416b639ad460a8162926bcJames Smartlpfc_els_hbq_free(struct lpfc_hba *phba, struct hbq_dmabuf *hbqbp)
454ed957684294618602b48f1950b0c9bbcb036583fJames Smart{
4558568a4d2495ebcf5da38a2141c7633399143b1a5James Smart	pci_pool_free(phba->lpfc_hbq_pool, hbqbp->dbuf.virt, hbqbp->dbuf.phys);
45651ef4c26891a734bc8416b639ad460a8162926bcJames Smart	kfree(hbqbp);
457ed957684294618602b48f1950b0c9bbcb036583fJames Smart	return;
458ed957684294618602b48f1950b0c9bbcb036583fJames Smart}
459ed957684294618602b48f1950b0c9bbcb036583fJames Smart
460e59058c44025d71c9b7f260076a932935d3bba95James Smart/**
461da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart * lpfc_sli4_rb_alloc - Allocate an SLI4 Receive buffer
462da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart * @phba: HBA to allocate a receive buffer for
463da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart *
464da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart * Description: Allocates a DMA-mapped receive buffer from the lpfc_hrb_pool PCI
465da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart * pool along a non-DMA-mapped container for it.
466da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart *
467da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart * Notes: Not interrupt-safe.  Must be called with no locks held.
468da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart *
469da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart * Returns:
470da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart *   pointer to HBQ on success
471da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart *   NULL on failure
472da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart **/
473da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smartstruct hbq_dmabuf *
474da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smartlpfc_sli4_rb_alloc(struct lpfc_hba *phba)
475da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart{
476da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	struct hbq_dmabuf *dma_buf;
477da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart
4782e90f4b5a2a0ce5ab72c0c81c74269bd0a62522bJames Smart	dma_buf = kzalloc(sizeof(struct hbq_dmabuf), GFP_KERNEL);
479da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	if (!dma_buf)
480da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart		return NULL;
481da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart
482da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	dma_buf->hbuf.virt = pci_pool_alloc(phba->lpfc_hrb_pool, GFP_KERNEL,
483da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart					    &dma_buf->hbuf.phys);
484da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	if (!dma_buf->hbuf.virt) {
485da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart		kfree(dma_buf);
486da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart		return NULL;
487da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	}
488da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	dma_buf->dbuf.virt = pci_pool_alloc(phba->lpfc_drb_pool, GFP_KERNEL,
489da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart					    &dma_buf->dbuf.phys);
490da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	if (!dma_buf->dbuf.virt) {
491da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart		pci_pool_free(phba->lpfc_hrb_pool, dma_buf->hbuf.virt,
492da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart			      dma_buf->hbuf.phys);
493da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart		kfree(dma_buf);
494da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart		return NULL;
495da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	}
496da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	dma_buf->size = LPFC_BPL_SIZE;
497da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	return dma_buf;
498da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart}
499da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart
500da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart/**
501da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart * lpfc_sli4_rb_free - Frees a receive buffer
502da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart * @phba: HBA buffer was allocated for
503da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart * @dmab: DMA Buffer container returned by lpfc_sli4_hbq_alloc
504da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart *
505da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart * Description: Frees both the container and the DMA-mapped buffers returned by
506da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart * lpfc_sli4_rb_alloc.
507da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart *
508da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart * Notes: Can be called with or without locks held.
509da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart *
510da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart * Returns: None
511da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart **/
512da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smartvoid
513da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smartlpfc_sli4_rb_free(struct lpfc_hba *phba, struct hbq_dmabuf *dmab)
514da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart{
515da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	pci_pool_free(phba->lpfc_hrb_pool, dmab->hbuf.virt, dmab->hbuf.phys);
516da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	pci_pool_free(phba->lpfc_drb_pool, dmab->dbuf.virt, dmab->dbuf.phys);
517da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	kfree(dmab);
518da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart	return;
519da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart}
520da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart
521da0436e915a5c17ee79e72c1bf978a4ebb1cbf4dJames Smart/**
5223621a710a7dbb2d22a8e95d94bcf0c2d13ef57fcJames Smart * lpfc_in_buf_free - Free a DMA buffer
523e59058c44025d71c9b7f260076a932935d3bba95James Smart * @phba: HBA buffer is associated with
524e59058c44025d71c9b7f260076a932935d3bba95James Smart * @mp: Buffer to free
525e59058c44025d71c9b7f260076a932935d3bba95James Smart *
526e59058c44025d71c9b7f260076a932935d3bba95James Smart * Description: Frees the given DMA buffer in the appropriate way given if the
527e59058c44025d71c9b7f260076a932935d3bba95James Smart * HBA is running in SLI3 mode with HBQs enabled.
528e59058c44025d71c9b7f260076a932935d3bba95James Smart *
529e59058c44025d71c9b7f260076a932935d3bba95James Smart * Notes: Takes phba->hbalock.  Can be called with or without other locks held.
530e59058c44025d71c9b7f260076a932935d3bba95James Smart *
531e59058c44025d71c9b7f260076a932935d3bba95James Smart * Returns: None
532e59058c44025d71c9b7f260076a932935d3bba95James Smart **/
53392d7f7b0cde3ad2260e7462b40867b57efd49851James Smartvoid
53492d7f7b0cde3ad2260e7462b40867b57efd49851James Smartlpfc_in_buf_free(struct lpfc_hba *phba, struct lpfc_dmabuf *mp)
53592d7f7b0cde3ad2260e7462b40867b57efd49851James Smart{
53692d7f7b0cde3ad2260e7462b40867b57efd49851James Smart	struct hbq_dmabuf *hbq_entry;
5373163f725a5d071eea1830bbbfab78cfe3fc9baafJames Smart	unsigned long flags;
53892d7f7b0cde3ad2260e7462b40867b57efd49851James Smart
5397f5f3d0d02aa2f124e764aee5c775589ce72fd42James Smart	if (!mp)
5407f5f3d0d02aa2f124e764aee5c775589ce72fd42James Smart		return;
5417f5f3d0d02aa2f124e764aee5c775589ce72fd42James Smart
54292d7f7b0cde3ad2260e7462b40867b57efd49851James Smart	if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) {
5433163f725a5d071eea1830bbbfab78cfe3fc9baafJames Smart		/* Check whether HBQ is still in use */
5443163f725a5d071eea1830bbbfab78cfe3fc9baafJames Smart		spin_lock_irqsave(&phba->hbalock, flags);
5453163f725a5d071eea1830bbbfab78cfe3fc9baafJames Smart		if (!phba->hbq_in_use) {
5463163f725a5d071eea1830bbbfab78cfe3fc9baafJames Smart			spin_unlock_irqrestore(&phba->hbalock, flags);
5473163f725a5d071eea1830bbbfab78cfe3fc9baafJames Smart			return;
5483163f725a5d071eea1830bbbfab78cfe3fc9baafJames Smart		}
54992d7f7b0cde3ad2260e7462b40867b57efd49851James Smart		hbq_entry = container_of(mp, struct hbq_dmabuf, dbuf);
5503163f725a5d071eea1830bbbfab78cfe3fc9baafJames Smart		list_del(&hbq_entry->dbuf.list);
55192d7f7b0cde3ad2260e7462b40867b57efd49851James Smart		if (hbq_entry->tag == -1) {
55251ef4c26891a734bc8416b639ad460a8162926bcJames Smart			(phba->hbqs[LPFC_ELS_HBQ].hbq_free_buffer)
55351ef4c26891a734bc8416b639ad460a8162926bcJames Smart				(phba, hbq_entry);
55492d7f7b0cde3ad2260e7462b40867b57efd49851James Smart		} else {
55592d7f7b0cde3ad2260e7462b40867b57efd49851James Smart			lpfc_sli_free_hbq(phba, hbq_entry);
55692d7f7b0cde3ad2260e7462b40867b57efd49851James Smart		}
5573163f725a5d071eea1830bbbfab78cfe3fc9baafJames Smart		spin_unlock_irqrestore(&phba->hbalock, flags);
55892d7f7b0cde3ad2260e7462b40867b57efd49851James Smart	} else {
55992d7f7b0cde3ad2260e7462b40867b57efd49851James Smart		lpfc_mbuf_free(phba, mp->virt, mp->phys);
56092d7f7b0cde3ad2260e7462b40867b57efd49851James Smart		kfree(mp);
56192d7f7b0cde3ad2260e7462b40867b57efd49851James Smart	}
56292d7f7b0cde3ad2260e7462b40867b57efd49851James Smart	return;
56392d7f7b0cde3ad2260e7462b40867b57efd49851James Smart}
564