diff options
Diffstat (limited to 'drivers/net/wireless/rtlwifi/usb.c')
| -rw-r--r-- | drivers/net/wireless/rtlwifi/usb.c | 57 | 
1 files changed, 33 insertions, 24 deletions
| diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c index f2ecdeb3a90d..156b52732f3d 100644 --- a/drivers/net/wireless/rtlwifi/usb.c +++ b/drivers/net/wireless/rtlwifi/usb.c @@ -42,8 +42,12 @@  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, @@ -55,39 +59,47 @@ 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);  	/* data are already in little-endian order */ -	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;  } @@ -542,8 +554,8 @@ static void _rtl_rx_pre_process(struct ieee80211_hw *hw, struct sk_buff *skb)  	WARN_ON(skb_queue_empty(&rx_queue));  	while (!skb_queue_empty(&rx_queue)) {  		_skb = skb_dequeue(&rx_queue); -		_rtl_usb_rx_process_agg(hw, skb); -		ieee80211_rx_irqsafe(hw, skb); +		_rtl_usb_rx_process_agg(hw, _skb); +		ieee80211_rx_irqsafe(hw, _skb);  	}  } @@ -825,8 +837,6 @@ static void _rtl_usb_transmit(struct ieee80211_hw *hw, struct sk_buff *skb,  	u32 ep_num;  	struct urb *_urb = NULL;  	struct sk_buff *_skb = NULL; -	struct sk_buff_head *skb_list; -	struct usb_anchor *urb_list;  	WARN_ON(NULL == rtlusb->usb_tx_aggregate_hdl);  	if (unlikely(IS_USB_STOP(rtlusb))) { @@ -836,7 +846,6 @@ static void _rtl_usb_transmit(struct ieee80211_hw *hw, struct sk_buff *skb,  		return;  	}  	ep_num = rtlusb->ep_map.ep_mapping[qnum]; -	skb_list = &rtlusb->tx_skb_queue[ep_num];  	_skb = skb;  	_urb = _rtl_usb_tx_urb_setup(hw, _skb, ep_num);  	if (unlikely(!_urb)) { @@ -844,7 +853,6 @@ static void _rtl_usb_transmit(struct ieee80211_hw *hw, struct sk_buff *skb,  			 "Can't allocate urb. Drop skb!\n");  		return;  	} -	urb_list = &rtlusb->tx_pending[ep_num];  	_rtl_submit_tx_urb(hw, _urb);  } @@ -941,7 +949,8 @@ static struct rtl_intf_ops rtl_usb_ops = {  };  int 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; @@ -976,7 +985,7 @@ int 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 */ |