diff options
Diffstat (limited to 'drivers/usb/core')
| -rw-r--r-- | drivers/usb/core/hcd.c | 14 | ||||
| -rw-r--r-- | drivers/usb/core/urb.c | 12 | 
2 files changed, 26 insertions, 0 deletions
| diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 3e01dd6e509b..d9712c2602af 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -1563,6 +1563,13 @@ int usb_hcd_submit_urb (struct urb *urb, gfp_t mem_flags)  		urb->hcpriv = NULL;  		INIT_LIST_HEAD(&urb->urb_list);  		atomic_dec(&urb->use_count); +		/* +		 * Order the write of urb->use_count above before the read +		 * of urb->reject below.  Pairs with the memory barriers in +		 * usb_kill_urb() and usb_poison_urb(). +		 */ +		smp_mb__after_atomic(); +  		atomic_dec(&urb->dev->urbnum);  		if (atomic_read(&urb->reject))  			wake_up(&usb_kill_urb_queue); @@ -1665,6 +1672,13 @@ static void __usb_hcd_giveback_urb(struct urb *urb)  	usb_anchor_resume_wakeups(anchor);  	atomic_dec(&urb->use_count); +	/* +	 * Order the write of urb->use_count above before the read +	 * of urb->reject below.  Pairs with the memory barriers in +	 * usb_kill_urb() and usb_poison_urb(). +	 */ +	smp_mb__after_atomic(); +  	if (unlikely(atomic_read(&urb->reject)))  		wake_up(&usb_kill_urb_queue);  	usb_put_urb(urb); diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c index 30727729a44c..33d62d7e3929 100644 --- a/drivers/usb/core/urb.c +++ b/drivers/usb/core/urb.c @@ -715,6 +715,12 @@ void usb_kill_urb(struct urb *urb)  	if (!(urb && urb->dev && urb->ep))  		return;  	atomic_inc(&urb->reject); +	/* +	 * Order the write of urb->reject above before the read +	 * of urb->use_count below.  Pairs with the barriers in +	 * __usb_hcd_giveback_urb() and usb_hcd_submit_urb(). +	 */ +	smp_mb__after_atomic();  	usb_hcd_unlink_urb(urb, -ENOENT);  	wait_event(usb_kill_urb_queue, atomic_read(&urb->use_count) == 0); @@ -756,6 +762,12 @@ void usb_poison_urb(struct urb *urb)  	if (!urb)  		return;  	atomic_inc(&urb->reject); +	/* +	 * Order the write of urb->reject above before the read +	 * of urb->use_count below.  Pairs with the barriers in +	 * __usb_hcd_giveback_urb() and usb_hcd_submit_urb(). +	 */ +	smp_mb__after_atomic();  	if (!urb->dev || !urb->ep)  		return; |