diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-01-09 12:09:47 -0800 | 
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-01-09 12:09:47 -0800 | 
| commit | 55b81e6f2795484ea8edf5805c95c007cacfa736 (patch) | |
| tree | c3724975107857fcc03b5dd649c462e4f72397be /drivers/usb/usb-skeleton.c | |
| parent | 5983faf942f260023e547f3c5f38c1033c35cc9b (diff) | |
| parent | 08e87d0d773dc9ca5faf4c3306e238ed0ea129b0 (diff) | |
| download | olio-linux-3.10-55b81e6f2795484ea8edf5805c95c007cacfa736.tar.xz olio-linux-3.10-55b81e6f2795484ea8edf5805c95c007cacfa736.zip  | |
Merge branch 'usb-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
* 'usb-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (232 commits)
  USB: Add USB-ID for Multiplex RC serial adapter to cp210x.c
  xhci: Clean up 32-bit build warnings.
  USB: update documentation for usbmon
  usb: usb-storage doesn't support dynamic id currently, the patch disables the feature to fix an oops
  drivers/usb/class/cdc-acm.c: clear dangling pointer
  drivers/usb/dwc3/dwc3-pci.c: introduce missing kfree
  drivers/usb/host/isp1760-if.c: introduce missing kfree
  usb: option: add ZD Incorporated HSPA modem
  usb: ch9: fix up MaxStreams helper
  USB: usb-skeleton.c: cleanup open_count
  USB: usb-skeleton.c: fix open/disconnect race
  xhci: Properly handle COMP_2ND_BW_ERR
  USB: remove dead code from suspend/resume path
  USB: add quirk for another camera
  drivers: usb: wusbcore: Fix dependency for USB_WUSB
  xhci: Better debugging for critical host errors.
  xhci: Be less verbose during URB cancellation.
  xhci: Remove debugging about ring structure allocation.
  xhci: Remove debugging about toggling cycle bits.
  xhci: Remove debugging for individual transfers.
  ...
Diffstat (limited to 'drivers/usb/usb-skeleton.c')
| -rw-r--r-- | drivers/usb/usb-skeleton.c | 40 | 
1 files changed, 21 insertions, 19 deletions
diff --git a/drivers/usb/usb-skeleton.c b/drivers/usb/usb-skeleton.c index 5c6c1bdbd45..8efeae24764 100644 --- a/drivers/usb/usb-skeleton.c +++ b/drivers/usb/usb-skeleton.c @@ -27,6 +27,8 @@  #define USB_SKEL_VENDOR_ID	0xfff0  #define USB_SKEL_PRODUCT_ID	0xfff0 +static DEFINE_MUTEX(skel_mutex); +  /* table of devices that work with this driver */  static const struct usb_device_id skel_table[] = {  	{ USB_DEVICE(USB_SKEL_VENDOR_ID, USB_SKEL_PRODUCT_ID) }, @@ -60,7 +62,6 @@ struct usb_skel {  	__u8			bulk_in_endpointAddr;	/* the address of the bulk in endpoint */  	__u8			bulk_out_endpointAddr;	/* the address of the bulk out endpoint */  	int			errors;			/* the last request tanked */ -	int			open_count;		/* count the number of openers */  	bool			ongoing_read;		/* a read is going on */  	bool			processed_urb;		/* indicates we haven't processed the urb */  	spinlock_t		err_lock;		/* lock for errors */ @@ -100,39 +101,37 @@ static int skel_open(struct inode *inode, struct file *file)  		goto exit;  	} +	mutex_lock(&skel_mutex);  	dev = usb_get_intfdata(interface);  	if (!dev) { +		mutex_unlock(&skel_mutex);  		retval = -ENODEV;  		goto exit;  	}  	/* increment our usage count for the device */  	kref_get(&dev->kref); +	mutex_unlock(&skel_mutex);  	/* lock the device to allow correctly handling errors  	 * in resumption */  	mutex_lock(&dev->io_mutex); +	if (!dev->interface) { +		retval = -ENODEV; +		goto out_err; +	} -	if (!dev->open_count++) { -		retval = usb_autopm_get_interface(interface); -			if (retval) { -				dev->open_count--; -				mutex_unlock(&dev->io_mutex); -				kref_put(&dev->kref, skel_delete); -				goto exit; -			} -	} /* else { //uncomment this block if you want exclusive open -		retval = -EBUSY; -		dev->open_count--; -		mutex_unlock(&dev->io_mutex); -		kref_put(&dev->kref, skel_delete); -		goto exit; -	} */ -	/* prevent the device from being autosuspended */ +	retval = usb_autopm_get_interface(interface); +	if (retval) +		goto out_err;  	/* save our object in the file's private structure */  	file->private_data = dev; + +out_err:  	mutex_unlock(&dev->io_mutex); +	if (retval) +		kref_put(&dev->kref, skel_delete);  exit:  	return retval; @@ -148,7 +147,7 @@ static int skel_release(struct inode *inode, struct file *file)  	/* allow the device to be autosuspended */  	mutex_lock(&dev->io_mutex); -	if (!--dev->open_count && dev->interface) +	if (dev->interface)  		usb_autopm_put_interface(dev->interface);  	mutex_unlock(&dev->io_mutex); @@ -612,7 +611,6 @@ static void skel_disconnect(struct usb_interface *interface)  	int minor = interface->minor;  	dev = usb_get_intfdata(interface); -	usb_set_intfdata(interface, NULL);  	/* give back our minor */  	usb_deregister_dev(interface, &skel_class); @@ -624,8 +622,12 @@ static void skel_disconnect(struct usb_interface *interface)  	usb_kill_anchored_urbs(&dev->submitted); +	mutex_lock(&skel_mutex); +	usb_set_intfdata(interface, NULL); +  	/* decrement our usage count */  	kref_put(&dev->kref, skel_delete); +	mutex_unlock(&skel_mutex);  	dev_info(&interface->dev, "USB Skeleton #%d now disconnected", minor);  }  |