diff options
Diffstat (limited to 'drivers/media/video/gspca/gspca.c')
-rw-r--r-- | drivers/media/video/gspca/gspca.c | 210 |
1 files changed, 95 insertions, 115 deletions
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index 442970073e8a..f21f2a258ae0 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c | |||
@@ -55,7 +55,7 @@ MODULE_AUTHOR("Jean-François Moine <http://moinejf.free.fr>"); | |||
55 | MODULE_DESCRIPTION("GSPCA USB Camera Driver"); | 55 | MODULE_DESCRIPTION("GSPCA USB Camera Driver"); |
56 | MODULE_LICENSE("GPL"); | 56 | MODULE_LICENSE("GPL"); |
57 | 57 | ||
58 | #define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 11, 0) | 58 | #define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 12, 0) |
59 | 59 | ||
60 | #ifdef GSPCA_DEBUG | 60 | #ifdef GSPCA_DEBUG |
61 | int gspca_debug = D_ERR | D_PROBE; | 61 | int gspca_debug = D_ERR | D_PROBE; |
@@ -508,8 +508,8 @@ static int gspca_is_compressed(__u32 format) | |||
508 | return 0; | 508 | return 0; |
509 | } | 509 | } |
510 | 510 | ||
511 | static int frame_alloc(struct gspca_dev *gspca_dev, | 511 | static int frame_alloc(struct gspca_dev *gspca_dev, struct file *file, |
512 | unsigned int count) | 512 | enum v4l2_memory memory, unsigned int count) |
513 | { | 513 | { |
514 | struct gspca_frame *frame; | 514 | struct gspca_frame *frame; |
515 | unsigned int frsz; | 515 | unsigned int frsz; |
@@ -519,7 +519,6 @@ static int frame_alloc(struct gspca_dev *gspca_dev, | |||
519 | frsz = gspca_dev->cam.cam_mode[i].sizeimage; | 519 | frsz = gspca_dev->cam.cam_mode[i].sizeimage; |
520 | PDEBUG(D_STREAM, "frame alloc frsz: %d", frsz); | 520 | PDEBUG(D_STREAM, "frame alloc frsz: %d", frsz); |
521 | frsz = PAGE_ALIGN(frsz); | 521 | frsz = PAGE_ALIGN(frsz); |
522 | gspca_dev->frsz = frsz; | ||
523 | if (count >= GSPCA_MAX_FRAMES) | 522 | if (count >= GSPCA_MAX_FRAMES) |
524 | count = GSPCA_MAX_FRAMES - 1; | 523 | count = GSPCA_MAX_FRAMES - 1; |
525 | gspca_dev->frbuf = vmalloc_32(frsz * count); | 524 | gspca_dev->frbuf = vmalloc_32(frsz * count); |
@@ -527,6 +526,9 @@ static int frame_alloc(struct gspca_dev *gspca_dev, | |||
527 | err("frame alloc failed"); | 526 | err("frame alloc failed"); |
528 | return -ENOMEM; | 527 | return -ENOMEM; |
529 | } | 528 | } |
529 | gspca_dev->capt_file = file; | ||
530 | gspca_dev->memory = memory; | ||
531 | gspca_dev->frsz = frsz; | ||
530 | gspca_dev->nframes = count; | 532 | gspca_dev->nframes = count; |
531 | for (i = 0; i < count; i++) { | 533 | for (i = 0; i < count; i++) { |
532 | frame = &gspca_dev->frame[i]; | 534 | frame = &gspca_dev->frame[i]; |
@@ -535,7 +537,7 @@ static int frame_alloc(struct gspca_dev *gspca_dev, | |||
535 | frame->v4l2_buf.flags = 0; | 537 | frame->v4l2_buf.flags = 0; |
536 | frame->v4l2_buf.field = V4L2_FIELD_NONE; | 538 | frame->v4l2_buf.field = V4L2_FIELD_NONE; |
537 | frame->v4l2_buf.length = frsz; | 539 | frame->v4l2_buf.length = frsz; |
538 | frame->v4l2_buf.memory = gspca_dev->memory; | 540 | frame->v4l2_buf.memory = memory; |
539 | frame->v4l2_buf.sequence = 0; | 541 | frame->v4l2_buf.sequence = 0; |
540 | frame->data = gspca_dev->frbuf + i * frsz; | 542 | frame->data = gspca_dev->frbuf + i * frsz; |
541 | frame->v4l2_buf.m.offset = i * frsz; | 543 | frame->v4l2_buf.m.offset = i * frsz; |
@@ -558,6 +560,9 @@ static void frame_free(struct gspca_dev *gspca_dev) | |||
558 | gspca_dev->frame[i].data = NULL; | 560 | gspca_dev->frame[i].data = NULL; |
559 | } | 561 | } |
560 | gspca_dev->nframes = 0; | 562 | gspca_dev->nframes = 0; |
563 | gspca_dev->frsz = 0; | ||
564 | gspca_dev->capt_file = NULL; | ||
565 | gspca_dev->memory = GSPCA_MEMORY_NO; | ||
561 | } | 566 | } |
562 | 567 | ||
563 | static void destroy_urbs(struct gspca_dev *gspca_dev) | 568 | static void destroy_urbs(struct gspca_dev *gspca_dev) |
@@ -1210,29 +1215,15 @@ static void gspca_release(struct video_device *vfd) | |||
1210 | static int dev_open(struct file *file) | 1215 | static int dev_open(struct file *file) |
1211 | { | 1216 | { |
1212 | struct gspca_dev *gspca_dev; | 1217 | struct gspca_dev *gspca_dev; |
1213 | int ret; | ||
1214 | 1218 | ||
1215 | PDEBUG(D_STREAM, "[%s] open", current->comm); | 1219 | PDEBUG(D_STREAM, "[%s] open", current->comm); |
1216 | gspca_dev = (struct gspca_dev *) video_devdata(file); | 1220 | gspca_dev = (struct gspca_dev *) video_devdata(file); |
1217 | if (mutex_lock_interruptible(&gspca_dev->queue_lock)) | 1221 | if (!gspca_dev->present) |
1218 | return -ERESTARTSYS; | 1222 | return -ENODEV; |
1219 | if (!gspca_dev->present) { | ||
1220 | ret = -ENODEV; | ||
1221 | goto out; | ||
1222 | } | ||
1223 | |||
1224 | if (gspca_dev->users > 4) { /* (arbitrary value) */ | ||
1225 | ret = -EBUSY; | ||
1226 | goto out; | ||
1227 | } | ||
1228 | 1223 | ||
1229 | /* protect the subdriver against rmmod */ | 1224 | /* protect the subdriver against rmmod */ |
1230 | if (!try_module_get(gspca_dev->module)) { | 1225 | if (!try_module_get(gspca_dev->module)) |
1231 | ret = -ENODEV; | 1226 | return -ENODEV; |
1232 | goto out; | ||
1233 | } | ||
1234 | |||
1235 | gspca_dev->users++; | ||
1236 | 1227 | ||
1237 | file->private_data = gspca_dev; | 1228 | file->private_data = gspca_dev; |
1238 | #ifdef GSPCA_DEBUG | 1229 | #ifdef GSPCA_DEBUG |
@@ -1244,14 +1235,7 @@ static int dev_open(struct file *file) | |||
1244 | gspca_dev->vdev.debug &= ~(V4L2_DEBUG_IOCTL | 1235 | gspca_dev->vdev.debug &= ~(V4L2_DEBUG_IOCTL |
1245 | | V4L2_DEBUG_IOCTL_ARG); | 1236 | | V4L2_DEBUG_IOCTL_ARG); |
1246 | #endif | 1237 | #endif |
1247 | ret = 0; | 1238 | return 0; |
1248 | out: | ||
1249 | mutex_unlock(&gspca_dev->queue_lock); | ||
1250 | if (ret != 0) | ||
1251 | PDEBUG(D_ERR|D_STREAM, "open failed err %d", ret); | ||
1252 | else | ||
1253 | PDEBUG(D_STREAM, "open done"); | ||
1254 | return ret; | ||
1255 | } | 1239 | } |
1256 | 1240 | ||
1257 | static int dev_close(struct file *file) | 1241 | static int dev_close(struct file *file) |
@@ -1261,7 +1245,6 @@ static int dev_close(struct file *file) | |||
1261 | PDEBUG(D_STREAM, "[%s] close", current->comm); | 1245 | PDEBUG(D_STREAM, "[%s] close", current->comm); |
1262 | if (mutex_lock_interruptible(&gspca_dev->queue_lock)) | 1246 | if (mutex_lock_interruptible(&gspca_dev->queue_lock)) |
1263 | return -ERESTARTSYS; | 1247 | return -ERESTARTSYS; |
1264 | gspca_dev->users--; | ||
1265 | 1248 | ||
1266 | /* if the file did the capture, free the streaming resources */ | 1249 | /* if the file did the capture, free the streaming resources */ |
1267 | if (gspca_dev->capt_file == file) { | 1250 | if (gspca_dev->capt_file == file) { |
@@ -1272,8 +1255,6 @@ static int dev_close(struct file *file) | |||
1272 | mutex_unlock(&gspca_dev->usb_lock); | 1255 | mutex_unlock(&gspca_dev->usb_lock); |
1273 | } | 1256 | } |
1274 | frame_free(gspca_dev); | 1257 | frame_free(gspca_dev); |
1275 | gspca_dev->capt_file = NULL; | ||
1276 | gspca_dev->memory = GSPCA_MEMORY_NO; | ||
1277 | } | 1258 | } |
1278 | file->private_data = NULL; | 1259 | file->private_data = NULL; |
1279 | module_put(gspca_dev->module); | 1260 | module_put(gspca_dev->module); |
@@ -1516,6 +1497,7 @@ static int vidioc_reqbufs(struct file *file, void *priv, | |||
1516 | return -ERESTARTSYS; | 1497 | return -ERESTARTSYS; |
1517 | 1498 | ||
1518 | if (gspca_dev->memory != GSPCA_MEMORY_NO | 1499 | if (gspca_dev->memory != GSPCA_MEMORY_NO |
1500 | && gspca_dev->memory != GSPCA_MEMORY_READ | ||
1519 | && gspca_dev->memory != rb->memory) { | 1501 | && gspca_dev->memory != rb->memory) { |
1520 | ret = -EBUSY; | 1502 | ret = -EBUSY; |
1521 | goto out; | 1503 | goto out; |
@@ -1544,19 +1526,18 @@ static int vidioc_reqbufs(struct file *file, void *priv, | |||
1544 | gspca_stream_off(gspca_dev); | 1526 | gspca_stream_off(gspca_dev); |
1545 | mutex_unlock(&gspca_dev->usb_lock); | 1527 | mutex_unlock(&gspca_dev->usb_lock); |
1546 | } | 1528 | } |
1529 | /* Don't restart the stream when switching from read to mmap mode */ | ||
1530 | if (gspca_dev->memory == GSPCA_MEMORY_READ) | ||
1531 | streaming = 0; | ||
1547 | 1532 | ||
1548 | /* free the previous allocated buffers, if any */ | 1533 | /* free the previous allocated buffers, if any */ |
1549 | if (gspca_dev->nframes != 0) { | 1534 | if (gspca_dev->nframes != 0) |
1550 | frame_free(gspca_dev); | 1535 | frame_free(gspca_dev); |
1551 | gspca_dev->capt_file = NULL; | ||
1552 | } | ||
1553 | if (rb->count == 0) /* unrequest */ | 1536 | if (rb->count == 0) /* unrequest */ |
1554 | goto out; | 1537 | goto out; |
1555 | gspca_dev->memory = rb->memory; | 1538 | ret = frame_alloc(gspca_dev, file, rb->memory, rb->count); |
1556 | ret = frame_alloc(gspca_dev, rb->count); | ||
1557 | if (ret == 0) { | 1539 | if (ret == 0) { |
1558 | rb->count = gspca_dev->nframes; | 1540 | rb->count = gspca_dev->nframes; |
1559 | gspca_dev->capt_file = file; | ||
1560 | if (streaming) | 1541 | if (streaming) |
1561 | ret = gspca_init_transfer(gspca_dev); | 1542 | ret = gspca_init_transfer(gspca_dev); |
1562 | } | 1543 | } |
@@ -1630,11 +1611,15 @@ static int vidioc_streamoff(struct file *file, void *priv, | |||
1630 | 1611 | ||
1631 | if (buf_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | 1612 | if (buf_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) |
1632 | return -EINVAL; | 1613 | return -EINVAL; |
1633 | if (!gspca_dev->streaming) | 1614 | |
1634 | return 0; | ||
1635 | if (mutex_lock_interruptible(&gspca_dev->queue_lock)) | 1615 | if (mutex_lock_interruptible(&gspca_dev->queue_lock)) |
1636 | return -ERESTARTSYS; | 1616 | return -ERESTARTSYS; |
1637 | 1617 | ||
1618 | if (!gspca_dev->streaming) { | ||
1619 | ret = 0; | ||
1620 | goto out; | ||
1621 | } | ||
1622 | |||
1638 | /* check the capture file */ | 1623 | /* check the capture file */ |
1639 | if (gspca_dev->capt_file != file) { | 1624 | if (gspca_dev->capt_file != file) { |
1640 | ret = -EBUSY; | 1625 | ret = -EBUSY; |
@@ -1649,6 +1634,8 @@ static int vidioc_streamoff(struct file *file, void *priv, | |||
1649 | gspca_dev->usb_err = 0; | 1634 | gspca_dev->usb_err = 0; |
1650 | gspca_stream_off(gspca_dev); | 1635 | gspca_stream_off(gspca_dev); |
1651 | mutex_unlock(&gspca_dev->usb_lock); | 1636 | mutex_unlock(&gspca_dev->usb_lock); |
1637 | /* In case another thread is waiting in dqbuf */ | ||
1638 | wake_up_interruptible(&gspca_dev->wq); | ||
1652 | 1639 | ||
1653 | /* empty the transfer queues */ | 1640 | /* empty the transfer queues */ |
1654 | atomic_set(&gspca_dev->fr_q, 0); | 1641 | atomic_set(&gspca_dev->fr_q, 0); |
@@ -1827,33 +1814,77 @@ out: | |||
1827 | return ret; | 1814 | return ret; |
1828 | } | 1815 | } |
1829 | 1816 | ||
1817 | static int frame_ready_nolock(struct gspca_dev *gspca_dev, struct file *file, | ||
1818 | enum v4l2_memory memory) | ||
1819 | { | ||
1820 | if (!gspca_dev->present) | ||
1821 | return -ENODEV; | ||
1822 | if (gspca_dev->capt_file != file || gspca_dev->memory != memory || | ||
1823 | !gspca_dev->streaming) | ||
1824 | return -EINVAL; | ||
1825 | |||
1826 | /* check if a frame is ready */ | ||
1827 | return gspca_dev->fr_o != atomic_read(&gspca_dev->fr_i); | ||
1828 | } | ||
1829 | |||
1830 | static int frame_ready(struct gspca_dev *gspca_dev, struct file *file, | ||
1831 | enum v4l2_memory memory) | ||
1832 | { | ||
1833 | int ret; | ||
1834 | |||
1835 | if (mutex_lock_interruptible(&gspca_dev->queue_lock)) | ||
1836 | return -ERESTARTSYS; | ||
1837 | ret = frame_ready_nolock(gspca_dev, file, memory); | ||
1838 | mutex_unlock(&gspca_dev->queue_lock); | ||
1839 | return ret; | ||
1840 | } | ||
1841 | |||
1830 | /* | 1842 | /* |
1831 | * wait for a video frame | 1843 | * dequeue a video buffer |
1832 | * | 1844 | * |
1833 | * If a frame is ready, its index is returned. | 1845 | * If nonblock_ing is false, block until a buffer is available. |
1834 | */ | 1846 | */ |
1835 | static int frame_wait(struct gspca_dev *gspca_dev, | 1847 | static int vidioc_dqbuf(struct file *file, void *priv, |
1836 | int nonblock_ing) | 1848 | struct v4l2_buffer *v4l2_buf) |
1837 | { | 1849 | { |
1838 | int i, ret; | 1850 | struct gspca_dev *gspca_dev = priv; |
1851 | struct gspca_frame *frame; | ||
1852 | int i, j, ret; | ||
1839 | 1853 | ||
1840 | /* check if a frame is ready */ | 1854 | PDEBUG(D_FRAM, "dqbuf"); |
1841 | i = gspca_dev->fr_o; | 1855 | |
1842 | if (i == atomic_read(&gspca_dev->fr_i)) { | 1856 | if (mutex_lock_interruptible(&gspca_dev->queue_lock)) |
1843 | if (nonblock_ing) | 1857 | return -ERESTARTSYS; |
1858 | |||
1859 | for (;;) { | ||
1860 | ret = frame_ready_nolock(gspca_dev, file, v4l2_buf->memory); | ||
1861 | if (ret < 0) | ||
1862 | goto out; | ||
1863 | if (ret > 0) | ||
1864 | break; | ||
1865 | |||
1866 | mutex_unlock(&gspca_dev->queue_lock); | ||
1867 | |||
1868 | if (file->f_flags & O_NONBLOCK) | ||
1844 | return -EAGAIN; | 1869 | return -EAGAIN; |
1845 | 1870 | ||
1846 | /* wait till a frame is ready */ | 1871 | /* wait till a frame is ready */ |
1847 | ret = wait_event_interruptible_timeout(gspca_dev->wq, | 1872 | ret = wait_event_interruptible_timeout(gspca_dev->wq, |
1848 | i != atomic_read(&gspca_dev->fr_i) || | 1873 | frame_ready(gspca_dev, file, v4l2_buf->memory), |
1849 | !gspca_dev->streaming || !gspca_dev->present, | ||
1850 | msecs_to_jiffies(3000)); | 1874 | msecs_to_jiffies(3000)); |
1851 | if (ret < 0) | 1875 | if (ret < 0) |
1852 | return ret; | 1876 | return ret; |
1853 | if (ret == 0 || !gspca_dev->streaming || !gspca_dev->present) | 1877 | if (ret == 0) |
1854 | return -EIO; | 1878 | return -EIO; |
1879 | |||
1880 | if (mutex_lock_interruptible(&gspca_dev->queue_lock)) | ||
1881 | return -ERESTARTSYS; | ||
1855 | } | 1882 | } |
1856 | 1883 | ||
1884 | i = gspca_dev->fr_o; | ||
1885 | j = gspca_dev->fr_queue[i]; | ||
1886 | frame = &gspca_dev->frame[j]; | ||
1887 | |||
1857 | gspca_dev->fr_o = (i + 1) % GSPCA_MAX_FRAMES; | 1888 | gspca_dev->fr_o = (i + 1) % GSPCA_MAX_FRAMES; |
1858 | 1889 | ||
1859 | if (gspca_dev->sd_desc->dq_callback) { | 1890 | if (gspca_dev->sd_desc->dq_callback) { |
@@ -1863,46 +1894,12 @@ static int frame_wait(struct gspca_dev *gspca_dev, | |||
1863 | gspca_dev->sd_desc->dq_callback(gspca_dev); | 1894 | gspca_dev->sd_desc->dq_callback(gspca_dev); |
1864 | mutex_unlock(&gspca_dev->usb_lock); | 1895 | mutex_unlock(&gspca_dev->usb_lock); |
1865 | } | 1896 | } |
1866 | return gspca_dev->fr_queue[i]; | ||
1867 | } | ||
1868 | |||
1869 | /* | ||
1870 | * dequeue a video buffer | ||
1871 | * | ||
1872 | * If nonblock_ing is false, block until a buffer is available. | ||
1873 | */ | ||
1874 | static int vidioc_dqbuf(struct file *file, void *priv, | ||
1875 | struct v4l2_buffer *v4l2_buf) | ||
1876 | { | ||
1877 | struct gspca_dev *gspca_dev = priv; | ||
1878 | struct gspca_frame *frame; | ||
1879 | int i, ret; | ||
1880 | |||
1881 | PDEBUG(D_FRAM, "dqbuf"); | ||
1882 | if (v4l2_buf->memory != gspca_dev->memory) | ||
1883 | return -EINVAL; | ||
1884 | |||
1885 | if (!gspca_dev->present) | ||
1886 | return -ENODEV; | ||
1887 | |||
1888 | /* if not streaming, be sure the application will not loop forever */ | ||
1889 | if (!(file->f_flags & O_NONBLOCK) | ||
1890 | && !gspca_dev->streaming && gspca_dev->users == 1) | ||
1891 | return -EINVAL; | ||
1892 | 1897 | ||
1893 | /* only the capturing file may dequeue */ | 1898 | frame->v4l2_buf.flags &= ~V4L2_BUF_FLAG_DONE; |
1894 | if (gspca_dev->capt_file != file) | 1899 | memcpy(v4l2_buf, &frame->v4l2_buf, sizeof *v4l2_buf); |
1895 | return -EINVAL; | 1900 | PDEBUG(D_FRAM, "dqbuf %d", j); |
1896 | 1901 | ret = 0; | |
1897 | /* only one dequeue / read at a time */ | ||
1898 | if (mutex_lock_interruptible(&gspca_dev->read_lock)) | ||
1899 | return -ERESTARTSYS; | ||
1900 | 1902 | ||
1901 | ret = frame_wait(gspca_dev, file->f_flags & O_NONBLOCK); | ||
1902 | if (ret < 0) | ||
1903 | goto out; | ||
1904 | i = ret; /* frame index */ | ||
1905 | frame = &gspca_dev->frame[i]; | ||
1906 | if (gspca_dev->memory == V4L2_MEMORY_USERPTR) { | 1903 | if (gspca_dev->memory == V4L2_MEMORY_USERPTR) { |
1907 | if (copy_to_user((__u8 __user *) frame->v4l2_buf.m.userptr, | 1904 | if (copy_to_user((__u8 __user *) frame->v4l2_buf.m.userptr, |
1908 | frame->data, | 1905 | frame->data, |
@@ -1910,15 +1907,10 @@ static int vidioc_dqbuf(struct file *file, void *priv, | |||
1910 | PDEBUG(D_ERR|D_STREAM, | 1907 | PDEBUG(D_ERR|D_STREAM, |
1911 | "dqbuf cp to user failed"); | 1908 | "dqbuf cp to user failed"); |
1912 | ret = -EFAULT; | 1909 | ret = -EFAULT; |
1913 | goto out; | ||
1914 | } | 1910 | } |
1915 | } | 1911 | } |
1916 | frame->v4l2_buf.flags &= ~V4L2_BUF_FLAG_DONE; | ||
1917 | memcpy(v4l2_buf, &frame->v4l2_buf, sizeof *v4l2_buf); | ||
1918 | PDEBUG(D_FRAM, "dqbuf %d", i); | ||
1919 | ret = 0; | ||
1920 | out: | 1912 | out: |
1921 | mutex_unlock(&gspca_dev->read_lock); | 1913 | mutex_unlock(&gspca_dev->queue_lock); |
1922 | return ret; | 1914 | return ret; |
1923 | } | 1915 | } |
1924 | 1916 | ||
@@ -2033,9 +2025,7 @@ static unsigned int dev_poll(struct file *file, poll_table *wait) | |||
2033 | poll_wait(file, &gspca_dev->wq, wait); | 2025 | poll_wait(file, &gspca_dev->wq, wait); |
2034 | 2026 | ||
2035 | /* if reqbufs is not done, the user would use read() */ | 2027 | /* if reqbufs is not done, the user would use read() */ |
2036 | if (gspca_dev->nframes == 0) { | 2028 | if (gspca_dev->memory == GSPCA_MEMORY_NO) { |
2037 | if (gspca_dev->memory != GSPCA_MEMORY_NO) | ||
2038 | return POLLERR; /* not the 1st time */ | ||
2039 | ret = read_alloc(gspca_dev, file); | 2029 | ret = read_alloc(gspca_dev, file); |
2040 | if (ret != 0) | 2030 | if (ret != 0) |
2041 | return POLLERR; | 2031 | return POLLERR; |
@@ -2067,18 +2057,10 @@ static ssize_t dev_read(struct file *file, char __user *data, | |||
2067 | PDEBUG(D_FRAM, "read (%zd)", count); | 2057 | PDEBUG(D_FRAM, "read (%zd)", count); |
2068 | if (!gspca_dev->present) | 2058 | if (!gspca_dev->present) |
2069 | return -ENODEV; | 2059 | return -ENODEV; |
2070 | switch (gspca_dev->memory) { | 2060 | if (gspca_dev->memory == GSPCA_MEMORY_NO) { /* first time ? */ |
2071 | case GSPCA_MEMORY_NO: /* first time */ | ||
2072 | ret = read_alloc(gspca_dev, file); | 2061 | ret = read_alloc(gspca_dev, file); |
2073 | if (ret != 0) | 2062 | if (ret != 0) |
2074 | return ret; | 2063 | return ret; |
2075 | break; | ||
2076 | case GSPCA_MEMORY_READ: | ||
2077 | if (gspca_dev->capt_file == file) | ||
2078 | break; | ||
2079 | /* fall thru */ | ||
2080 | default: | ||
2081 | return -EINVAL; | ||
2082 | } | 2064 | } |
2083 | 2065 | ||
2084 | /* get a frame */ | 2066 | /* get a frame */ |
@@ -2266,7 +2248,6 @@ int gspca_dev_probe2(struct usb_interface *intf, | |||
2266 | goto out; | 2248 | goto out; |
2267 | 2249 | ||
2268 | mutex_init(&gspca_dev->usb_lock); | 2250 | mutex_init(&gspca_dev->usb_lock); |
2269 | mutex_init(&gspca_dev->read_lock); | ||
2270 | mutex_init(&gspca_dev->queue_lock); | 2251 | mutex_init(&gspca_dev->queue_lock); |
2271 | init_waitqueue_head(&gspca_dev->wq); | 2252 | init_waitqueue_head(&gspca_dev->wq); |
2272 | 2253 | ||
@@ -2341,12 +2322,11 @@ void gspca_disconnect(struct usb_interface *intf) | |||
2341 | PDEBUG(D_PROBE, "%s disconnect", | 2322 | PDEBUG(D_PROBE, "%s disconnect", |
2342 | video_device_node_name(&gspca_dev->vdev)); | 2323 | video_device_node_name(&gspca_dev->vdev)); |
2343 | mutex_lock(&gspca_dev->usb_lock); | 2324 | mutex_lock(&gspca_dev->usb_lock); |
2325 | |||
2344 | gspca_dev->present = 0; | 2326 | gspca_dev->present = 0; |
2327 | wake_up_interruptible(&gspca_dev->wq); | ||
2345 | 2328 | ||
2346 | if (gspca_dev->streaming) { | 2329 | destroy_urbs(gspca_dev); |
2347 | destroy_urbs(gspca_dev); | ||
2348 | wake_up_interruptible(&gspca_dev->wq); | ||
2349 | } | ||
2350 | 2330 | ||
2351 | #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) | 2331 | #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) |
2352 | gspca_input_destroy_urb(gspca_dev); | 2332 | gspca_input_destroy_urb(gspca_dev); |