aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/gspca/gspca.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/gspca/gspca.c')
-rw-r--r--drivers/media/video/gspca/gspca.c245
1 files changed, 170 insertions, 75 deletions
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c
index ac95c55887df..c21af312ee7c 100644
--- a/drivers/media/video/gspca/gspca.c
+++ b/drivers/media/video/gspca/gspca.c
@@ -29,6 +29,7 @@
29#include <linux/string.h> 29#include <linux/string.h>
30#include <linux/pagemap.h> 30#include <linux/pagemap.h>
31#include <linux/io.h> 31#include <linux/io.h>
32#include <linux/kref.h>
32#include <asm/page.h> 33#include <asm/page.h>
33#include <linux/uaccess.h> 34#include <linux/uaccess.h>
34#include <linux/jiffies.h> 35#include <linux/jiffies.h>
@@ -43,7 +44,7 @@ MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>");
43MODULE_DESCRIPTION("GSPCA USB Camera Driver"); 44MODULE_DESCRIPTION("GSPCA USB Camera Driver");
44MODULE_LICENSE("GPL"); 45MODULE_LICENSE("GPL");
45 46
46#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 2, 0) 47#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 3, 0)
47 48
48static int video_nr = -1; 49static int video_nr = -1;
49 50
@@ -102,6 +103,22 @@ static struct vm_operations_struct gspca_vm_ops = {
102 .close = gspca_vm_close, 103 .close = gspca_vm_close,
103}; 104};
104 105
106/* get the current input frame buffer */
107struct gspca_frame *gspca_get_i_frame(struct gspca_dev *gspca_dev)
108{
109 struct gspca_frame *frame;
110 int i;
111
112 i = gspca_dev->fr_i;
113 i = gspca_dev->fr_queue[i];
114 frame = &gspca_dev->frame[i];
115 if ((frame->v4l2_buf.flags & BUF_ALL_FLAGS)
116 != V4L2_BUF_FLAG_QUEUED)
117 return NULL;
118 return frame;
119}
120EXPORT_SYMBOL(gspca_get_i_frame);
121
105/* 122/*
106 * fill a video frame from an URB and resubmit 123 * fill a video frame from an URB and resubmit
107 */ 124 */
@@ -110,7 +127,7 @@ static void fill_frame(struct gspca_dev *gspca_dev,
110{ 127{
111 struct gspca_frame *frame; 128 struct gspca_frame *frame;
112 __u8 *data; /* address of data in the iso message */ 129 __u8 *data; /* address of data in the iso message */
113 int i, j, len, st; 130 int i, len, st;
114 cam_pkt_op pkt_scan; 131 cam_pkt_op pkt_scan;
115 132
116 if (urb->status != 0) { 133 if (urb->status != 0) {
@@ -124,11 +141,8 @@ static void fill_frame(struct gspca_dev *gspca_dev,
124 for (i = 0; i < urb->number_of_packets; i++) { 141 for (i = 0; i < urb->number_of_packets; i++) {
125 142
126 /* check the availability of the frame buffer */ 143 /* check the availability of the frame buffer */
127 j = gspca_dev->fr_i; 144 frame = gspca_get_i_frame(gspca_dev);
128 j = gspca_dev->fr_queue[j]; 145 if (!frame) {
129 frame = &gspca_dev->frame[j];
130 if ((frame->v4l2_buf.flags & BUF_ALL_FLAGS)
131 != V4L2_BUF_FLAG_QUEUED) {
132 gspca_dev->last_packet_type = DISCARD_PACKET; 146 gspca_dev->last_packet_type = DISCARD_PACKET;
133 break; 147 break;
134 } 148 }
@@ -178,6 +192,39 @@ static void isoc_irq(struct urb *urb
178} 192}
179 193
180/* 194/*
195 * bulk message interrupt from the USB device
196 */
197static void bulk_irq(struct urb *urb
198)
199{
200 struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context;
201 struct gspca_frame *frame;
202
203 PDEBUG(D_PACK, "bulk irq");
204 if (!gspca_dev->streaming)
205 return;
206 if (urb->status != 0 && urb->status != -ECONNRESET) {
207#ifdef CONFIG_PM
208 if (!gspca_dev->frozen)
209#endif
210 PDEBUG(D_ERR|D_PACK, "urb status: %d", urb->status);
211 return; /* disconnection ? */
212 }
213
214 /* check the availability of the frame buffer */
215 frame = gspca_get_i_frame(gspca_dev);
216 if (!frame) {
217 gspca_dev->last_packet_type = DISCARD_PACKET;
218 } else {
219 PDEBUG(D_PACK, "packet l:%d", urb->actual_length);
220 gspca_dev->sd_desc->pkt_scan(gspca_dev,
221 frame,
222 urb->transfer_buffer,
223 urb->actual_length);
224 }
225}
226
227/*
181 * add data to the current frame 228 * add data to the current frame
182 * 229 *
183 * This function is called by the subdrivers at interrupt level. 230 * This function is called by the subdrivers at interrupt level.
@@ -190,7 +237,7 @@ static void isoc_irq(struct urb *urb
190 * On LAST_PACKET, a new frame is returned. 237 * On LAST_PACKET, a new frame is returned.
191 */ 238 */
192struct gspca_frame *gspca_frame_add(struct gspca_dev *gspca_dev, 239struct gspca_frame *gspca_frame_add(struct gspca_dev *gspca_dev,
193 int packet_type, 240 enum gspca_packet_type packet_type,
194 struct gspca_frame *frame, 241 struct gspca_frame *frame,
195 const __u8 *data, 242 const __u8 *data,
196 int len) 243 int len)
@@ -232,7 +279,7 @@ struct gspca_frame *gspca_frame_add(struct gspca_dev *gspca_dev,
232 } 279 }
233 gspca_dev->last_packet_type = packet_type; 280 gspca_dev->last_packet_type = packet_type;
234 281
235 /* if last packet, wake the application and advance in the queue */ 282 /* if last packet, wake up the application and advance in the queue */
236 if (packet_type == LAST_PACKET) { 283 if (packet_type == LAST_PACKET) {
237 frame->v4l2_buf.bytesused = frame->data_end - frame->data; 284 frame->v4l2_buf.bytesused = frame->data_end - frame->data;
238 frame->v4l2_buf.flags &= ~V4L2_BUF_FLAG_QUEUED; 285 frame->v4l2_buf.flags &= ~V4L2_BUF_FLAG_QUEUED;
@@ -270,7 +317,6 @@ static void *rvmalloc(unsigned long size)
270 void *mem; 317 void *mem;
271 unsigned long adr; 318 unsigned long adr;
272 319
273/* size = PAGE_ALIGN(size); (already done) */
274 mem = vmalloc_32(size); 320 mem = vmalloc_32(size);
275 if (mem != NULL) { 321 if (mem != NULL) {
276 adr = (unsigned long) mem; 322 adr = (unsigned long) mem;
@@ -374,10 +420,11 @@ static void destroy_urbs(struct gspca_dev *gspca_dev)
374} 420}
375 421
376/* 422/*
377 * search an input isochronous endpoint in an alternate setting 423 * look for an input transfer endpoint in an alternate setting
378 */ 424 */
379static struct usb_host_endpoint *alt_isoc(struct usb_host_interface *alt, 425static struct usb_host_endpoint *alt_xfer(struct usb_host_interface *alt,
380 __u8 epaddr) 426 __u8 epaddr,
427 __u8 xfer)
381{ 428{
382 struct usb_host_endpoint *ep; 429 struct usb_host_endpoint *ep;
383 int i, attr; 430 int i, attr;
@@ -388,7 +435,7 @@ static struct usb_host_endpoint *alt_isoc(struct usb_host_interface *alt,
388 if (ep->desc.bEndpointAddress == epaddr) { 435 if (ep->desc.bEndpointAddress == epaddr) {
389 attr = ep->desc.bmAttributes 436 attr = ep->desc.bmAttributes
390 & USB_ENDPOINT_XFERTYPE_MASK; 437 & USB_ENDPOINT_XFERTYPE_MASK;
391 if (attr == USB_ENDPOINT_XFER_ISOC) 438 if (attr == xfer)
392 return ep; 439 return ep;
393 break; 440 break;
394 } 441 }
@@ -397,14 +444,14 @@ static struct usb_host_endpoint *alt_isoc(struct usb_host_interface *alt,
397} 444}
398 445
399/* 446/*
400 * search an input isochronous endpoint 447 * look for an input (isoc or bulk) endpoint
401 * 448 *
402 * The endpoint is defined by the subdriver. 449 * The endpoint is defined by the subdriver.
403 * Use only the first isoc (some Zoran - 0x0572:0x0001 - have two such ep). 450 * Use only the first isoc (some Zoran - 0x0572:0x0001 - have two such ep).
404 * This routine may be called many times when the bandwidth is too small 451 * This routine may be called many times when the bandwidth is too small
405 * (the bandwidth is checked on urb submit). 452 * (the bandwidth is checked on urb submit).
406 */ 453 */
407static struct usb_host_endpoint *get_isoc_ep(struct gspca_dev *gspca_dev) 454static struct usb_host_endpoint *get_ep(struct gspca_dev *gspca_dev)
408{ 455{
409 struct usb_interface *intf; 456 struct usb_interface *intf;
410 struct usb_host_endpoint *ep; 457 struct usb_host_endpoint *ep;
@@ -413,28 +460,41 @@ static struct usb_host_endpoint *get_isoc_ep(struct gspca_dev *gspca_dev)
413 intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface); 460 intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface);
414 ep = NULL; 461 ep = NULL;
415 i = gspca_dev->alt; /* previous alt setting */ 462 i = gspca_dev->alt; /* previous alt setting */
463
464 /* try isoc */
416 while (--i > 0) { /* alt 0 is unusable */ 465 while (--i > 0) { /* alt 0 is unusable */
417 ep = alt_isoc(&intf->altsetting[i], gspca_dev->cam.epaddr); 466 ep = alt_xfer(&intf->altsetting[i],
467 gspca_dev->cam.epaddr,
468 USB_ENDPOINT_XFER_ISOC);
418 if (ep) 469 if (ep)
419 break; 470 break;
420 } 471 }
472
473 /* if no isoc, try bulk */
421 if (ep == NULL) { 474 if (ep == NULL) {
422 err("no ISOC endpoint found"); 475 ep = alt_xfer(&intf->altsetting[0],
423 return NULL; 476 gspca_dev->cam.epaddr,
477 USB_ENDPOINT_XFER_BULK);
478 if (ep == NULL) {
479 err("no transfer endpoint found");
480 return NULL;
481 }
424 } 482 }
425 PDEBUG(D_STREAM, "use ISOC alt %d ep 0x%02x", 483 PDEBUG(D_STREAM, "use alt %d ep 0x%02x",
426 i, ep->desc.bEndpointAddress); 484 i, ep->desc.bEndpointAddress);
427 ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, i); 485 if (i > 0) {
428 if (ret < 0) { 486 ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, i);
429 err("set interface err %d", ret); 487 if (ret < 0) {
430 return NULL; 488 err("set interface err %d", ret);
489 return NULL;
490 }
431 } 491 }
432 gspca_dev->alt = i; /* memorize the current alt setting */ 492 gspca_dev->alt = i; /* memorize the current alt setting */
433 return ep; 493 return ep;
434} 494}
435 495
436/* 496/*
437 * create the isochronous URBs 497 * create the URBs for image transfer
438 */ 498 */
439static int create_urbs(struct gspca_dev *gspca_dev, 499static int create_urbs(struct gspca_dev *gspca_dev,
440 struct usb_host_endpoint *ep) 500 struct usb_host_endpoint *ep)
@@ -445,15 +505,27 @@ static int create_urbs(struct gspca_dev *gspca_dev,
445 /* calculate the packet size and the number of packets */ 505 /* calculate the packet size and the number of packets */
446 psize = le16_to_cpu(ep->desc.wMaxPacketSize); 506 psize = le16_to_cpu(ep->desc.wMaxPacketSize);
447 507
448 /* See paragraph 5.9 / table 5-11 of the usb 2.0 spec. */ 508 if (gspca_dev->alt != 0) { /* isoc */
449 psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3)); 509
450 npkt = ISO_MAX_SIZE / psize; 510 /* See paragraph 5.9 / table 5-11 of the usb 2.0 spec. */
451 if (npkt > ISO_MAX_PKT) 511 psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3));
452 npkt = ISO_MAX_PKT; 512 npkt = ISO_MAX_SIZE / psize;
453 bsize = psize * npkt; 513 if (npkt > ISO_MAX_PKT)
454 PDEBUG(D_STREAM, 514 npkt = ISO_MAX_PKT;
455 "isoc %d pkts size %d (bsize:%d)", npkt, psize, bsize); 515 bsize = psize * npkt;
456 nurbs = DEF_NURBS; 516 PDEBUG(D_STREAM,
517 "isoc %d pkts size %d = bsize:%d",
518 npkt, psize, bsize);
519 nurbs = DEF_NURBS;
520 } else { /* bulk */
521 npkt = 0;
522 bsize = gspca_dev->cam. bulk_size;
523 if (bsize == 0)
524 bsize = psize;
525 PDEBUG(D_STREAM, "bulk bsize:%d", bsize);
526 nurbs = 1;
527 }
528
457 gspca_dev->nurbs = nurbs; 529 gspca_dev->nurbs = nurbs;
458 for (n = 0; n < nurbs; n++) { 530 for (n = 0; n < nurbs; n++) {
459 urb = usb_alloc_urb(npkt, GFP_KERNEL); 531 urb = usb_alloc_urb(npkt, GFP_KERNEL);
@@ -476,17 +548,24 @@ static int create_urbs(struct gspca_dev *gspca_dev,
476 gspca_dev->urb[n] = urb; 548 gspca_dev->urb[n] = urb;
477 urb->dev = gspca_dev->dev; 549 urb->dev = gspca_dev->dev;
478 urb->context = gspca_dev; 550 urb->context = gspca_dev;
479 urb->pipe = usb_rcvisocpipe(gspca_dev->dev,
480 ep->desc.bEndpointAddress);
481 urb->transfer_flags = URB_ISO_ASAP
482 | URB_NO_TRANSFER_DMA_MAP;
483 urb->interval = ep->desc.bInterval;
484 urb->complete = isoc_irq;
485 urb->number_of_packets = npkt;
486 urb->transfer_buffer_length = bsize; 551 urb->transfer_buffer_length = bsize;
487 for (i = 0; i < npkt; i++) { 552 if (npkt != 0) { /* ISOC */
488 urb->iso_frame_desc[i].length = psize; 553 urb->pipe = usb_rcvisocpipe(gspca_dev->dev,
489 urb->iso_frame_desc[i].offset = psize * i; 554 ep->desc.bEndpointAddress);
555 urb->transfer_flags = URB_ISO_ASAP
556 | URB_NO_TRANSFER_DMA_MAP;
557 urb->interval = ep->desc.bInterval;
558 urb->complete = isoc_irq;
559 urb->number_of_packets = npkt;
560 for (i = 0; i < npkt; i++) {
561 urb->iso_frame_desc[i].length = psize;
562 urb->iso_frame_desc[i].offset = psize * i;
563 }
564 } else { /* bulk */
565 urb->pipe = usb_rcvbulkpipe(gspca_dev->dev,
566 ep->desc.bEndpointAddress),
567 urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP;
568 urb->complete = bulk_irq;
490 } 569 }
491 } 570 }
492 return 0; 571 return 0;
@@ -508,7 +587,7 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev)
508 gspca_dev->alt = gspca_dev->nbalt; 587 gspca_dev->alt = gspca_dev->nbalt;
509 for (;;) { 588 for (;;) {
510 PDEBUG(D_STREAM, "init transfer alt %d", gspca_dev->alt); 589 PDEBUG(D_STREAM, "init transfer alt %d", gspca_dev->alt);
511 ep = get_isoc_ep(gspca_dev); 590 ep = get_ep(gspca_dev);
512 if (ep == NULL) { 591 if (ep == NULL) {
513 ret = -EIO; 592 ret = -EIO;
514 goto out; 593 goto out;
@@ -518,10 +597,18 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev)
518 goto out; 597 goto out;
519 598
520 /* start the cam */ 599 /* start the cam */
521 gspca_dev->sd_desc->start(gspca_dev); 600 ret = gspca_dev->sd_desc->start(gspca_dev);
601 if (ret < 0) {
602 destroy_urbs(gspca_dev);
603 goto out;
604 }
522 gspca_dev->streaming = 1; 605 gspca_dev->streaming = 1;
523 atomic_set(&gspca_dev->nevent, 0); 606 atomic_set(&gspca_dev->nevent, 0);
524 607
608 /* bulk transfers are started by the subdriver */
609 if (gspca_dev->alt == 0)
610 break;
611
525 /* submit the URBs */ 612 /* submit the URBs */
526 for (n = 0; n < gspca_dev->nurbs; n++) { 613 for (n = 0; n < gspca_dev->nurbs; n++) {
527 ret = usb_submit_urb(gspca_dev->urb[n], GFP_KERNEL); 614 ret = usb_submit_urb(gspca_dev->urb[n], GFP_KERNEL);
@@ -553,7 +640,7 @@ static int gspca_set_alt0(struct gspca_dev *gspca_dev)
553 return ret; 640 return ret;
554} 641}
555 642
556/* Note both the queue and the usb lock should be hold when calling this */ 643/* Note: both the queue and the usb locks should be held when calling this */
557static void gspca_stream_off(struct gspca_dev *gspca_dev) 644static void gspca_stream_off(struct gspca_dev *gspca_dev)
558{ 645{
559 gspca_dev->streaming = 0; 646 gspca_dev->streaming = 0;
@@ -759,6 +846,16 @@ out:
759 return ret; 846 return ret;
760} 847}
761 848
849static void gspca_delete(struct kref *kref)
850{
851 struct gspca_dev *gspca_dev = container_of(kref, struct gspca_dev, kref);
852
853 PDEBUG(D_STREAM, "device deleted");
854
855 kfree(gspca_dev->usb_buf);
856 kfree(gspca_dev);
857}
858
762static int dev_open(struct inode *inode, struct file *file) 859static int dev_open(struct inode *inode, struct file *file)
763{ 860{
764 struct gspca_dev *gspca_dev; 861 struct gspca_dev *gspca_dev;
@@ -778,13 +875,19 @@ static int dev_open(struct inode *inode, struct file *file)
778 goto out; 875 goto out;
779 } 876 }
780 gspca_dev->users++; 877 gspca_dev->users++;
878
879 /* one more user */
880 kref_get(&gspca_dev->kref);
881
781 file->private_data = gspca_dev; 882 file->private_data = gspca_dev;
782#ifdef GSPCA_DEBUG 883#ifdef GSPCA_DEBUG
783 /* activate the v4l2 debug */ 884 /* activate the v4l2 debug */
784 if (gspca_debug & D_V4L2) 885 if (gspca_debug & D_V4L2)
785 gspca_dev->vdev.debug |= 3; 886 gspca_dev->vdev.debug |= V4L2_DEBUG_IOCTL
887 | V4L2_DEBUG_IOCTL_ARG;
786 else 888 else
787 gspca_dev->vdev.debug &= ~3; 889 gspca_dev->vdev.debug &= ~(V4L2_DEBUG_IOCTL
890 | V4L2_DEBUG_IOCTL_ARG);
788#endif 891#endif
789 ret = 0; 892 ret = 0;
790out: 893out:
@@ -818,7 +921,11 @@ static int dev_close(struct inode *inode, struct file *file)
818 } 921 }
819 file->private_data = NULL; 922 file->private_data = NULL;
820 mutex_unlock(&gspca_dev->queue_lock); 923 mutex_unlock(&gspca_dev->queue_lock);
924
821 PDEBUG(D_STREAM, "close done"); 925 PDEBUG(D_STREAM, "close done");
926
927 kref_put(&gspca_dev->kref, gspca_delete);
928
822 return 0; 929 return 0;
823} 930}
824 931
@@ -829,7 +936,6 @@ static int vidioc_querycap(struct file *file, void *priv,
829 936
830 memset(cap, 0, sizeof *cap); 937 memset(cap, 0, sizeof *cap);
831 strncpy(cap->driver, gspca_dev->sd_desc->name, sizeof cap->driver); 938 strncpy(cap->driver, gspca_dev->sd_desc->name, sizeof cap->driver);
832/* strncpy(cap->card, gspca_dev->cam.dev_name, sizeof cap->card); */
833 if (gspca_dev->dev->product != NULL) { 939 if (gspca_dev->dev->product != NULL) {
834 strncpy(cap->card, gspca_dev->dev->product, 940 strncpy(cap->card, gspca_dev->dev->product,
835 sizeof cap->card); 941 sizeof cap->card);
@@ -1463,7 +1569,6 @@ static int vidioc_qbuf(struct file *file, void *priv,
1463 } 1569 }
1464 1570
1465 frame->v4l2_buf.flags |= V4L2_BUF_FLAG_QUEUED; 1571 frame->v4l2_buf.flags |= V4L2_BUF_FLAG_QUEUED;
1466/* frame->v4l2_buf.flags &= ~V4L2_BUF_FLAG_DONE; */
1467 1572
1468 if (frame->v4l2_buf.memory == V4L2_MEMORY_USERPTR) { 1573 if (frame->v4l2_buf.memory == V4L2_MEMORY_USERPTR) {
1469 frame->v4l2_buf.m.userptr = v4l2_buf->m.userptr; 1574 frame->v4l2_buf.m.userptr = v4l2_buf->m.userptr;
@@ -1610,7 +1715,7 @@ static ssize_t dev_read(struct file *file, char __user *data,
1610 } 1715 }
1611 1716
1612 /* if the process slept for more than 1 second, 1717 /* if the process slept for more than 1 second,
1613 * get anewer frame */ 1718 * get a newer frame */
1614 frame = &gspca_dev->frame[v4l2_buf.index]; 1719 frame = &gspca_dev->frame[v4l2_buf.index];
1615 if (--n < 0) 1720 if (--n < 0)
1616 break; /* avoid infinite loop */ 1721 break; /* avoid infinite loop */
@@ -1728,21 +1833,21 @@ int gspca_dev_probe(struct usb_interface *intf,
1728 if (dev_size < sizeof *gspca_dev) 1833 if (dev_size < sizeof *gspca_dev)
1729 dev_size = sizeof *gspca_dev; 1834 dev_size = sizeof *gspca_dev;
1730 gspca_dev = kzalloc(dev_size, GFP_KERNEL); 1835 gspca_dev = kzalloc(dev_size, GFP_KERNEL);
1731 if (gspca_dev == NULL) { 1836 if (!gspca_dev) {
1732 err("couldn't kzalloc gspca struct"); 1837 err("couldn't kzalloc gspca struct");
1733 return -EIO; 1838 return -ENOMEM;
1734 } 1839 }
1840 kref_init(&gspca_dev->kref);
1735 gspca_dev->usb_buf = kmalloc(USB_BUF_SZ, GFP_KERNEL); 1841 gspca_dev->usb_buf = kmalloc(USB_BUF_SZ, GFP_KERNEL);
1736 if (!gspca_dev->usb_buf) { 1842 if (!gspca_dev->usb_buf) {
1737 err("out of memory"); 1843 err("out of memory");
1738 ret = -EIO; 1844 ret = -ENOMEM;
1739 goto out; 1845 goto out;
1740 } 1846 }
1741 gspca_dev->dev = dev; 1847 gspca_dev->dev = dev;
1742 gspca_dev->iface = interface->bInterfaceNumber; 1848 gspca_dev->iface = interface->bInterfaceNumber;
1743 gspca_dev->nbalt = intf->num_altsetting; 1849 gspca_dev->nbalt = intf->num_altsetting;
1744 gspca_dev->sd_desc = sd_desc; 1850 gspca_dev->sd_desc = sd_desc;
1745/* gspca_dev->users = 0; (done by kzalloc) */
1746 gspca_dev->nbufread = 2; 1851 gspca_dev->nbufread = 2;
1747 1852
1748 /* configure the subdriver and initialize the USB device */ 1853 /* configure the subdriver and initialize the USB device */
@@ -1781,8 +1886,7 @@ int gspca_dev_probe(struct usb_interface *intf,
1781 PDEBUG(D_PROBE, "probe ok"); 1886 PDEBUG(D_PROBE, "probe ok");
1782 return 0; 1887 return 0;
1783out: 1888out:
1784 kfree(gspca_dev->usb_buf); 1889 kref_put(&gspca_dev->kref, gspca_delete);
1785 kfree(gspca_dev);
1786 return ret; 1890 return ret;
1787} 1891}
1788EXPORT_SYMBOL(gspca_dev_probe); 1892EXPORT_SYMBOL(gspca_dev_probe);
@@ -1797,25 +1901,16 @@ void gspca_disconnect(struct usb_interface *intf)
1797{ 1901{
1798 struct gspca_dev *gspca_dev = usb_get_intfdata(intf); 1902 struct gspca_dev *gspca_dev = usb_get_intfdata(intf);
1799 1903
1800 if (!gspca_dev) 1904 usb_set_intfdata(intf, NULL);
1801 return; 1905
1802 gspca_dev->present = 0;
1803 mutex_lock(&gspca_dev->queue_lock);
1804 mutex_lock(&gspca_dev->usb_lock);
1805 gspca_dev->streaming = 0;
1806 destroy_urbs(gspca_dev);
1807 mutex_unlock(&gspca_dev->usb_lock);
1808 mutex_unlock(&gspca_dev->queue_lock);
1809 while (gspca_dev->users != 0) { /* wait until fully closed */
1810 atomic_inc(&gspca_dev->nevent);
1811 wake_up_interruptible(&gspca_dev->wq); /* wake processes */
1812 schedule();
1813 }
1814/* We don't want people trying to open up the device */ 1906/* We don't want people trying to open up the device */
1815 video_unregister_device(&gspca_dev->vdev); 1907 video_unregister_device(&gspca_dev->vdev);
1816/* Free the memory */ 1908
1817 kfree(gspca_dev->usb_buf); 1909 gspca_dev->present = 0;
1818 kfree(gspca_dev); 1910 gspca_dev->streaming = 0;
1911
1912 kref_put(&gspca_dev->kref, gspca_delete);
1913
1819 PDEBUG(D_PROBE, "disconnect complete"); 1914 PDEBUG(D_PROBE, "disconnect complete");
1820} 1915}
1821EXPORT_SYMBOL(gspca_disconnect); 1916EXPORT_SYMBOL(gspca_disconnect);