diff options
Diffstat (limited to 'drivers/net/wireless/rtlwifi/usb.c')
-rw-r--r-- | drivers/net/wireless/rtlwifi/usb.c | 68 |
1 files changed, 39 insertions, 29 deletions
diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c index e3ea4b346889..5847d6d0881e 100644 --- a/drivers/net/wireless/rtlwifi/usb.c +++ b/drivers/net/wireless/rtlwifi/usb.c | |||
@@ -42,8 +42,12 @@ | |||
42 | 42 | ||
43 | static void usbctrl_async_callback(struct urb *urb) | 43 | static void usbctrl_async_callback(struct urb *urb) |
44 | { | 44 | { |
45 | if (urb) | 45 | if (urb) { |
46 | kfree(urb->context); | 46 | /* free dr */ |
47 | kfree(urb->setup_packet); | ||
48 | /* free databuf */ | ||
49 | kfree(urb->transfer_buffer); | ||
50 | } | ||
47 | } | 51 | } |
48 | 52 | ||
49 | static int _usbctrl_vendorreq_async_write(struct usb_device *udev, u8 request, | 53 | static int _usbctrl_vendorreq_async_write(struct usb_device *udev, u8 request, |
@@ -55,39 +59,47 @@ static int _usbctrl_vendorreq_async_write(struct usb_device *udev, u8 request, | |||
55 | u8 reqtype; | 59 | u8 reqtype; |
56 | struct usb_ctrlrequest *dr; | 60 | struct usb_ctrlrequest *dr; |
57 | struct urb *urb; | 61 | struct urb *urb; |
58 | struct rtl819x_async_write_data { | 62 | const u16 databuf_maxlen = REALTEK_USB_VENQT_MAX_BUF_SIZE; |
59 | u8 data[REALTEK_USB_VENQT_MAX_BUF_SIZE]; | 63 | u8 *databuf; |
60 | struct usb_ctrlrequest dr; | 64 | |
61 | } *buf; | 65 | if (WARN_ON_ONCE(len > databuf_maxlen)) |
66 | len = databuf_maxlen; | ||
62 | 67 | ||
63 | pipe = usb_sndctrlpipe(udev, 0); /* write_out */ | 68 | pipe = usb_sndctrlpipe(udev, 0); /* write_out */ |
64 | reqtype = REALTEK_USB_VENQT_WRITE; | 69 | reqtype = REALTEK_USB_VENQT_WRITE; |
65 | 70 | ||
66 | buf = kmalloc(sizeof(*buf), GFP_ATOMIC); | 71 | dr = kmalloc(sizeof(*dr), GFP_ATOMIC); |
67 | if (!buf) | 72 | if (!dr) |
68 | return -ENOMEM; | 73 | return -ENOMEM; |
69 | 74 | ||
75 | databuf = kmalloc(databuf_maxlen, GFP_ATOMIC); | ||
76 | if (!databuf) { | ||
77 | kfree(dr); | ||
78 | return -ENOMEM; | ||
79 | } | ||
80 | |||
70 | urb = usb_alloc_urb(0, GFP_ATOMIC); | 81 | urb = usb_alloc_urb(0, GFP_ATOMIC); |
71 | if (!urb) { | 82 | if (!urb) { |
72 | kfree(buf); | 83 | kfree(databuf); |
84 | kfree(dr); | ||
73 | return -ENOMEM; | 85 | return -ENOMEM; |
74 | } | 86 | } |
75 | 87 | ||
76 | dr = &buf->dr; | ||
77 | |||
78 | dr->bRequestType = reqtype; | 88 | dr->bRequestType = reqtype; |
79 | dr->bRequest = request; | 89 | dr->bRequest = request; |
80 | dr->wValue = cpu_to_le16(value); | 90 | dr->wValue = cpu_to_le16(value); |
81 | dr->wIndex = cpu_to_le16(index); | 91 | dr->wIndex = cpu_to_le16(index); |
82 | dr->wLength = cpu_to_le16(len); | 92 | dr->wLength = cpu_to_le16(len); |
83 | /* data are already in little-endian order */ | 93 | /* data are already in little-endian order */ |
84 | memcpy(buf, pdata, len); | 94 | memcpy(databuf, pdata, len); |
85 | usb_fill_control_urb(urb, udev, pipe, | 95 | usb_fill_control_urb(urb, udev, pipe, |
86 | (unsigned char *)dr, buf, len, | 96 | (unsigned char *)dr, databuf, len, |
87 | usbctrl_async_callback, buf); | 97 | usbctrl_async_callback, NULL); |
88 | rc = usb_submit_urb(urb, GFP_ATOMIC); | 98 | rc = usb_submit_urb(urb, GFP_ATOMIC); |
89 | if (rc < 0) | 99 | if (rc < 0) { |
90 | kfree(buf); | 100 | kfree(databuf); |
101 | kfree(dr); | ||
102 | } | ||
91 | usb_free_urb(urb); | 103 | usb_free_urb(urb); |
92 | return rc; | 104 | return rc; |
93 | } | 105 | } |
@@ -210,17 +222,16 @@ static void _usb_writeN_sync(struct rtl_priv *rtlpriv, u32 addr, void *data, | |||
210 | u16 index = REALTEK_USB_VENQT_CMD_IDX; | 222 | u16 index = REALTEK_USB_VENQT_CMD_IDX; |
211 | int pipe = usb_sndctrlpipe(udev, 0); /* write_out */ | 223 | int pipe = usb_sndctrlpipe(udev, 0); /* write_out */ |
212 | u8 *buffer; | 224 | u8 *buffer; |
213 | dma_addr_t dma_addr; | ||
214 | 225 | ||
215 | wvalue = (u16)(addr&0x0000ffff); | 226 | wvalue = (u16)(addr & 0x0000ffff); |
216 | buffer = usb_alloc_coherent(udev, (size_t)len, GFP_ATOMIC, &dma_addr); | 227 | buffer = kmalloc(len, GFP_ATOMIC); |
217 | if (!buffer) | 228 | if (!buffer) |
218 | return; | 229 | return; |
219 | memcpy(buffer, data, len); | 230 | memcpy(buffer, data, len); |
220 | usb_control_msg(udev, pipe, request, reqtype, wvalue, | 231 | usb_control_msg(udev, pipe, request, reqtype, wvalue, |
221 | index, buffer, len, 50); | 232 | index, buffer, len, 50); |
222 | 233 | ||
223 | usb_free_coherent(udev, (size_t)len, buffer, dma_addr); | 234 | kfree(buffer); |
224 | } | 235 | } |
225 | 236 | ||
226 | static void _rtl_usb_io_handler_init(struct device *dev, | 237 | static void _rtl_usb_io_handler_init(struct device *dev, |
@@ -543,8 +554,8 @@ static void _rtl_rx_pre_process(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
543 | WARN_ON(skb_queue_empty(&rx_queue)); | 554 | WARN_ON(skb_queue_empty(&rx_queue)); |
544 | while (!skb_queue_empty(&rx_queue)) { | 555 | while (!skb_queue_empty(&rx_queue)) { |
545 | _skb = skb_dequeue(&rx_queue); | 556 | _skb = skb_dequeue(&rx_queue); |
546 | _rtl_usb_rx_process_agg(hw, skb); | 557 | _rtl_usb_rx_process_agg(hw, _skb); |
547 | ieee80211_rx_irqsafe(hw, skb); | 558 | ieee80211_rx_irqsafe(hw, _skb); |
548 | } | 559 | } |
549 | } | 560 | } |
550 | 561 | ||
@@ -640,6 +651,7 @@ static int _rtl_usb_receive(struct ieee80211_hw *hw) | |||
640 | RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG, | 651 | RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG, |
641 | "Failed to prep_rx_urb!!\n"); | 652 | "Failed to prep_rx_urb!!\n"); |
642 | err = PTR_ERR(skb); | 653 | err = PTR_ERR(skb); |
654 | usb_free_urb(urb); | ||
643 | goto err_out; | 655 | goto err_out; |
644 | } | 656 | } |
645 | 657 | ||
@@ -825,8 +837,6 @@ static void _rtl_usb_transmit(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
825 | u32 ep_num; | 837 | u32 ep_num; |
826 | struct urb *_urb = NULL; | 838 | struct urb *_urb = NULL; |
827 | struct sk_buff *_skb = NULL; | 839 | struct sk_buff *_skb = NULL; |
828 | struct sk_buff_head *skb_list; | ||
829 | struct usb_anchor *urb_list; | ||
830 | 840 | ||
831 | WARN_ON(NULL == rtlusb->usb_tx_aggregate_hdl); | 841 | WARN_ON(NULL == rtlusb->usb_tx_aggregate_hdl); |
832 | if (unlikely(IS_USB_STOP(rtlusb))) { | 842 | if (unlikely(IS_USB_STOP(rtlusb))) { |
@@ -836,15 +846,14 @@ static void _rtl_usb_transmit(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
836 | return; | 846 | return; |
837 | } | 847 | } |
838 | ep_num = rtlusb->ep_map.ep_mapping[qnum]; | 848 | ep_num = rtlusb->ep_map.ep_mapping[qnum]; |
839 | skb_list = &rtlusb->tx_skb_queue[ep_num]; | ||
840 | _skb = skb; | 849 | _skb = skb; |
841 | _urb = _rtl_usb_tx_urb_setup(hw, _skb, ep_num); | 850 | _urb = _rtl_usb_tx_urb_setup(hw, _skb, ep_num); |
842 | if (unlikely(!_urb)) { | 851 | if (unlikely(!_urb)) { |
843 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | 852 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, |
844 | "Can't allocate urb. Drop skb!\n"); | 853 | "Can't allocate urb. Drop skb!\n"); |
854 | kfree_skb(skb); | ||
845 | return; | 855 | return; |
846 | } | 856 | } |
847 | urb_list = &rtlusb->tx_pending[ep_num]; | ||
848 | _rtl_submit_tx_urb(hw, _urb); | 857 | _rtl_submit_tx_urb(hw, _urb); |
849 | } | 858 | } |
850 | 859 | ||
@@ -940,8 +949,9 @@ static struct rtl_intf_ops rtl_usb_ops = { | |||
940 | .waitq_insert = rtl_usb_tx_chk_waitq_insert, | 949 | .waitq_insert = rtl_usb_tx_chk_waitq_insert, |
941 | }; | 950 | }; |
942 | 951 | ||
943 | int __devinit rtl_usb_probe(struct usb_interface *intf, | 952 | int rtl_usb_probe(struct usb_interface *intf, |
944 | const struct usb_device_id *id) | 953 | const struct usb_device_id *id, |
954 | struct rtl_hal_cfg *rtl_hal_cfg) | ||
945 | { | 955 | { |
946 | int err; | 956 | int err; |
947 | struct ieee80211_hw *hw = NULL; | 957 | struct ieee80211_hw *hw = NULL; |
@@ -976,7 +986,7 @@ int __devinit rtl_usb_probe(struct usb_interface *intf, | |||
976 | usb_set_intfdata(intf, hw); | 986 | usb_set_intfdata(intf, hw); |
977 | /* init cfg & intf_ops */ | 987 | /* init cfg & intf_ops */ |
978 | rtlpriv->rtlhal.interface = INTF_USB; | 988 | rtlpriv->rtlhal.interface = INTF_USB; |
979 | rtlpriv->cfg = (struct rtl_hal_cfg *)(id->driver_info); | 989 | rtlpriv->cfg = rtl_hal_cfg; |
980 | rtlpriv->intf_ops = &rtl_usb_ops; | 990 | rtlpriv->intf_ops = &rtl_usb_ops; |
981 | rtl_dbgp_flag_init(hw); | 991 | rtl_dbgp_flag_init(hw); |
982 | /* Init IO handler */ | 992 | /* Init IO handler */ |