diff options
Diffstat (limited to 'drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c')
| -rw-r--r-- | drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c | 44 | 
1 files changed, 22 insertions, 22 deletions
| diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c index e9cbfd077710..75fcd6752edc 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c @@ -160,7 +160,7 @@ struct brcmf_usbdev_info {  	struct usb_device *usbdev;  	struct device *dev; -	struct mutex dev_init_lock; +	struct completion dev_init_done;  	int ctl_in_pipe, ctl_out_pipe;  	struct urb *ctl_urb; /* URB for control endpoint */ @@ -445,22 +445,17 @@ fail:  } -static void brcmf_usb_free_q(struct list_head *q, bool pending) +static void brcmf_usb_free_q(struct list_head *q)  {  	struct brcmf_usbreq *req, *next; -	int i = 0; +  	list_for_each_entry_safe(req, next, q, list) {  		if (!req->urb) {  			brcmf_err("bad req\n");  			break;  		} -		i++; -		if (pending) { -			usb_kill_urb(req->urb); -		} else { -			usb_free_urb(req->urb); -			list_del_init(&req->list); -		} +		usb_free_urb(req->urb); +		list_del_init(&req->list);  	}  } @@ -682,12 +677,18 @@ static int brcmf_usb_up(struct device *dev)  static void brcmf_cancel_all_urbs(struct brcmf_usbdev_info *devinfo)  { +	int i; +  	if (devinfo->ctl_urb)  		usb_kill_urb(devinfo->ctl_urb);  	if (devinfo->bulk_urb)  		usb_kill_urb(devinfo->bulk_urb); -	brcmf_usb_free_q(&devinfo->tx_postq, true); -	brcmf_usb_free_q(&devinfo->rx_postq, true); +	if (devinfo->tx_reqs) +		for (i = 0; i < devinfo->bus_pub.ntxq; i++) +			usb_kill_urb(devinfo->tx_reqs[i].urb); +	if (devinfo->rx_reqs) +		for (i = 0; i < devinfo->bus_pub.nrxq; i++) +			usb_kill_urb(devinfo->rx_reqs[i].urb);  }  static void brcmf_usb_down(struct device *dev) @@ -1023,8 +1024,8 @@ static void brcmf_usb_detach(struct brcmf_usbdev_info *devinfo)  	brcmf_dbg(USB, "Enter, devinfo %p\n", devinfo);  	/* free the URBS */ -	brcmf_usb_free_q(&devinfo->rx_freeq, false); -	brcmf_usb_free_q(&devinfo->tx_freeq, false); +	brcmf_usb_free_q(&devinfo->rx_freeq); +	brcmf_usb_free_q(&devinfo->tx_freeq);  	usb_free_urb(devinfo->ctl_urb);  	usb_free_urb(devinfo->bulk_urb); @@ -1193,11 +1194,11 @@ static void brcmf_usb_probe_phase2(struct device *dev, int ret,  	if (ret)  		goto error; -	mutex_unlock(&devinfo->dev_init_lock); +	complete(&devinfo->dev_init_done);  	return;  error:  	brcmf_dbg(TRACE, "failed: dev=%s, err=%d\n", dev_name(dev), ret); -	mutex_unlock(&devinfo->dev_init_lock); +	complete(&devinfo->dev_init_done);  	device_release_driver(dev);  } @@ -1265,7 +1266,7 @@ static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo)  		if (ret)  			goto fail;  		/* we are done */ -		mutex_unlock(&devinfo->dev_init_lock); +		complete(&devinfo->dev_init_done);  		return 0;  	}  	bus->chip = bus_pub->devid; @@ -1325,11 +1326,10 @@ brcmf_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)  	devinfo->usbdev = usb;  	devinfo->dev = &usb->dev; -	/* Take an init lock, to protect for disconnect while still loading. +	/* Init completion, to protect for disconnect while still loading.  	 * Necessary because of the asynchronous firmware load construction  	 */ -	mutex_init(&devinfo->dev_init_lock); -	mutex_lock(&devinfo->dev_init_lock); +	init_completion(&devinfo->dev_init_done);  	usb_set_intfdata(intf, devinfo); @@ -1407,7 +1407,7 @@ brcmf_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)  	return 0;  fail: -	mutex_unlock(&devinfo->dev_init_lock); +	complete(&devinfo->dev_init_done);  	kfree(devinfo);  	usb_set_intfdata(intf, NULL);  	return ret; @@ -1422,7 +1422,7 @@ brcmf_usb_disconnect(struct usb_interface *intf)  	devinfo = (struct brcmf_usbdev_info *)usb_get_intfdata(intf);  	if (devinfo) { -		mutex_lock(&devinfo->dev_init_lock); +		wait_for_completion(&devinfo->dev_init_done);  		/* Make sure that devinfo still exists. Firmware probe routines  		 * may have released the device and cleared the intfdata.  		 */ |