aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/usb-skeleton.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-01-09 15:09:47 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-01-09 15:09:47 -0500
commit55b81e6f2795484ea8edf5805c95c007cacfa736 (patch)
treec3724975107857fcc03b5dd649c462e4f72397be /drivers/usb/usb-skeleton.c
parent5983faf942f260023e547f3c5f38c1033c35cc9b (diff)
parent08e87d0d773dc9ca5faf4c3306e238ed0ea129b0 (diff)
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.c40
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 @@
27#define USB_SKEL_VENDOR_ID 0xfff0 27#define USB_SKEL_VENDOR_ID 0xfff0
28#define USB_SKEL_PRODUCT_ID 0xfff0 28#define USB_SKEL_PRODUCT_ID 0xfff0
29 29
30static DEFINE_MUTEX(skel_mutex);
31
30/* table of devices that work with this driver */ 32/* table of devices that work with this driver */
31static const struct usb_device_id skel_table[] = { 33static const struct usb_device_id skel_table[] = {
32 { USB_DEVICE(USB_SKEL_VENDOR_ID, USB_SKEL_PRODUCT_ID) }, 34 { USB_DEVICE(USB_SKEL_VENDOR_ID, USB_SKEL_PRODUCT_ID) },
@@ -60,7 +62,6 @@ struct usb_skel {
60 __u8 bulk_in_endpointAddr; /* the address of the bulk in endpoint */ 62 __u8 bulk_in_endpointAddr; /* the address of the bulk in endpoint */
61 __u8 bulk_out_endpointAddr; /* the address of the bulk out endpoint */ 63 __u8 bulk_out_endpointAddr; /* the address of the bulk out endpoint */
62 int errors; /* the last request tanked */ 64 int errors; /* the last request tanked */
63 int open_count; /* count the number of openers */
64 bool ongoing_read; /* a read is going on */ 65 bool ongoing_read; /* a read is going on */
65 bool processed_urb; /* indicates we haven't processed the urb */ 66 bool processed_urb; /* indicates we haven't processed the urb */
66 spinlock_t err_lock; /* lock for errors */ 67 spinlock_t err_lock; /* lock for errors */
@@ -100,39 +101,37 @@ static int skel_open(struct inode *inode, struct file *file)
100 goto exit; 101 goto exit;
101 } 102 }
102 103
104 mutex_lock(&skel_mutex);
103 dev = usb_get_intfdata(interface); 105 dev = usb_get_intfdata(interface);
104 if (!dev) { 106 if (!dev) {
107 mutex_unlock(&skel_mutex);
105 retval = -ENODEV; 108 retval = -ENODEV;
106 goto exit; 109 goto exit;
107 } 110 }
108 111
109 /* increment our usage count for the device */ 112 /* increment our usage count for the device */
110 kref_get(&dev->kref); 113 kref_get(&dev->kref);
114 mutex_unlock(&skel_mutex);
111 115
112 /* lock the device to allow correctly handling errors 116 /* lock the device to allow correctly handling errors
113 * in resumption */ 117 * in resumption */
114 mutex_lock(&dev->io_mutex); 118 mutex_lock(&dev->io_mutex);
119 if (!dev->interface) {
120 retval = -ENODEV;
121 goto out_err;
122 }
115 123
116 if (!dev->open_count++) { 124 retval = usb_autopm_get_interface(interface);
117 retval = usb_autopm_get_interface(interface); 125 if (retval)
118 if (retval) { 126 goto out_err;
119 dev->open_count--;
120 mutex_unlock(&dev->io_mutex);
121 kref_put(&dev->kref, skel_delete);
122 goto exit;
123 }
124 } /* else { //uncomment this block if you want exclusive open
125 retval = -EBUSY;
126 dev->open_count--;
127 mutex_unlock(&dev->io_mutex);
128 kref_put(&dev->kref, skel_delete);
129 goto exit;
130 } */
131 /* prevent the device from being autosuspended */
132 127
133 /* save our object in the file's private structure */ 128 /* save our object in the file's private structure */
134 file->private_data = dev; 129 file->private_data = dev;
130
131out_err:
135 mutex_unlock(&dev->io_mutex); 132 mutex_unlock(&dev->io_mutex);
133 if (retval)
134 kref_put(&dev->kref, skel_delete);
136 135
137exit: 136exit:
138 return retval; 137 return retval;
@@ -148,7 +147,7 @@ static int skel_release(struct inode *inode, struct file *file)
148 147
149 /* allow the device to be autosuspended */ 148 /* allow the device to be autosuspended */
150 mutex_lock(&dev->io_mutex); 149 mutex_lock(&dev->io_mutex);
151 if (!--dev->open_count && dev->interface) 150 if (dev->interface)
152 usb_autopm_put_interface(dev->interface); 151 usb_autopm_put_interface(dev->interface);
153 mutex_unlock(&dev->io_mutex); 152 mutex_unlock(&dev->io_mutex);
154 153
@@ -612,7 +611,6 @@ static void skel_disconnect(struct usb_interface *interface)
612 int minor = interface->minor; 611 int minor = interface->minor;
613 612
614 dev = usb_get_intfdata(interface); 613 dev = usb_get_intfdata(interface);
615 usb_set_intfdata(interface, NULL);
616 614
617 /* give back our minor */ 615 /* give back our minor */
618 usb_deregister_dev(interface, &skel_class); 616 usb_deregister_dev(interface, &skel_class);
@@ -624,8 +622,12 @@ static void skel_disconnect(struct usb_interface *interface)
624 622
625 usb_kill_anchored_urbs(&dev->submitted); 623 usb_kill_anchored_urbs(&dev->submitted);
626 624
625 mutex_lock(&skel_mutex);
626 usb_set_intfdata(interface, NULL);
627
627 /* decrement our usage count */ 628 /* decrement our usage count */
628 kref_put(&dev->kref, skel_delete); 629 kref_put(&dev->kref, skel_delete);
630 mutex_unlock(&skel_mutex);
629 631
630 dev_info(&interface->dev, "USB Skeleton #%d now disconnected", minor); 632 dev_info(&interface->dev, "USB Skeleton #%d now disconnected", minor);
631} 633}