diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-05-20 12:37:45 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-05-20 12:37:45 -0400 |
commit | fb091be08d1acf184e8801dfdcace6e0cb19b1fe (patch) | |
tree | cbd0c4200fd8628d592167589ca790e36fc4ae26 /drivers/media/video/gspca/gspca.c | |
parent | bd7fc2f2d807fdb254f7efc542f8eec3f23e289e (diff) | |
parent | e8d0416796d43a950ec7b65629e53419b2e22453 (diff) |
Merge branch 'v4l_for_2.6.35' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6
* 'v4l_for_2.6.35' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6: (534 commits)
V4L/DVB (13554a): v4l: Use the video_drvdata function in drivers
V4L/DVB: vivi and mem2mem_testdev need slab.h to build
V4L/DVB: tm6000: bugfix image position
V4L/DVB: IR/imon: remove dead IMON_KEY_RELEASE_OFFSET
V4L/DVB: tm6000: README - add vbi
V4L/DVB: Fix unlock logic at medusa_video_init
V4L/DVB: fix dvb frontend lockup
V4L/DVB: s2255drv: remove dead code
V4L/DVB: s2255drv: return if vdev not found
V4L/DVB: ov511: cleanup: remove unneeded null check
V4L/DVB: media/mem2mem: dereferencing free memory
V4L/DVB: media/IR: Add missing include file to rc-map.c
V4L/DVB: dvb/stv6110x: cleanup error handling
V4L/DVB: ngene: Add lgdt3303 and mt2131 deps to Kconfig
V4L/DVB: ngene: start separating out DVB functions into separate file
V4L/DVB: ngene: split out card specific code into a separate file
V4L/DVB: ngene: split out i2c code into a separate file
V4L/DVB: ngene: add initial support for digital side of Avermedia m780
V4L/DVB: ngene: properly support boards where channel 0 isn't a TS input
V4L-DVB: ngene: make sure that tuner headers are included
...
Diffstat (limited to 'drivers/media/video/gspca/gspca.c')
-rw-r--r-- | drivers/media/video/gspca/gspca.c | 124 |
1 files changed, 73 insertions, 51 deletions
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index 222af479150b..efe615938783 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Main USB camera driver | 2 | * Main USB camera driver |
3 | * | 3 | * |
4 | * Copyright (C) 2008-2009 Jean-Francois Moine (http://moinejf.free.fr) | 4 | * Copyright (C) 2008-2010 Jean-François Moine <http://moinejf.free.fr> |
5 | * | 5 | * |
6 | * Camera button input handling by Márton Németh | 6 | * Camera button input handling by Márton Németh |
7 | * Copyright (C) 2009-2010 Márton Németh <nm127@freemail.hu> | 7 | * Copyright (C) 2009-2010 Márton Németh <nm127@freemail.hu> |
@@ -35,12 +35,12 @@ | |||
35 | #include <linux/io.h> | 35 | #include <linux/io.h> |
36 | #include <asm/page.h> | 36 | #include <asm/page.h> |
37 | #include <linux/uaccess.h> | 37 | #include <linux/uaccess.h> |
38 | #include <linux/jiffies.h> | 38 | #include <linux/ktime.h> |
39 | #include <media/v4l2-ioctl.h> | 39 | #include <media/v4l2-ioctl.h> |
40 | 40 | ||
41 | #include "gspca.h" | 41 | #include "gspca.h" |
42 | 42 | ||
43 | #ifdef CONFIG_INPUT | 43 | #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) |
44 | #include <linux/input.h> | 44 | #include <linux/input.h> |
45 | #include <linux/usb/input.h> | 45 | #include <linux/usb/input.h> |
46 | #endif | 46 | #endif |
@@ -51,7 +51,7 @@ | |||
51 | #error "DEF_NURBS too big" | 51 | #error "DEF_NURBS too big" |
52 | #endif | 52 | #endif |
53 | 53 | ||
54 | MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>"); | 54 | 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 | ||
@@ -115,7 +115,7 @@ static const struct vm_operations_struct gspca_vm_ops = { | |||
115 | /* | 115 | /* |
116 | * Input and interrupt endpoint handling functions | 116 | * Input and interrupt endpoint handling functions |
117 | */ | 117 | */ |
118 | #ifdef CONFIG_INPUT | 118 | #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) |
119 | static void int_irq(struct urb *urb) | 119 | static void int_irq(struct urb *urb) |
120 | { | 120 | { |
121 | struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context; | 121 | struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context; |
@@ -199,7 +199,7 @@ static int alloc_and_submit_int_urb(struct gspca_dev *gspca_dev, | |||
199 | void *buffer = NULL; | 199 | void *buffer = NULL; |
200 | int ret = -EINVAL; | 200 | int ret = -EINVAL; |
201 | 201 | ||
202 | buffer_len = ep->wMaxPacketSize; | 202 | buffer_len = le16_to_cpu(ep->wMaxPacketSize); |
203 | interval = ep->bInterval; | 203 | interval = ep->bInterval; |
204 | PDEBUG(D_PROBE, "found int in endpoint: 0x%x, " | 204 | PDEBUG(D_PROBE, "found int in endpoint: 0x%x, " |
205 | "buffer_len=%u, interval=%u", | 205 | "buffer_len=%u, interval=%u", |
@@ -213,7 +213,7 @@ static int alloc_and_submit_int_urb(struct gspca_dev *gspca_dev, | |||
213 | goto error; | 213 | goto error; |
214 | } | 214 | } |
215 | 215 | ||
216 | buffer = usb_buffer_alloc(dev, ep->wMaxPacketSize, | 216 | buffer = usb_buffer_alloc(dev, buffer_len, |
217 | GFP_KERNEL, &urb->transfer_dma); | 217 | GFP_KERNEL, &urb->transfer_dma); |
218 | if (!buffer) { | 218 | if (!buffer) { |
219 | ret = -ENOMEM; | 219 | ret = -ENOMEM; |
@@ -280,9 +280,18 @@ static void gspca_input_destroy_urb(struct gspca_dev *gspca_dev) | |||
280 | } | 280 | } |
281 | } | 281 | } |
282 | #else | 282 | #else |
283 | #define gspca_input_connect(gspca_dev) 0 | 283 | static inline void gspca_input_destroy_urb(struct gspca_dev *gspca_dev) |
284 | #define gspca_input_create_urb(gspca_dev) | 284 | { |
285 | #define gspca_input_destroy_urb(gspca_dev) | 285 | } |
286 | |||
287 | static inline void gspca_input_create_urb(struct gspca_dev *gspca_dev) | ||
288 | { | ||
289 | } | ||
290 | |||
291 | static inline int gspca_input_connect(struct gspca_dev *dev) | ||
292 | { | ||
293 | return 0; | ||
294 | } | ||
286 | #endif | 295 | #endif |
287 | 296 | ||
288 | /* get the current input frame buffer */ | 297 | /* get the current input frame buffer */ |
@@ -442,8 +451,7 @@ void gspca_frame_add(struct gspca_dev *gspca_dev, | |||
442 | * is not queued, discard the whole frame */ | 451 | * is not queued, discard the whole frame */ |
443 | if (packet_type == FIRST_PACKET) { | 452 | if (packet_type == FIRST_PACKET) { |
444 | frame->data_end = frame->data; | 453 | frame->data_end = frame->data; |
445 | jiffies_to_timeval(get_jiffies_64(), | 454 | frame->v4l2_buf.timestamp = ktime_to_timeval(ktime_get()); |
446 | &frame->v4l2_buf.timestamp); | ||
447 | frame->v4l2_buf.sequence = ++gspca_dev->sequence; | 455 | frame->v4l2_buf.sequence = ++gspca_dev->sequence; |
448 | } else if (gspca_dev->last_packet_type == DISCARD_PACKET) { | 456 | } else if (gspca_dev->last_packet_type == DISCARD_PACKET) { |
449 | if (packet_type == LAST_PACKET) | 457 | if (packet_type == LAST_PACKET) |
@@ -605,6 +613,37 @@ static void destroy_urbs(struct gspca_dev *gspca_dev) | |||
605 | } | 613 | } |
606 | } | 614 | } |
607 | 615 | ||
616 | static int gspca_set_alt0(struct gspca_dev *gspca_dev) | ||
617 | { | ||
618 | int ret; | ||
619 | |||
620 | if (gspca_dev->alt == 0) | ||
621 | return 0; | ||
622 | ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, 0); | ||
623 | if (ret < 0) | ||
624 | PDEBUG(D_ERR|D_STREAM, "set alt 0 err %d", ret); | ||
625 | return ret; | ||
626 | } | ||
627 | |||
628 | /* Note: both the queue and the usb locks should be held when calling this */ | ||
629 | static void gspca_stream_off(struct gspca_dev *gspca_dev) | ||
630 | { | ||
631 | gspca_dev->streaming = 0; | ||
632 | if (gspca_dev->present) { | ||
633 | if (gspca_dev->sd_desc->stopN) | ||
634 | gspca_dev->sd_desc->stopN(gspca_dev); | ||
635 | destroy_urbs(gspca_dev); | ||
636 | gspca_input_destroy_urb(gspca_dev); | ||
637 | gspca_set_alt0(gspca_dev); | ||
638 | gspca_input_create_urb(gspca_dev); | ||
639 | } | ||
640 | |||
641 | /* always call stop0 to free the subdriver's resources */ | ||
642 | if (gspca_dev->sd_desc->stop0) | ||
643 | gspca_dev->sd_desc->stop0(gspca_dev); | ||
644 | PDEBUG(D_STREAM, "stream off OK"); | ||
645 | } | ||
646 | |||
608 | /* | 647 | /* |
609 | * look for an input transfer endpoint in an alternate setting | 648 | * look for an input transfer endpoint in an alternate setting |
610 | */ | 649 | */ |
@@ -830,8 +869,7 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev) | |||
830 | } | 869 | } |
831 | if (ret >= 0) | 870 | if (ret >= 0) |
832 | break; | 871 | break; |
833 | gspca_dev->streaming = 0; | 872 | gspca_stream_off(gspca_dev); |
834 | destroy_urbs(gspca_dev); | ||
835 | if (ret != -ENOSPC) { | 873 | if (ret != -ENOSPC) { |
836 | PDEBUG(D_ERR|D_STREAM, | 874 | PDEBUG(D_ERR|D_STREAM, |
837 | "usb_submit_urb alt %d err %d", | 875 | "usb_submit_urb alt %d err %d", |
@@ -861,37 +899,6 @@ out: | |||
861 | return ret; | 899 | return ret; |
862 | } | 900 | } |
863 | 901 | ||
864 | static int gspca_set_alt0(struct gspca_dev *gspca_dev) | ||
865 | { | ||
866 | int ret; | ||
867 | |||
868 | if (gspca_dev->alt == 0) | ||
869 | return 0; | ||
870 | ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, 0); | ||
871 | if (ret < 0) | ||
872 | PDEBUG(D_ERR|D_STREAM, "set alt 0 err %d", ret); | ||
873 | return ret; | ||
874 | } | ||
875 | |||
876 | /* Note: both the queue and the usb locks should be held when calling this */ | ||
877 | static void gspca_stream_off(struct gspca_dev *gspca_dev) | ||
878 | { | ||
879 | gspca_dev->streaming = 0; | ||
880 | if (gspca_dev->present) { | ||
881 | if (gspca_dev->sd_desc->stopN) | ||
882 | gspca_dev->sd_desc->stopN(gspca_dev); | ||
883 | destroy_urbs(gspca_dev); | ||
884 | gspca_input_destroy_urb(gspca_dev); | ||
885 | gspca_set_alt0(gspca_dev); | ||
886 | gspca_input_create_urb(gspca_dev); | ||
887 | } | ||
888 | |||
889 | /* always call stop0 to free the subdriver's resources */ | ||
890 | if (gspca_dev->sd_desc->stop0) | ||
891 | gspca_dev->sd_desc->stop0(gspca_dev); | ||
892 | PDEBUG(D_STREAM, "stream off OK"); | ||
893 | } | ||
894 | |||
895 | static void gspca_set_default_mode(struct gspca_dev *gspca_dev) | 902 | static void gspca_set_default_mode(struct gspca_dev *gspca_dev) |
896 | { | 903 | { |
897 | int i; | 904 | int i; |
@@ -1495,7 +1502,7 @@ static int vidioc_reqbufs(struct file *file, void *priv, | |||
1495 | struct v4l2_requestbuffers *rb) | 1502 | struct v4l2_requestbuffers *rb) |
1496 | { | 1503 | { |
1497 | struct gspca_dev *gspca_dev = priv; | 1504 | struct gspca_dev *gspca_dev = priv; |
1498 | int i, ret = 0; | 1505 | int i, ret = 0, streaming; |
1499 | 1506 | ||
1500 | switch (rb->memory) { | 1507 | switch (rb->memory) { |
1501 | case GSPCA_MEMORY_READ: /* (internal call) */ | 1508 | case GSPCA_MEMORY_READ: /* (internal call) */ |
@@ -1530,7 +1537,8 @@ static int vidioc_reqbufs(struct file *file, void *priv, | |||
1530 | } | 1537 | } |
1531 | 1538 | ||
1532 | /* stop streaming */ | 1539 | /* stop streaming */ |
1533 | if (gspca_dev->streaming) { | 1540 | streaming = gspca_dev->streaming; |
1541 | if (streaming) { | ||
1534 | mutex_lock(&gspca_dev->usb_lock); | 1542 | mutex_lock(&gspca_dev->usb_lock); |
1535 | gspca_dev->usb_err = 0; | 1543 | gspca_dev->usb_err = 0; |
1536 | gspca_stream_off(gspca_dev); | 1544 | gspca_stream_off(gspca_dev); |
@@ -1549,6 +1557,8 @@ static int vidioc_reqbufs(struct file *file, void *priv, | |||
1549 | if (ret == 0) { | 1557 | if (ret == 0) { |
1550 | rb->count = gspca_dev->nframes; | 1558 | rb->count = gspca_dev->nframes; |
1551 | gspca_dev->capt_file = file; | 1559 | gspca_dev->capt_file = file; |
1560 | if (streaming) | ||
1561 | ret = gspca_init_transfer(gspca_dev); | ||
1552 | } | 1562 | } |
1553 | out: | 1563 | out: |
1554 | mutex_unlock(&gspca_dev->queue_lock); | 1564 | mutex_unlock(&gspca_dev->queue_lock); |
@@ -1582,6 +1592,12 @@ static int vidioc_streamon(struct file *file, void *priv, | |||
1582 | if (mutex_lock_interruptible(&gspca_dev->queue_lock)) | 1592 | if (mutex_lock_interruptible(&gspca_dev->queue_lock)) |
1583 | return -ERESTARTSYS; | 1593 | return -ERESTARTSYS; |
1584 | 1594 | ||
1595 | /* check the capture file */ | ||
1596 | if (gspca_dev->capt_file != file) { | ||
1597 | ret = -EBUSY; | ||
1598 | goto out; | ||
1599 | } | ||
1600 | |||
1585 | if (gspca_dev->nframes == 0 | 1601 | if (gspca_dev->nframes == 0 |
1586 | || !(gspca_dev->frame[0].v4l2_buf.flags & V4L2_BUF_FLAG_QUEUED)) { | 1602 | || !(gspca_dev->frame[0].v4l2_buf.flags & V4L2_BUF_FLAG_QUEUED)) { |
1587 | ret = -EINVAL; | 1603 | ret = -EINVAL; |
@@ -1619,6 +1635,12 @@ static int vidioc_streamoff(struct file *file, void *priv, | |||
1619 | if (mutex_lock_interruptible(&gspca_dev->queue_lock)) | 1635 | if (mutex_lock_interruptible(&gspca_dev->queue_lock)) |
1620 | return -ERESTARTSYS; | 1636 | return -ERESTARTSYS; |
1621 | 1637 | ||
1638 | /* check the capture file */ | ||
1639 | if (gspca_dev->capt_file != file) { | ||
1640 | ret = -EBUSY; | ||
1641 | goto out; | ||
1642 | } | ||
1643 | |||
1622 | /* stop streaming */ | 1644 | /* stop streaming */ |
1623 | if (mutex_lock_interruptible(&gspca_dev->usb_lock)) { | 1645 | if (mutex_lock_interruptible(&gspca_dev->usb_lock)) { |
1624 | ret = -ERESTARTSYS; | 1646 | ret = -ERESTARTSYS; |
@@ -2124,7 +2146,7 @@ static ssize_t dev_read(struct file *file, char __user *data, | |||
2124 | } | 2146 | } |
2125 | 2147 | ||
2126 | /* get a frame */ | 2148 | /* get a frame */ |
2127 | jiffies_to_timeval(get_jiffies_64(), ×tamp); | 2149 | timestamp = ktime_to_timeval(ktime_get()); |
2128 | timestamp.tv_sec--; | 2150 | timestamp.tv_sec--; |
2129 | n = 2; | 2151 | n = 2; |
2130 | for (;;) { | 2152 | for (;;) { |
@@ -2315,7 +2337,7 @@ int gspca_dev_probe(struct usb_interface *intf, | |||
2315 | 2337 | ||
2316 | return 0; | 2338 | return 0; |
2317 | out: | 2339 | out: |
2318 | #ifdef CONFIG_INPUT | 2340 | #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) |
2319 | if (gspca_dev->input_dev) | 2341 | if (gspca_dev->input_dev) |
2320 | input_unregister_device(gspca_dev->input_dev); | 2342 | input_unregister_device(gspca_dev->input_dev); |
2321 | #endif | 2343 | #endif |
@@ -2334,7 +2356,7 @@ EXPORT_SYMBOL(gspca_dev_probe); | |||
2334 | void gspca_disconnect(struct usb_interface *intf) | 2356 | void gspca_disconnect(struct usb_interface *intf) |
2335 | { | 2357 | { |
2336 | struct gspca_dev *gspca_dev = usb_get_intfdata(intf); | 2358 | struct gspca_dev *gspca_dev = usb_get_intfdata(intf); |
2337 | #ifdef CONFIG_INPUT | 2359 | #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) |
2338 | struct input_dev *input_dev; | 2360 | struct input_dev *input_dev; |
2339 | #endif | 2361 | #endif |
2340 | 2362 | ||
@@ -2348,7 +2370,7 @@ void gspca_disconnect(struct usb_interface *intf) | |||
2348 | wake_up_interruptible(&gspca_dev->wq); | 2370 | wake_up_interruptible(&gspca_dev->wq); |
2349 | } | 2371 | } |
2350 | 2372 | ||
2351 | #ifdef CONFIG_INPUT | 2373 | #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) |
2352 | gspca_input_destroy_urb(gspca_dev); | 2374 | gspca_input_destroy_urb(gspca_dev); |
2353 | input_dev = gspca_dev->input_dev; | 2375 | input_dev = gspca_dev->input_dev; |
2354 | if (input_dev) { | 2376 | if (input_dev) { |