summaryrefslogtreecommitdiff
path: root/drivers/staging/rtl8712/rtl871x_xmit.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/rtl8712/rtl871x_xmit.c')
-rw-r--r--drivers/staging/rtl8712/rtl871x_xmit.c43
1 files changed, 34 insertions, 9 deletions
diff --git a/drivers/staging/rtl8712/rtl871x_xmit.c b/drivers/staging/rtl8712/rtl871x_xmit.c
index 090345bad223..6353dbe554d3 100644
--- a/drivers/staging/rtl8712/rtl871x_xmit.c
+++ b/drivers/staging/rtl8712/rtl871x_xmit.c
@@ -21,6 +21,7 @@
#include "osdep_intf.h"
#include "usb_ops.h"
+#include <linux/usb.h>
#include <linux/ieee80211.h>
static const u8 P802_1H_OUI[P80211_OUI_LEN] = {0x00, 0x00, 0xf8};
@@ -55,6 +56,7 @@ int _r8712_init_xmit_priv(struct xmit_priv *pxmitpriv,
sint i;
struct xmit_buf *pxmitbuf;
struct xmit_frame *pxframe;
+ int j;
memset((unsigned char *)pxmitpriv, 0, sizeof(struct xmit_priv));
spin_lock_init(&pxmitpriv->lock);
@@ -117,11 +119,8 @@ int _r8712_init_xmit_priv(struct xmit_priv *pxmitpriv,
_init_queue(&pxmitpriv->pending_xmitbuf_queue);
pxmitpriv->pallocated_xmitbuf =
kmalloc(NR_XMITBUFF * sizeof(struct xmit_buf) + 4, GFP_ATOMIC);
- if (!pxmitpriv->pallocated_xmitbuf) {
- kfree(pxmitpriv->pallocated_frame_buf);
- pxmitpriv->pallocated_frame_buf = NULL;
- return -ENOMEM;
- }
+ if (!pxmitpriv->pallocated_xmitbuf)
+ goto clean_up_frame_buf;
pxmitpriv->pxmitbuf = pxmitpriv->pallocated_xmitbuf + 4 -
((addr_t)(pxmitpriv->pallocated_xmitbuf) & 3);
pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmitbuf;
@@ -129,13 +128,17 @@ int _r8712_init_xmit_priv(struct xmit_priv *pxmitpriv,
INIT_LIST_HEAD(&pxmitbuf->list);
pxmitbuf->pallocated_buf =
kmalloc(MAX_XMITBUF_SZ + XMITBUF_ALIGN_SZ, GFP_ATOMIC);
- if (!pxmitbuf->pallocated_buf)
- return -ENOMEM;
+ if (!pxmitbuf->pallocated_buf) {
+ j = 0;
+ goto clean_up_alloc_buf;
+ }
pxmitbuf->pbuf = pxmitbuf->pallocated_buf + XMITBUF_ALIGN_SZ -
((addr_t) (pxmitbuf->pallocated_buf) &
(XMITBUF_ALIGN_SZ - 1));
- if (r8712_xmit_resource_alloc(padapter, pxmitbuf))
- return -ENOMEM;
+ if (r8712_xmit_resource_alloc(padapter, pxmitbuf)) {
+ j = 1;
+ goto clean_up_alloc_buf;
+ }
list_add_tail(&pxmitbuf->list,
&(pxmitpriv->free_xmitbuf_queue.queue));
pxmitbuf++;
@@ -146,6 +149,28 @@ int _r8712_init_xmit_priv(struct xmit_priv *pxmitpriv,
init_hwxmits(pxmitpriv->hwxmits, pxmitpriv->hwxmit_entry);
tasklet_setup(&pxmitpriv->xmit_tasklet, r8712_xmit_bh);
return 0;
+
+clean_up_alloc_buf:
+ if (j) {
+ /* failure happened in r8712_xmit_resource_alloc()
+ * delete extra pxmitbuf->pallocated_buf
+ */
+ kfree(pxmitbuf->pallocated_buf);
+ }
+ for (j = 0; j < i; j++) {
+ int k;
+
+ pxmitbuf--; /* reset pointer */
+ kfree(pxmitbuf->pallocated_buf);
+ for (k = 0; k < 8; k++) /* delete xmit urb's */
+ usb_free_urb(pxmitbuf->pxmit_urb[k]);
+ }
+ kfree(pxmitpriv->pallocated_xmitbuf);
+ pxmitpriv->pallocated_xmitbuf = NULL;
+clean_up_frame_buf:
+ kfree(pxmitpriv->pallocated_frame_buf);
+ pxmitpriv->pallocated_frame_buf = NULL;
+ return -ENOMEM;
}
void _free_xmit_priv(struct xmit_priv *pxmitpriv)