qlcnic: Pre-allocate DMA buffer used for minidump collection
authorShahed Shaikh <shahed.shaikh@qlogic.com>
Wed, 11 Jun 2014 18:09:11 +0000 (14:09 -0400)
committerDavid S. Miller <davem@davemloft.net>
Wed, 11 Jun 2014 22:44:29 +0000 (15:44 -0700)
Pre-allocate the physically contiguous DMA buffer used for
minidump collection at driver load time, rather than at
run time, to minimize allocation failures. Driver will allocate
the buffer at load time if PEX DMA support capability is indicated
by the adapter.

Signed-off-by: Shahed Shaikh <shahed.shaikh@qlogic.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
drivers/net/ethernet/qlogic/qlcnic/qlcnic_minidump.c

index 41abe6070466602245ece9966c1bafa87a529160..d85f7e1e117f482f4e891fca0e8f389d37f2273d 100644 (file)
@@ -441,6 +441,8 @@ struct qlcnic_82xx_dump_template_hdr {
        u32     rsvd1[0];
 };
 
+#define QLC_PEX_DMA_READ_SIZE  (PAGE_SIZE * 16)
+
 struct qlcnic_fw_dump {
        u8      clr;    /* flag to indicate if dump is cleared */
        bool    enable; /* enable/disable dump */
index f06ba90b428233586bb846f6962ec210e00501d8..1c188919cdda2bc6b05fa340707dedd1db966ed9 100644 (file)
@@ -2087,12 +2087,20 @@ err_out:
 
 static void qlcnic_free_adapter_resources(struct qlcnic_adapter *adapter)
 {
+       struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
+
        kfree(adapter->recv_ctx);
        adapter->recv_ctx = NULL;
 
-       if (adapter->ahw->fw_dump.tmpl_hdr) {
-               vfree(adapter->ahw->fw_dump.tmpl_hdr);
-               adapter->ahw->fw_dump.tmpl_hdr = NULL;
+       if (fw_dump->tmpl_hdr) {
+               vfree(fw_dump->tmpl_hdr);
+               fw_dump->tmpl_hdr = NULL;
+       }
+
+       if (fw_dump->dma_buffer) {
+               dma_free_coherent(&adapter->pdev->dev, QLC_PEX_DMA_READ_SIZE,
+                                 fw_dump->dma_buffer, fw_dump->phys_addr);
+               fw_dump->dma_buffer = NULL;
        }
 
        kfree(adapter->ahw->reset.buff);
index f7694da8ed5dcbbc5ed0124427f7b303a91c23f3..e46fc39d425d45ee1d0d081b45954801c46f89ed 100644 (file)
@@ -660,8 +660,6 @@ out:
 #define QLC_DMA_CMD_BUFF_ADDR_HI       4
 #define QLC_DMA_CMD_STATUS_CTRL                8
 
-#define QLC_PEX_DMA_READ_SIZE          (PAGE_SIZE * 16)
-
 static int qlcnic_start_pex_dma(struct qlcnic_adapter *adapter,
                                struct __mem *mem)
 {
@@ -1155,6 +1153,7 @@ int qlcnic_fw_cmd_get_minidump_temp(struct qlcnic_adapter *adapter)
        u32 version, csum, *tmp_buf;
        u8 use_flash_temp = 0;
        u32 temp_size = 0;
+       void *temp_buffer;
        int err;
 
        ahw = adapter->ahw;
@@ -1204,6 +1203,19 @@ flash_temp:
 
        qlcnic_cache_tmpl_hdr_values(adapter, fw_dump);
 
+       if (fw_dump->use_pex_dma) {
+               fw_dump->dma_buffer = NULL;
+               temp_buffer = dma_alloc_coherent(&adapter->pdev->dev,
+                                                QLC_PEX_DMA_READ_SIZE,
+                                                &fw_dump->phys_addr,
+                                                GFP_KERNEL);
+               if (!temp_buffer)
+                       fw_dump->use_pex_dma = false;
+               else
+                       fw_dump->dma_buffer = temp_buffer;
+       }
+
+
        dev_info(&adapter->pdev->dev,
                 "Default minidump capture mask 0x%x\n",
                 fw_dump->cap_mask);
@@ -1223,7 +1235,7 @@ int qlcnic_dump_fw(struct qlcnic_adapter *adapter)
        struct device *dev = &adapter->pdev->dev;
        struct qlcnic_hardware_context *ahw;
        struct qlcnic_dump_entry *entry;
-       void *temp_buffer, *tmpl_hdr;
+       void *tmpl_hdr;
        u32 ocm_window;
        __le32 *buffer;
        char mesg[64];
@@ -1267,16 +1279,6 @@ int qlcnic_dump_fw(struct qlcnic_adapter *adapter)
        qlcnic_set_sys_info(adapter, tmpl_hdr, 0, QLCNIC_DRIVER_VERSION);
        qlcnic_set_sys_info(adapter, tmpl_hdr, 1, adapter->fw_version);
 
-       if (fw_dump->use_pex_dma) {
-               temp_buffer = dma_alloc_coherent(dev, QLC_PEX_DMA_READ_SIZE,
-                                                &fw_dump->phys_addr,
-                                                GFP_KERNEL);
-               if (!temp_buffer)
-                       fw_dump->use_pex_dma = false;
-               else
-                       fw_dump->dma_buffer = temp_buffer;
-       }
-
        if (qlcnic_82xx_check(adapter)) {
                ops_cnt = ARRAY_SIZE(qlcnic_fw_dump_ops);
                fw_dump_ops = qlcnic_fw_dump_ops;
@@ -1334,10 +1336,6 @@ int qlcnic_dump_fw(struct qlcnic_adapter *adapter)
        /* Send a udev event to notify availability of FW dump */
        kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, msg);
 
-       if (fw_dump->use_pex_dma)
-               dma_free_coherent(dev, QLC_PEX_DMA_READ_SIZE,
-                                 fw_dump->dma_buffer, fw_dump->phys_addr);
-
        return 0;
 }