aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/usb-skeleton.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/usb-skeleton.c')
-rw-r--r--drivers/usb/usb-skeleton.c88
1 files changed, 59 insertions, 29 deletions
diff --git a/drivers/usb/usb-skeleton.c b/drivers/usb/usb-skeleton.c
index ce310170829..e24ce312307 100644
--- a/drivers/usb/usb-skeleton.c
+++ b/drivers/usb/usb-skeleton.c
@@ -60,6 +60,7 @@ struct usb_skel {
60 __u8 bulk_in_endpointAddr; /* the address of the bulk in endpoint */ 60 __u8 bulk_in_endpointAddr; /* the address of the bulk in endpoint */
61 __u8 bulk_out_endpointAddr; /* the address of the bulk out endpoint */ 61 __u8 bulk_out_endpointAddr; /* the address of the bulk out endpoint */
62 int errors; /* the last request tanked */ 62 int errors; /* the last request tanked */
63 int open_count; /* count the number of openers */
63 bool ongoing_read; /* a read is going on */ 64 bool ongoing_read; /* a read is going on */
64 bool processed_urb; /* indicates we haven't processed the urb */ 65 bool processed_urb; /* indicates we haven't processed the urb */
65 spinlock_t err_lock; /* lock for errors */ 66 spinlock_t err_lock; /* lock for errors */
@@ -93,8 +94,8 @@ static int skel_open(struct inode *inode, struct file *file)
93 94
94 interface = usb_find_interface(&skel_driver, subminor); 95 interface = usb_find_interface(&skel_driver, subminor);
95 if (!interface) { 96 if (!interface) {
96 pr_err("%s - error, can't find device for minor %d\n", 97 err("%s - error, can't find device for minor %d",
97 __func__, subminor); 98 __func__, subminor);
98 retval = -ENODEV; 99 retval = -ENODEV;
99 goto exit; 100 goto exit;
100 } 101 }
@@ -105,15 +106,33 @@ static int skel_open(struct inode *inode, struct file *file)
105 goto exit; 106 goto exit;
106 } 107 }
107 108
108 retval = usb_autopm_get_interface(interface);
109 if (retval)
110 goto exit;
111
112 /* increment our usage count for the device */ 109 /* increment our usage count for the device */
113 kref_get(&dev->kref); 110 kref_get(&dev->kref);
114 111
112 /* lock the device to allow correctly handling errors
113 * in resumption */
114 mutex_lock(&dev->io_mutex);
115
116 if (!dev->open_count++) {
117 retval = usb_autopm_get_interface(interface);
118 if (retval) {
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
115 /* save our object in the file's private structure */ 133 /* save our object in the file's private structure */
116 file->private_data = dev; 134 file->private_data = dev;
135 mutex_unlock(&dev->io_mutex);
117 136
118exit: 137exit:
119 return retval; 138 return retval;
@@ -129,7 +148,7 @@ static int skel_release(struct inode *inode, struct file *file)
129 148
130 /* allow the device to be autosuspended */ 149 /* allow the device to be autosuspended */
131 mutex_lock(&dev->io_mutex); 150 mutex_lock(&dev->io_mutex);
132 if (dev->interface) 151 if (!--dev->open_count && dev->interface)
133 usb_autopm_put_interface(dev->interface); 152 usb_autopm_put_interface(dev->interface);
134 mutex_unlock(&dev->io_mutex); 153 mutex_unlock(&dev->io_mutex);
135 154
@@ -174,9 +193,8 @@ static void skel_read_bulk_callback(struct urb *urb)
174 if (!(urb->status == -ENOENT || 193 if (!(urb->status == -ENOENT ||
175 urb->status == -ECONNRESET || 194 urb->status == -ECONNRESET ||
176 urb->status == -ESHUTDOWN)) 195 urb->status == -ESHUTDOWN))
177 dev_err(&dev->interface->dev, 196 err("%s - nonzero write bulk status received: %d",
178 "%s - nonzero write bulk status received: %d\n", 197 __func__, urb->status);
179 __func__, urb->status);
180 198
181 dev->errors = urb->status; 199 dev->errors = urb->status;
182 } else { 200 } else {
@@ -209,8 +227,7 @@ static int skel_do_read_io(struct usb_skel *dev, size_t count)
209 /* do it */ 227 /* do it */
210 rv = usb_submit_urb(dev->bulk_in_urb, GFP_KERNEL); 228 rv = usb_submit_urb(dev->bulk_in_urb, GFP_KERNEL);
211 if (rv < 0) { 229 if (rv < 0) {
212 dev_err(&dev->interface->dev, 230 err("%s - failed submitting read urb, error %d",
213 "%s - failed submitting read urb, error %d\n",
214 __func__, rv); 231 __func__, rv);
215 dev->bulk_in_filled = 0; 232 dev->bulk_in_filled = 0;
216 rv = (rv == -ENOMEM) ? rv : -EIO; 233 rv = (rv == -ENOMEM) ? rv : -EIO;
@@ -361,9 +378,8 @@ static void skel_write_bulk_callback(struct urb *urb)
361 if (!(urb->status == -ENOENT || 378 if (!(urb->status == -ENOENT ||
362 urb->status == -ECONNRESET || 379 urb->status == -ECONNRESET ||
363 urb->status == -ESHUTDOWN)) 380 urb->status == -ESHUTDOWN))
364 dev_err(&dev->interface->dev, 381 err("%s - nonzero write bulk status received: %d",
365 "%s - nonzero write bulk status received: %d\n", 382 __func__, urb->status);
366 __func__, urb->status);
367 383
368 spin_lock(&dev->err_lock); 384 spin_lock(&dev->err_lock);
369 dev->errors = urb->status; 385 dev->errors = urb->status;
@@ -457,9 +473,8 @@ static ssize_t skel_write(struct file *file, const char *user_buffer,
457 retval = usb_submit_urb(urb, GFP_KERNEL); 473 retval = usb_submit_urb(urb, GFP_KERNEL);
458 mutex_unlock(&dev->io_mutex); 474 mutex_unlock(&dev->io_mutex);
459 if (retval) { 475 if (retval) {
460 dev_err(&dev->interface->dev, 476 err("%s - failed submitting write urb, error %d", __func__,
461 "%s - failed submitting write urb, error %d\n", 477 retval);
462 __func__, retval);
463 goto error_unanchor; 478 goto error_unanchor;
464 } 479 }
465 480
@@ -518,7 +533,7 @@ static int skel_probe(struct usb_interface *interface,
518 /* allocate memory for our device state and initialize it */ 533 /* allocate memory for our device state and initialize it */
519 dev = kzalloc(sizeof(*dev), GFP_KERNEL); 534 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
520 if (!dev) { 535 if (!dev) {
521 dev_err(&interface->dev, "Out of memory\n"); 536 err("Out of memory");
522 goto error; 537 goto error;
523 } 538 }
524 kref_init(&dev->kref); 539 kref_init(&dev->kref);
@@ -540,19 +555,17 @@ static int skel_probe(struct usb_interface *interface,
540 if (!dev->bulk_in_endpointAddr && 555 if (!dev->bulk_in_endpointAddr &&
541 usb_endpoint_is_bulk_in(endpoint)) { 556 usb_endpoint_is_bulk_in(endpoint)) {
542 /* we found a bulk in endpoint */ 557 /* we found a bulk in endpoint */
543 buffer_size = usb_endpoint_maxp(endpoint); 558 buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
544 dev->bulk_in_size = buffer_size; 559 dev->bulk_in_size = buffer_size;
545 dev->bulk_in_endpointAddr = endpoint->bEndpointAddress; 560 dev->bulk_in_endpointAddr = endpoint->bEndpointAddress;
546 dev->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL); 561 dev->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL);
547 if (!dev->bulk_in_buffer) { 562 if (!dev->bulk_in_buffer) {
548 dev_err(&interface->dev, 563 err("Could not allocate bulk_in_buffer");
549 "Could not allocate bulk_in_buffer\n");
550 goto error; 564 goto error;
551 } 565 }
552 dev->bulk_in_urb = usb_alloc_urb(0, GFP_KERNEL); 566 dev->bulk_in_urb = usb_alloc_urb(0, GFP_KERNEL);
553 if (!dev->bulk_in_urb) { 567 if (!dev->bulk_in_urb) {
554 dev_err(&interface->dev, 568 err("Could not allocate bulk_in_urb");
555 "Could not allocate bulk_in_urb\n");
556 goto error; 569 goto error;
557 } 570 }
558 } 571 }
@@ -564,8 +577,7 @@ static int skel_probe(struct usb_interface *interface,
564 } 577 }
565 } 578 }
566 if (!(dev->bulk_in_endpointAddr && dev->bulk_out_endpointAddr)) { 579 if (!(dev->bulk_in_endpointAddr && dev->bulk_out_endpointAddr)) {
567 dev_err(&interface->dev, 580 err("Could not find both bulk-in and bulk-out endpoints");
568 "Could not find both bulk-in and bulk-out endpoints\n");
569 goto error; 581 goto error;
570 } 582 }
571 583
@@ -576,8 +588,7 @@ static int skel_probe(struct usb_interface *interface,
576 retval = usb_register_dev(interface, &skel_class); 588 retval = usb_register_dev(interface, &skel_class);
577 if (retval) { 589 if (retval) {
578 /* something prevented us from registering this driver */ 590 /* something prevented us from registering this driver */
579 dev_err(&interface->dev, 591 err("Not able to get a minor for this device.");
580 "Not able to get a minor for this device.\n");
581 usb_set_intfdata(interface, NULL); 592 usb_set_intfdata(interface, NULL);
582 goto error; 593 goto error;
583 } 594 }
@@ -677,6 +688,25 @@ static struct usb_driver skel_driver = {
677 .supports_autosuspend = 1, 688 .supports_autosuspend = 1,
678}; 689};
679 690
680module_usb_driver(skel_driver); 691static int __init usb_skel_init(void)
692{
693 int result;
694
695 /* register this driver with the USB subsystem */
696 result = usb_register(&skel_driver);
697 if (result)
698 err("usb_register failed. Error number %d", result);
699
700 return result;
701}
702
703static void __exit usb_skel_exit(void)
704{
705 /* deregister this driver with the USB subsystem */
706 usb_deregister(&skel_driver);
707}
708
709module_init(usb_skel_init);
710module_exit(usb_skel_exit);
681 711
682MODULE_LICENSE("GPL"); 712MODULE_LICENSE("GPL");