Merge branch 'stable-3.2' into pandora-3.2
[pandora-kernel.git] / drivers / net / wireless / rtlwifi / usb.c
index 30dd0a9..e5fe956 100644 (file)
 
 static void usbctrl_async_callback(struct urb *urb)
 {
-       if (urb)
-               kfree(urb->context);
+       if (urb) {
+               /* free dr */
+               kfree(urb->setup_packet);
+               /* free databuf */
+               kfree(urb->transfer_buffer);
+       }
 }
 
 static int _usbctrl_vendorreq_async_write(struct usb_device *udev, u8 request,
@@ -57,38 +61,46 @@ static int _usbctrl_vendorreq_async_write(struct usb_device *udev, u8 request,
        u8 reqtype;
        struct usb_ctrlrequest *dr;
        struct urb *urb;
-       struct rtl819x_async_write_data {
-               u8 data[REALTEK_USB_VENQT_MAX_BUF_SIZE];
-               struct usb_ctrlrequest dr;
-       } *buf;
+       const u16 databuf_maxlen = REALTEK_USB_VENQT_MAX_BUF_SIZE;
+       u8 *databuf;
+
+       if (WARN_ON_ONCE(len > databuf_maxlen))
+               len = databuf_maxlen;
 
        pipe = usb_sndctrlpipe(udev, 0); /* write_out */
        reqtype =  REALTEK_USB_VENQT_WRITE;
 
-       buf = kmalloc(sizeof(*buf), GFP_ATOMIC);
-       if (!buf)
+       dr = kmalloc(sizeof(*dr), GFP_ATOMIC);
+       if (!dr)
+               return -ENOMEM;
+
+       databuf = kmalloc(databuf_maxlen, GFP_ATOMIC);
+       if (!databuf) {
+               kfree(dr);
                return -ENOMEM;
+       }
 
        urb = usb_alloc_urb(0, GFP_ATOMIC);
        if (!urb) {
-               kfree(buf);
+               kfree(databuf);
+               kfree(dr);
                return -ENOMEM;
        }
 
-       dr = &buf->dr;
-
        dr->bRequestType = reqtype;
        dr->bRequest = request;
        dr->wValue = cpu_to_le16(value);
        dr->wIndex = cpu_to_le16(index);
        dr->wLength = cpu_to_le16(len);
-       memcpy(buf, pdata, len);
+       memcpy(databuf, pdata, len);
        usb_fill_control_urb(urb, udev, pipe,
-                            (unsigned char *)dr, buf, len,
-                            usbctrl_async_callback, buf);
+                            (unsigned char *)dr, databuf, len,
+                            usbctrl_async_callback, NULL);
        rc = usb_submit_urb(urb, GFP_ATOMIC);
-       if (rc < 0)
-               kfree(buf);
+       if (rc < 0) {
+               kfree(databuf);
+               kfree(dr);
+       }
        usb_free_urb(urb);
        return rc;
 }
@@ -800,6 +812,7 @@ static void _rtl_usb_transmit(struct ieee80211_hw *hw, struct sk_buff *skb,
        if (unlikely(!_urb)) {
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
                         ("Can't allocate urb. Drop skb!\n"));
+               kfree_skb(skb);
                return;
        }
        urb_list = &rtlusb->tx_pending[ep_num];
@@ -894,7 +907,8 @@ static struct rtl_intf_ops rtl_usb_ops = {
 };
 
 int __devinit rtl_usb_probe(struct usb_interface *intf,
-                       const struct usb_device_id *id)
+                           const struct usb_device_id *id,
+                           struct rtl_hal_cfg *rtl_hal_cfg)
 {
        int err;
        struct ieee80211_hw *hw = NULL;
@@ -928,7 +942,7 @@ int __devinit rtl_usb_probe(struct usb_interface *intf,
        usb_set_intfdata(intf, hw);
        /* init cfg & intf_ops */
        rtlpriv->rtlhal.interface = INTF_USB;
-       rtlpriv->cfg = (struct rtl_hal_cfg *)(id->driver_info);
+       rtlpriv->cfg = rtl_hal_cfg;
        rtlpriv->intf_ops = &rtl_usb_ops;
        rtl_dbgp_flag_init(hw);
        /* Init IO handler */