[WCNCR00166654] misc: add memory preallocation module
[Description]
memory preallocation is for avoiding memory fragmentation
Usage:
1. in Makefile.x86 or Makefile.ce
export CONFIG_MTK_PREALLOC_MEMORY=y
2. after build, there is preallocate module
ex. wlan_mt6632_usb_prealloc.ko
3. insmod prealloc module before insmod wifi module
Note:
for all HIFs, now just USB is implemented
Test:
in Linux PC is ok
1. insmod prealloc module
2. loop insmod wifi module -> connect AP -> rmmod wifi module
Change-Id: I3531381a328ee47f25e2cd2764b67e1dbfe04578
Signed-off-by: Neil Chen <yn.chen@mediatek.com>
CR-Id: WCNCR00166654
Feature: misc
diff --git a/Makefile b/Makefile
index eb58c30..2c253ad 100644
--- a/Makefile
+++ b/Makefile
@@ -254,4 +254,14 @@
$(MODULE_NAME)-objs += $(MGMT_OBJS)
$(MODULE_NAME)-objs += $(CHIPS_OBJS)
-
+#
+# mtprealloc
+#
+ifeq ($(CONFIG_MTK_PREALLOC_MEMORY), y)
+ccflags-y += -DCFG_PREALLOC_MEMORY
+ccflags-y += -I$(src)/prealloc/include
+MODULE_NAME_PREALLOC = $(MODULE_NAME)_prealloc
+PREALLOC_OBJS := prealloc/prealloc.o
+$(MODULE_NAME_PREALLOC)-objs += $(PREALLOC_OBJS)
+obj-m += $(MODULE_NAME_PREALLOC).o
+endif
diff --git a/Makefile.ce b/Makefile.ce
index fa830eb..5738d2e 100644
--- a/Makefile.ce
+++ b/Makefile.ce
@@ -24,6 +24,7 @@
export CONFIG_MTK_COMBO_WIFI_HIF=$(HIF)
MODULE_NAME := wlan_$(WLAN_CHIP_ID)_$(HIF)
+export CONFIG_MTK_PREALLOC_MEMORY=n
##############################################################
# Platform specific
diff --git a/Makefile.x86 b/Makefile.x86
index 3a91303..ad95c45 100644
--- a/Makefile.x86
+++ b/Makefile.x86
@@ -36,6 +36,8 @@
export CONFIG_MTK_COMBO_PLAT_PATH=x86
+export CONFIG_MTK_PREALLOC_MEMORY=n
+
##############################################################
# Compile options
##############################################################
diff --git a/include/precomp.h b/include/precomp.h
index 33beba8..8dd937f 100644
--- a/include/precomp.h
+++ b/include/precomp.h
@@ -247,6 +247,14 @@
#include "gl_qa_agent.h"
#endif
+/*------------------------------------------------------------------------------
+ * Memory Prealloc
+ *------------------------------------------------------------------------------
+ */
+#ifdef CFG_PREALLOC_MEMORY
+#include "prealloc.h"
+#endif
+
/*******************************************************************************
* C O N S T A N T S
********************************************************************************
diff --git a/nic/nic.c b/nic/nic.c
index 8754a79..4fe165c 100644
--- a/nic/nic.c
+++ b/nic/nic.c
@@ -191,8 +191,12 @@
/* Allocate memory for the CMD_INFO_T and its MGMT memory pool. */
prAdapter->u4MgtBufCachedSize = MGT_BUFFER_SIZE;
+#ifdef CFG_PREALLOC_MEMORY
+ prAdapter->pucMgtBufCached = preallocGetMem(MEM_ID_NIC_ADAPTER);
+#else
LOCAL_NIC_ALLOCATE_MEMORY(prAdapter->pucMgtBufCached,
prAdapter->u4MgtBufCachedSize, PHY_MEM_TYPE, "COMMON MGMT MEMORY POOL");
+#endif
/* 4 <2> Memory for RX Descriptor */
/* Initialize the number of rx buffers we will have in our queue. */
@@ -279,7 +283,9 @@
}
/* 4 <1> Memory for Management Memory Pool */
if (prAdapter->pucMgtBufCached) {
+#ifndef CFG_PREALLOC_MEMORY
kalMemFree((PVOID) prAdapter->pucMgtBufCached, PHY_MEM_TYPE, prAdapter->u4MgtBufCachedSize);
+#endif
prAdapter->pucMgtBufCached = (PUINT_8) NULL;
}
diff --git a/os/linux/hif/usb/usb.c b/os/linux/hif/usb/usb.c
index d360448..2dcf6d4 100644
--- a/os/linux/hif/usb/usb.c
+++ b/os/linux/hif/usb/usb.c
@@ -793,8 +793,12 @@
prUsbReq->prBufCtrl->pucBuf = usb_alloc_coherent(prHifInfo->udev, USB_TX_CMD_BUF_SIZE, GFP_ATOMIC,
&prUsbReq->prUrb->transfer_dma);
#else
+#ifdef CFG_PREALLOC_MEMORY
+ prUsbReq->prBufCtrl->pucBuf = preallocGetMem(MEM_ID_TX_CMD);
+#else
prUsbReq->prBufCtrl->pucBuf = kmalloc(USB_TX_CMD_BUF_SIZE, GFP_ATOMIC);
#endif
+#endif
if (prUsbReq->prBufCtrl->pucBuf == NULL) {
DBGLOG(HAL, ERROR, "kmalloc() reports error\n");
goto error;
@@ -848,8 +852,12 @@
usb_alloc_coherent(prHifInfo->udev, USB_TX_DATA_BUFF_SIZE, GFP_ATOMIC,
&prUsbReq->prUrb->transfer_dma);
#else
+#ifdef CFG_PREALLOC_MEMORY
+ prUsbReq->prBufCtrl->pucBuf = preallocGetMem(MEM_ID_TX_DATA);
+#else
prUsbReq->prBufCtrl->pucBuf = kmalloc(USB_TX_DATA_BUFF_SIZE, GFP_ATOMIC);
#endif
+#endif
if (prUsbReq->prBufCtrl->pucBuf == NULL) {
DBGLOG(HAL, ERROR, "kmalloc() reports error\n");
goto error;
@@ -874,8 +882,12 @@
usb_alloc_coherent(prHifInfo->udev, USB_TX_DATA_BUF_SIZE, GFP_ATOMIC,
&prUsbReq->prUrb->transfer_dma);
#else
+#ifdef CFG_PREALLOC_MEMORY
+ prUsbReq->prBufCtrl->pucBuf = preallocGetMem(MEM_ID_TX_DATA);
+#else
prUsbReq->prBufCtrl->pucBuf = kmalloc(USB_TX_DATA_BUF_SIZE, GFP_ATOMIC);
#endif
+#endif
if (prUsbReq->prBufCtrl->pucBuf == NULL) {
DBGLOG(HAL, ERROR, "kmalloc() reports error\n");
goto error;
@@ -893,7 +905,11 @@
i = 0;
list_for_each_entry_safe(prUsbReq, prUsbReqNext, &prHifInfo->rRxEventFreeQ, list) {
prUsbReq->prBufCtrl = &prHifInfo->rRxEventBufCtrl[i];
+#ifdef CFG_PREALLOC_MEMORY
+ prUsbReq->prBufCtrl->pucBuf = preallocGetMem(MEM_ID_RX_EVENT);
+#else
prUsbReq->prBufCtrl->pucBuf = kmalloc(USB_RX_EVENT_BUF_SIZE, GFP_ATOMIC);
+#endif
if (prUsbReq->prBufCtrl->pucBuf == NULL) {
DBGLOG(HAL, ERROR, "kmalloc() reports error\n");
goto error;
@@ -908,7 +924,11 @@
i = 0;
list_for_each_entry_safe(prUsbReq, prUsbReqNext, &prHifInfo->rRxDataFreeQ, list) {
prUsbReq->prBufCtrl = &prHifInfo->rRxDataBufCtrl[i];
+#ifdef CFG_PREALLOC_MEMORY
+ prUsbReq->prBufCtrl->pucBuf = preallocGetMem(MEM_ID_RX_DATA);
+#else
prUsbReq->prBufCtrl->pucBuf = kmalloc(USB_RX_DATA_BUF_SIZE, GFP_ATOMIC);
+#endif
if (prUsbReq->prBufCtrl->pucBuf == NULL) {
DBGLOG(HAL, ERROR, "kmalloc() reports error\n");
goto error;
@@ -959,8 +979,10 @@
usb_free_coherent(prHifInfo->udev, USB_TX_DATA_BUFF_SIZE,
prUsbReq->prBufCtrl->pucBuf, prUsbReq->prUrb->transfer_dma);
#else
+#ifndef CFG_PREALLOC_MEMORY
kfree(prUsbReq->prBufCtrl->pucBuf);
#endif
+#endif
usb_free_urb(prUsbReq->prUrb);
}
}
@@ -970,8 +992,10 @@
usb_free_coherent(prHifInfo->udev, USB_TX_DATA_BUFF_SIZE,
prUsbReq->prBufCtrl->pucBuf, prUsbReq->prUrb->transfer_dma);
#else
+#ifndef CFG_PREALLOC_MEMORY
kfree(prUsbReq->prBufCtrl->pucBuf);
#endif
+#endif
usb_free_urb(prUsbReq->prUrb);
}
#endif
@@ -991,8 +1015,10 @@
usb_free_coherent(prHifInfo->udev, USB_TX_CMD_BUF_SIZE,
prUsbReq->prBufCtrl->pucBuf, prUsbReq->prUrb->transfer_dma);
#else
+#ifndef CFG_PREALLOC_MEMORY
kfree(prUsbReq->prBufCtrl->pucBuf);
#endif
+#endif
usb_free_urb(prUsbReq->prUrb);
}
@@ -1017,12 +1043,16 @@
}
list_for_each_entry_safe(prUsbReq, prUsbReqNext, &prHifInfo->rRxDataFreeQ, list) {
+#ifndef CFG_PREALLOC_MEMORY
kfree(prUsbReq->prBufCtrl->pucBuf);
+#endif
usb_free_urb(prUsbReq->prUrb);
}
list_for_each_entry_safe(prUsbReq, prUsbReqNext, &prHifInfo->rRxEventFreeQ, list) {
+#ifndef CFG_PREALLOC_MEMORY
kfree(prUsbReq->prBufCtrl->pucBuf);
+#endif
usb_free_urb(prUsbReq->prUrb);
}
diff --git a/prealloc/include/prealloc.h b/prealloc/include/prealloc.h
new file mode 100644
index 0000000..80d4ee5
--- /dev/null
+++ b/prealloc/include/prealloc.h
@@ -0,0 +1,113 @@
+/******************************************************************************
+ *
+ * This file is provided under a dual license. When you use or
+ * distribute this software, you may choose to be licensed under
+ * version 2 of the GNU General Public License ("GPLv2 License")
+ * or BSD License.
+ *
+ * GPLv2 License
+ *
+ * Copyright(C) 2017 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See http://www.gnu.org/licenses/gpl-2.0.html for more details.
+ *
+ * BSD LICENSE
+ *
+ * Copyright(C) 2017 MediaTek Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *****************************************************************************/
+/*! \file "prealloc.h"
+* \brief This file contains the declairation of memory preallocation module
+*/
+
+/*******************************************************************************
+* C O M P I L E R F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* E X T E R N A L R E F E R E N C E S
+********************************************************************************
+*/
+#ifndef _PREALLOC_H
+#define _PREALLOC_H
+
+/*******************************************************************************
+* C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* D A T A T Y P E S
+********************************************************************************
+*/
+enum ENUM_MEM_ID {
+ MEM_ID_NIC_ADAPTER,
+#if defined(_HIF_USB)
+ MEM_ID_TX_CMD,
+ MEM_ID_TX_DATA,
+ MEM_ID_RX_EVENT,
+ MEM_ID_RX_DATA,
+#endif
+
+ MEM_ID_NUM, /* END, Do not modify */
+};
+
+/*******************************************************************************
+* P U B L I C D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+* P R I V A T E D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+* M A C R O S
+********************************************************************************
+*/
+#define PreLog(level, ...) printk(level "[wlan][MemPrealloc] " __VA_ARGS__)
+#define MP_Info(...) PreLog(KERN_INFO, __VA_ARGS__)
+#define MP_Err(...) PreLog(KERN_ERR, __VA_ARGS__)
+
+/*******************************************************************************
+* F U N C T I O N D E C L A R A T I O N S
+********************************************************************************
+*/
+PVOID preallocGetMem(enum ENUM_MEM_ID memId);
+
+#endif /* _PREALLOC_H */
diff --git a/prealloc/prealloc.c b/prealloc/prealloc.c
new file mode 100644
index 0000000..3da0309
--- /dev/null
+++ b/prealloc/prealloc.c
@@ -0,0 +1,284 @@
+/******************************************************************************
+ *
+ * This file is provided under a dual license. When you use or
+ * distribute this software, you may choose to be licensed under
+ * version 2 of the GNU General Public License ("GPLv2 License")
+ * or BSD License.
+ *
+ * GPLv2 License
+ *
+ * Copyright(C) 2017 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See http://www.gnu.org/licenses/gpl-2.0.html for more details.
+ *
+ * BSD LICENSE
+ *
+ * Copyright(C) 2017 MediaTek Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *****************************************************************************/
+/*! \file prealloc.c
+* \brief memory preallocation module
+*
+* This file contains all implementations of memory preallocation module
+*/
+
+
+/*******************************************************************************
+* C O M P I L E R F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* E X T E R N A L R E F E R E N C E S
+********************************************************************************
+*/
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include "precomp.h"
+
+/*******************************************************************************
+* C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* D A T A T Y P E S
+********************************************************************************
+*/
+/*
+ * ----------------- ---------------- ----------
+ * | PRE_MEM_BLOCK |-pItemArray->| PRE_MEM_ITEM |-pvBuffer->| Memory |
+ * |---------------| |--------------| ----------
+ * | PRE_MEM_BLOCK |->... | PRE_MEM_ITEM |-pvBuffer->----------
+ * |---------------| |--------------| | Memory |
+ * . . ----------
+ * . .
+ * . .
+ */
+struct PRE_MEM_ITEM {
+ PVOID pvBuffer;
+};
+
+struct PRE_MEM_BLOCK {
+ PUCHAR pucName;
+ struct PRE_MEM_ITEM *pItemArray;
+ UINT_32 u4Count;
+ UINT_32 u4Size;
+ UINT_32 u4KmallocFlags;
+ UINT_32 u4Curr;
+};
+
+/*******************************************************************************
+* P U B L I C D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+* P R I V A T E D A T A
+********************************************************************************
+*/
+static INT_32 blockCount;
+static struct PRE_MEM_BLOCK arMemBlocks[MEM_ID_NUM];
+
+/*******************************************************************************
+* M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* F U N C T I O N D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* F U N C T I O N S
+********************************************************************************
+*/
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief export function for memory preallocation
+*
+* \param[in] memId memory id.
+*
+* \retval void pointer to the memory address
+*/
+/*----------------------------------------------------------------------------*/
+PVOID preallocGetMem(enum ENUM_MEM_ID memId)
+{
+ struct PRE_MEM_BLOCK *block = NULL;
+ UINT_32 curr = 0, count = 0;
+ PUCHAR name = NULL;
+
+ /* check memId exist */
+ if (memId < 0 || memId >= MEM_ID_NUM) {
+ MP_Err("request wrong memId %d", memId);
+ return NULL;
+ }
+
+ block = &arMemBlocks[memId];
+ curr = block->u4Curr;
+ count = block->u4Count;
+ name = block->pucName;
+ block->u4Curr = (curr + 1) % count; /* point to next */
+
+ /* return request memory address */
+ MP_Info("request [%s], return [%d]\n", name, curr);
+ return block->pItemArray[curr].pvBuffer;
+}
+EXPORT_SYMBOL(preallocGetMem);
+
+static void preallocFree(void)
+{
+ INT_32 i = 0, j = 0;
+ struct PRE_MEM_BLOCK *block = NULL;
+ struct PRE_MEM_ITEM *items = NULL;
+ PVOID memory = NULL;
+
+ for (i = 0; i < MEM_ID_NUM; i++) {
+ block = &arMemBlocks[i];
+ MP_Info("free [%d], block name=\"%s\" count=%d size=%d\n",
+ i, block->pucName, block->u4Count, block->u4Size);
+ items = block->pItemArray;
+ if (items == NULL)
+ continue;
+ /* free memory */
+ for (j = 0; j < block->u4Count; j++) {
+ memory = items[j].pvBuffer;
+ MP_Info(" - [%d] memory 0x%p\n", j, memory);
+ kfree(memory);
+ }
+ /* free items */
+ MP_Info(" - items 0x%p\n", items);
+ kfree(items);
+ memset(block, 0, sizeof(*block));
+ }
+}
+
+static int preallocAlloc(void)
+{
+ INT_32 i = 0, j = 0;
+ struct PRE_MEM_BLOCK *block = NULL;
+ struct PRE_MEM_ITEM *items = NULL;
+ PVOID memory = NULL;
+
+ for (i = 0; i < MEM_ID_NUM; i++) {
+ block = &arMemBlocks[i];
+ MP_Info("allocate [%d] block name=\"%s\" count=%d size=%d\n",
+ i, block->pucName, block->u4Count, block->u4Size);
+ /* allocate u4Count items */
+ items = kcalloc(block->u4Count, sizeof(*items), GFP_KERNEL);
+ if (items == NULL) {
+ MP_Err("allocate [%d] items failed\n", i);
+ goto fail;
+ }
+ MP_Info(" + items 0x%p\n", items);
+ block->pItemArray = items;
+ for (j = 0; j < block->u4Count; j++) {
+ /* allocate u4Size memory */
+ memory = kmalloc(block->u4Size, block->u4KmallocFlags);
+ if (memory == NULL) {
+ MP_Err("allocate [%d][%d] memory failed\n", i, j);
+ goto fail;
+ }
+ MP_Info(" + [%d] memory 0x%p\n", j, memory);
+ items[j].pvBuffer = memory;
+ }
+ }
+
+ return 0;
+
+fail:
+ preallocFree();
+ return -ENOMEM;
+}
+
+static void preallocAddBlock(enum ENUM_MEM_ID memId,
+ PUCHAR name, UINT_32 count, UINT_32 size, UINT_32 kmallocFlags)
+{
+ if (memId != blockCount) {
+ MP_Err("memId %d != index %d\n", memId, blockCount);
+ return;
+ }
+ arMemBlocks[blockCount].pucName = name;
+ arMemBlocks[blockCount].pItemArray = NULL;
+ arMemBlocks[blockCount].u4Count = count;
+ arMemBlocks[blockCount].u4Size = size;
+ arMemBlocks[blockCount].u4KmallocFlags = kmallocFlags;
+ arMemBlocks[blockCount].u4Curr = 0;
+ blockCount++;
+}
+
+static int __init preallocInit(void)
+{
+ blockCount = 0;
+
+ /* ADD BLOCK START, follow the sequence of ENUM_MEM_ID */
+ preallocAddBlock(MEM_ID_NIC_ADAPTER, "NIC ADAPTER MEMORY",
+ 1, MGT_BUFFER_SIZE,
+ GFP_KERNEL);
+#if defined(_HIF_USB)
+ preallocAddBlock(MEM_ID_TX_CMD, "TX CMD",
+ USB_REQ_TX_CMD_CNT, USB_TX_CMD_BUF_SIZE,
+ GFP_KERNEL);
+#if CFG_USB_TX_AGG
+ preallocAddBlock(MEM_ID_TX_DATA, "TX AGG DATA",
+ (USB_TC_NUM * USB_REQ_TX_DATA_CNT), USB_TX_DATA_BUFF_SIZE,
+ GFP_KERNEL);
+#else
+ preallocAddBlock(MEM_ID_TX_DATA, "TX DATA",
+ USB_REQ_TX_DATA_CNT, USB_TX_DATA_BUFF_SIZE,
+ GFP_KERNEL);
+#endif
+ preallocAddBlock(MEM_ID_RX_EVENT, "RX EVENT",
+ USB_REQ_RX_EVENT_CNT, USB_RX_EVENT_BUF_SIZE,
+ GFP_KERNEL);
+ preallocAddBlock(MEM_ID_RX_DATA, "RX DATA",
+ USB_REQ_RX_DATA_CNT, USB_RX_DATA_BUF_SIZE,
+ GFP_KERNEL);
+#endif
+ /* ADD BLOCK END */
+
+ return preallocAlloc();
+}
+
+static void __exit preallocExit(void)
+{
+ preallocFree();
+}
+
+module_init(preallocInit);
+module_exit(preallocExit);