From 101b25b55ec48354bc40b9102b4f7922c9ad9eae Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Fri, 5 Nov 2010 00:07:39 -0300 Subject: [media] drivers/media: Use vzalloc Signed-off-by: Joe Perches Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/pwc/pwc-if.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/media/video/pwc') diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c index f3dc89da4c4e..b821065e3870 100644 --- a/drivers/media/video/pwc/pwc-if.c +++ b/drivers/media/video/pwc/pwc-if.c @@ -287,14 +287,13 @@ static int pwc_allocate_buffers(struct pwc_device *pdev) /* create frame buffers, and make circular ring */ for (i = 0; i < default_fbufs; i++) { if (pdev->fbuf[i].data == NULL) { - kbuf = vmalloc(PWC_FRAME_SIZE); /* need vmalloc since frame buffer > 128K */ + kbuf = vzalloc(PWC_FRAME_SIZE); /* need vmalloc since frame buffer > 128K */ if (kbuf == NULL) { PWC_ERROR("Failed to allocate frame buffer %d.\n", i); return -ENOMEM; } PWC_DEBUG_MEMORY("Allocated frame buffer %d at %p.\n", i, kbuf); pdev->fbuf[i].data = kbuf; - memset(kbuf, 0, PWC_FRAME_SIZE); } } -- cgit v1.2.2 From 3751e288bcf3d77652ef979edc0b3ea8b21d8b97 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 16 Nov 2010 11:39:25 -0300 Subject: [media] pwc: do not start isoc stream on /dev/video open pwc was starting streaming on /dev/video# open rather then on STREAM_ON. Now that the v4l1 compat code is removed from the pwc driver there is no reason left to do this. So this patch changes the pwc driver to delay starting the isoc stream (and thus using valuable usb bandwidth) until the application does a STREAM_ON Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/pwc/pwc-ctrl.c | 7 ++++- drivers/media/video/pwc/pwc-if.c | 54 ++++++++++---------------------------- drivers/media/video/pwc/pwc-v4l.c | 13 ++++----- drivers/media/video/pwc/pwc.h | 1 - 4 files changed, 27 insertions(+), 48 deletions(-) (limited to 'drivers/media/video/pwc') diff --git a/drivers/media/video/pwc/pwc-ctrl.c b/drivers/media/video/pwc/pwc-ctrl.c index 6b8fbddc0747..1593f8deb810 100644 --- a/drivers/media/video/pwc/pwc-ctrl.c +++ b/drivers/media/video/pwc/pwc-ctrl.c @@ -1386,11 +1386,16 @@ long pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg) { ARG_DEF(int, qual) + if (pdev->iso_init) { + ret = -EBUSY; + break; + } + ARG_IN(qual) if (ARGR(qual) < 0 || ARGR(qual) > 3) ret = -EINVAL; else - ret = pwc_try_video_mode(pdev, pdev->view.x, pdev->view.y, pdev->vframes, ARGR(qual), pdev->vsnapshot); + ret = pwc_set_video_mode(pdev, pdev->view.x, pdev->view.y, pdev->vframes, ARGR(qual), pdev->vsnapshot); if (ret >= 0) pdev->vcompression = ARGR(qual); break; diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c index b821065e3870..6f8b682b9245 100644 --- a/drivers/media/video/pwc/pwc-if.c +++ b/drivers/media/video/pwc/pwc-if.c @@ -966,36 +966,6 @@ void pwc_isoc_cleanup(struct pwc_device *pdev) PWC_DEBUG_OPEN("<< pwc_isoc_cleanup()\n"); } -int pwc_try_video_mode(struct pwc_device *pdev, int width, int height, int new_fps, int new_compression, int new_snapshot) -{ - int ret, start; - - /* Stop isoc stuff */ - pwc_isoc_cleanup(pdev); - /* Reset parameters */ - pwc_reset_buffers(pdev); - /* Try to set video mode... */ - start = ret = pwc_set_video_mode(pdev, width, height, new_fps, new_compression, new_snapshot); - if (ret) { - PWC_DEBUG_FLOW("pwc_set_video_mode attempt 1 failed.\n"); - /* That failed... restore old mode (we know that worked) */ - start = pwc_set_video_mode(pdev, pdev->view.x, pdev->view.y, pdev->vframes, pdev->vcompression, pdev->vsnapshot); - if (start) { - PWC_DEBUG_FLOW("pwc_set_video_mode attempt 2 failed.\n"); - } - } - if (start == 0) - { - if (pwc_isoc_init(pdev) < 0) - { - PWC_WARNING("Failed to restart ISOC transfers in pwc_try_video_mode.\n"); - ret = -EAGAIN; /* let's try again, who knows if it works a second time */ - } - } - pdev->drop_frames++; /* try to avoid garbage during switch */ - return ret; /* Return original error code */ -} - /********* * sysfs *********/ @@ -1175,7 +1145,7 @@ static int pwc_video_open(struct file *file) /* Set some defaults */ pdev->vsnapshot = 0; - /* Start iso pipe for video; first try the last used video size + /* Set video size, first try the last used video size (or the default one); if that fails try QCIF/10 or QSIF/10; it that fails too, give up. */ @@ -1202,15 +1172,6 @@ static int pwc_video_open(struct file *file) return i; } - i = pwc_isoc_init(pdev); - if (i) { - PWC_DEBUG_OPEN("Failed to init ISOC stuff = %d.\n", i); - pwc_isoc_cleanup(pdev); - pwc_free_buffers(pdev); - mutex_unlock(&pdev->modlock); - return i; - } - /* Initialize the webcam to sane value */ pwc_set_brightness(pdev, 0x7fff); pwc_set_agc(pdev, 1, 0); @@ -1325,6 +1286,11 @@ static ssize_t pwc_video_read(struct file *file, char __user *buf, goto err_out; } + /* Start the stream (if not already started) */ + rv = pwc_isoc_init(pdev); + if (rv) + goto err_out; + /* In case we're doing partial reads, we don't have to wait for a frame */ if (pdev->image_read_pos == 0) { /* Do wait queueing according to the (doc)book */ @@ -1394,6 +1360,7 @@ static unsigned int pwc_video_poll(struct file *file, poll_table *wait) { struct video_device *vdev = file->private_data; struct pwc_device *pdev; + int ret; if (vdev == NULL) return -EFAULT; @@ -1401,6 +1368,13 @@ static unsigned int pwc_video_poll(struct file *file, poll_table *wait) if (pdev == NULL) return -EFAULT; + /* Start the stream (if not already started) */ + mutex_lock(&pdev->modlock); + ret = pwc_isoc_init(pdev); + mutex_unlock(&pdev->modlock); + if (ret) + return ret; + poll_wait(file, &pdev->frameq, wait); if (pdev->error_status) return POLLERR; diff --git a/drivers/media/video/pwc/pwc-v4l.c b/drivers/media/video/pwc/pwc-v4l.c index 7061a03f5cf1..2ef1668638f9 100644 --- a/drivers/media/video/pwc/pwc-v4l.c +++ b/drivers/media/video/pwc/pwc-v4l.c @@ -309,7 +309,10 @@ static int pwc_vidioc_set_fmt(struct pwc_device *pdev, struct v4l2_format *f) pixelformat != V4L2_PIX_FMT_PWC2) return -EINVAL; - PWC_DEBUG_IOCTL("Try to change format to: width=%d height=%d fps=%d " + if (pdev->iso_init) + return -EBUSY; + + PWC_DEBUG_IOCTL("Trying to set format to: width=%d height=%d fps=%d " "compression=%d snapshot=%d format=%c%c%c%c\n", f->fmt.pix.width, f->fmt.pix.height, fps, compression, snapshot, @@ -318,14 +321,14 @@ static int pwc_vidioc_set_fmt(struct pwc_device *pdev, struct v4l2_format *f) (pixelformat>>16)&255, (pixelformat>>24)&255); - ret = pwc_try_video_mode(pdev, + ret = pwc_set_video_mode(pdev, f->fmt.pix.width, f->fmt.pix.height, fps, compression, snapshot); - PWC_DEBUG_IOCTL("pwc_try_video_mode(), return=%d\n", ret); + PWC_DEBUG_IOCTL("pwc_set_video_mode(), return=%d\n", ret); if (ret) return ret; @@ -882,9 +885,7 @@ long pwc_video_do_ioctl(struct file *file, unsigned int cmd, void *arg) case VIDIOC_STREAMON: { - /* WARNING: pwc_try_video_mode() called pwc_isoc_init */ - pwc_isoc_init(pdev); - return 0; + return pwc_isoc_init(pdev); } case VIDIOC_STREAMOFF: diff --git a/drivers/media/video/pwc/pwc.h b/drivers/media/video/pwc/pwc.h index 36a9c83b5f5d..16bbc6df9b07 100644 --- a/drivers/media/video/pwc/pwc.h +++ b/drivers/media/video/pwc/pwc.h @@ -275,7 +275,6 @@ extern int pwc_trace; extern int pwc_mbufs; /** functions in pwc-if.c */ -int pwc_try_video_mode(struct pwc_device *pdev, int width, int height, int new_fps, int new_compression, int new_snapshot); int pwc_handle_frame(struct pwc_device *pdev); void pwc_next_image(struct pwc_device *pdev); int pwc_isoc_init(struct pwc_device *pdev); -- cgit v1.2.2 From c7d18867c82657a97f0bdb90ba1151b251b6a29b Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 16 Nov 2010 12:26:00 -0300 Subject: [media] pwc: Also set alt setting to alt0 when no error occured isoc_cleanup contains a check to not set the altsetting to alt0 when the device was unplugged, but the check currently is buggy, and causes the alt setting to only be set to 0 if an error occured while streaming. Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/pwc/pwc-if.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media/video/pwc') diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c index 6f8b682b9245..97319efc9948 100644 --- a/drivers/media/video/pwc/pwc-if.c +++ b/drivers/media/video/pwc/pwc-if.c @@ -957,7 +957,7 @@ void pwc_isoc_cleanup(struct pwc_device *pdev) /* Stop camera, but only if we are sure the camera is still there (unplug is signalled by EPIPE) */ - if (pdev->error_status && pdev->error_status != EPIPE) { + if (pdev->error_status != EPIPE) { PWC_DEBUG_OPEN("Setting alternate interface 0.\n"); usb_set_interface(pdev->udev, 0, 0); } -- cgit v1.2.2 From 622d9f5d302e99dc7a06cb442e9d9ff2bb0f59b5 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 16 Nov 2010 12:32:09 -0300 Subject: [media] pwc: failure to submit an urb is a fatal error Failure to submit an urb is a fatal error, make isoc_init return an error when this happens rather then only log it. Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/pwc/pwc-if.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers/media/video/pwc') diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c index 97319efc9948..bd1519a4ecb4 100644 --- a/drivers/media/video/pwc/pwc-if.c +++ b/drivers/media/video/pwc/pwc-if.c @@ -898,10 +898,13 @@ int pwc_isoc_init(struct pwc_device *pdev) /* link */ for (i = 0; i < MAX_ISO_BUFS; i++) { ret = usb_submit_urb(pdev->sbuf[i].urb, GFP_KERNEL); - if (ret) + if (ret) { PWC_ERROR("isoc_init() submit_urb %d failed with error %d\n", i, ret); - else - PWC_DEBUG_MEMORY("URB 0x%p submitted.\n", pdev->sbuf[i].urb); + pdev->iso_init = 1; + pwc_isoc_cleanup(pdev); + return ret; + } + PWC_DEBUG_MEMORY("URB 0x%p submitted.\n", pdev->sbuf[i].urb); } /* All is done... */ -- cgit v1.2.2 From 08af245de0cf6ab5f4ed008ee2bb99273774fce0 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 24 Dec 2010 10:33:19 -0300 Subject: [media] V4L: remove V4L1 compatibility mode Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/pwc/pwc-v4l.c | 17 ----------------- 1 file changed, 17 deletions(-) (limited to 'drivers/media/video/pwc') diff --git a/drivers/media/video/pwc/pwc-v4l.c b/drivers/media/video/pwc/pwc-v4l.c index 2ef1668638f9..8ca4d22b4384 100644 --- a/drivers/media/video/pwc/pwc-v4l.c +++ b/drivers/media/video/pwc/pwc-v4l.c @@ -362,23 +362,6 @@ long pwc_video_do_ioctl(struct file *file, unsigned int cmd, void *arg) switch (cmd) { -#ifdef CONFIG_VIDEO_V4L1_COMPAT - /* mmap() functions */ - case VIDIOCGMBUF: - { - /* Tell the user program how much memory is needed for a mmap() */ - struct video_mbuf *vm = arg; - int i; - - memset(vm, 0, sizeof(*vm)); - vm->size = pwc_mbufs * pdev->len_per_image; - vm->frames = pwc_mbufs; /* double buffering should be enough for most applications */ - for (i = 0; i < pwc_mbufs; i++) - vm->offsets[i] = i * pdev->len_per_image; - break; - } -#endif - /* V4L2 Layer */ case VIDIOC_QUERYCAP: { -- cgit v1.2.2