From: Mauro Carvalho Chehab <mchehab@infradead.org>
To: Oliver Neukum <oliver@neukum.org>
Cc: Alex Smith <lkml@alex-smith.me.uk>, linux-kernel@vger.kernel.org
Subject: Re: Oops in pwc v4l driver
Date: Wed, 26 Sep 2007 10:07:21 -0300 [thread overview]
Message-ID: <1190812041.5076.7.camel@gaivota> (raw)
In-Reply-To: <200709021502.17458.oliver@neukum.org>
Hi Oliver,
May you send your Signed-off-by for the patch?
Cheers,
Mauro.
Em Dom, 2007-09-02 às 15:02 +0200, Oliver Neukum escreveu:
> Am Sonntag 02 September 2007 schrieb Alex Smith:
> > Hi,
> >
> > I found an old Philips Askey VC010 webcam and attempted to get it
> > working on Linux (latest git, x86_64). It worked fine, I could view
> > the camera in mplayer. But, however, when I went to move the camera, I
> > unplugged it and forgot to close mplayer. I didn't notice, moved it,
>
> Yes,
>
> this is a known issue. This patch should fix it. Does it work for you?
>
> Regards
> Oliver
> ---
>
> --- a/drivers/media/video/pwc/pwc-if.c 2007-08-24 10:16:38.000000000 +0200
> +++ b/drivers/media/video/pwc/pwc-if.c 2007-08-24 11:01:26.000000000 +0200
> @@ -908,31 +908,49 @@ int pwc_isoc_init(struct pwc_device *pde
> return 0;
> }
>
> -void pwc_isoc_cleanup(struct pwc_device *pdev)
> +static void pwc_iso_stop(struct pwc_device *pdev)
> {
> int i;
>
> - PWC_DEBUG_OPEN(">> pwc_isoc_cleanup()\n");
> - if (pdev == NULL)
> - return;
> - if (pdev->iso_init == 0)
> - return;
> -
> /* Unlinking ISOC buffers one by one */
> for (i = 0; i < MAX_ISO_BUFS; i++) {
> struct urb *urb;
>
> urb = pdev->sbuf[i].urb;
> if (urb != 0) {
> - if (pdev->iso_init) {
> - PWC_DEBUG_MEMORY("Unlinking URB %p\n", urb);
> - usb_kill_urb(urb);
> - }
> + PWC_DEBUG_MEMORY("Unlinking URB %p\n", urb);
> + usb_kill_urb(urb);
> + }
> + }
> +}
> +
> +static void pwc_iso_free(struct pwc_device *pdev)
> +{
> + int i;
> +
> + /* Freeing ISOC buffers one by one */
> + for (i = 0; i < MAX_ISO_BUFS; i++) {
> + struct urb *urb;
> +
> + urb = pdev->sbuf[i].urb;
> + if (urb != 0) {
> PWC_DEBUG_MEMORY("Freeing URB\n");
> usb_free_urb(urb);
> pdev->sbuf[i].urb = NULL;
> }
> }
> +}
> +
> +void pwc_isoc_cleanup(struct pwc_device *pdev)
> +{
> + PWC_DEBUG_OPEN(">> pwc_isoc_cleanup()\n");
> + if (pdev == NULL)
> + return;
> + if (pdev->iso_init == 0)
> + return;
> +
> + pwc_iso_stop(pdev);
> + pwc_iso_free(pdev);
>
> /* Stop camera, but only if we are sure the camera is still there (unplug
> is signalled by EPIPE)
> @@ -1212,6 +1230,7 @@ static int pwc_video_close(struct inode
>
> PWC_DEBUG_OPEN(">> video_close called(vdev = 0x%p).\n", vdev);
>
> + lock_kernel();
> pdev = (struct pwc_device *)vdev->priv;
> if (pdev->vopen == 0)
> PWC_DEBUG_MODULE("video_close() called on closed device?\n");
> @@ -1231,7 +1250,6 @@ static int pwc_video_close(struct inode
> pwc_isoc_cleanup(pdev);
> pwc_free_buffers(pdev);
>
> - lock_kernel();
> /* Turn off LEDS and power down camera, but only when not unplugged */
> if (!pdev->unplugged) {
> /* Turn LEDs off */
> @@ -1277,7 +1295,7 @@ static ssize_t pwc_video_read(struct fil
> struct pwc_device *pdev;
> int noblock = file->f_flags & O_NONBLOCK;
> DECLARE_WAITQUEUE(wait, current);
> - int bytes_to_read;
> + int bytes_to_read, rv = 0;
> void *image_buffer_addr;
>
> PWC_DEBUG_READ("pwc_video_read(vdev=0x%p, buf=%p, count=%zd) called.\n",
> @@ -1287,8 +1305,12 @@ static ssize_t pwc_video_read(struct fil
> pdev = vdev->priv;
> if (pdev == NULL)
> return -EFAULT;
> - if (pdev->error_status)
> - return -pdev->error_status; /* Something happened, report what. */
> +
> + mutex_lock(&pdev->modlock);
> + if (pdev->error_status) {
> + rv = -pdev->error_status; /* Something happened, report what. */
> + 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) {
> @@ -1299,17 +1321,20 @@ static ssize_t pwc_video_read(struct fil
> if (pdev->error_status) {
> remove_wait_queue(&pdev->frameq, &wait);
> set_current_state(TASK_RUNNING);
> - return -pdev->error_status ;
> + rv = -pdev->error_status ;
> + goto err_out;
> }
> if (noblock) {
> remove_wait_queue(&pdev->frameq, &wait);
> set_current_state(TASK_RUNNING);
> - return -EWOULDBLOCK;
> + rv = -EWOULDBLOCK;
> + goto err_out;
> }
> if (signal_pending(current)) {
> remove_wait_queue(&pdev->frameq, &wait);
> set_current_state(TASK_RUNNING);
> - return -ERESTARTSYS;
> + rv = -ERESTARTSYS;
> + goto err_out;
> }
> schedule();
> set_current_state(TASK_INTERRUPTIBLE);
> @@ -1318,8 +1343,10 @@ static ssize_t pwc_video_read(struct fil
> set_current_state(TASK_RUNNING);
>
> /* Decompress and release frame */
> - if (pwc_handle_frame(pdev))
> - return -EFAULT;
> + if (pwc_handle_frame(pdev)) {
> + rv = -EFAULT;
> + goto err_out;
> + }
> }
>
> PWC_DEBUG_READ("Copying data to user space.\n");
> @@ -1334,14 +1361,20 @@ static ssize_t pwc_video_read(struct fil
> image_buffer_addr = pdev->image_data;
> image_buffer_addr += pdev->images[pdev->fill_image].offset;
> image_buffer_addr += pdev->image_read_pos;
> - if (copy_to_user(buf, image_buffer_addr, count))
> - return -EFAULT;
> + if (copy_to_user(buf, image_buffer_addr, count)) {
> + rv = -EFAULT;
> + goto err_out;
> + }
> pdev->image_read_pos += count;
> if (pdev->image_read_pos >= bytes_to_read) { /* All data has been read */
> pdev->image_read_pos = 0;
> pwc_next_image(pdev);
> }
> + mutex_unlock(&pdev->modlock);
> return count;
> +err_out:
> + mutex_unlock(&pdev->modlock);
> + return rv;
> }
>
> static unsigned int pwc_video_poll(struct file *file, poll_table *wait)
> @@ -1367,7 +1400,20 @@ static unsigned int pwc_video_poll(struc
> static int pwc_video_ioctl(struct inode *inode, struct file *file,
> unsigned int cmd, unsigned long arg)
> {
> - return video_usercopy(inode, file, cmd, arg, pwc_video_do_ioctl);
> + struct video_device *vdev = file->private_data;
> + struct pwc_device *pdev;
> + int r = -ENODEV;
> +
> + if (!vdev)
> + goto out;
> + pdev = vdev->priv;
> +
> + mutex_lock(&pdev->modlock);
> + if (!pdev->unplugged)
> + r = video_usercopy(inode, file, cmd, arg, pwc_video_do_ioctl);
> + mutex_unlock(&pdev->modlock);
> +out:
> + return r;
> }
>
> static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma)
> @@ -1810,7 +1856,10 @@ static void usb_pwc_disconnect(struct us
> wake_up_interruptible(&pdev->frameq);
> /* Wait until device is closed */
> if(pdev->vopen) {
> + mutex_lock(&pdev->modlock);
> pdev->unplugged = 1;
> + mutex_unlock(&pdev->modlock);
> + pwc_iso_stop(pdev);
> } else {
> /* Device is closed, so we can safely unregister it */
> PWC_DEBUG_PROBE("Unregistering video device in disconnect().\n");
> @@ -1828,7 +1877,6 @@ disconnect_out:
> unlock_kernel();
> }
>
> -
> /* *grunt* We have to do atoi ourselves :-( */
> static int pwc_atoi(const char *s)
> {
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
--
Cheers,
Mauro
next prev parent reply other threads:[~2007-09-26 13:09 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-09-02 11:57 Oops in pwc v4l driver Alex Smith
2007-09-02 13:02 ` Oliver Neukum
2007-09-26 13:07 ` Mauro Carvalho Chehab [this message]
2007-09-02 23:47 ` Michal Piotrowski
2007-09-03 6:37 ` Oliver Neukum
2007-09-08 13:59 ` Alex Smith
2007-09-26 13:16 ` Oliver Neukum
2007-09-26 13:19 ` Oliver Neukum
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1190812041.5076.7.camel@gaivota \
--to=mchehab@infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=lkml@alex-smith.me.uk \
--cc=oliver@neukum.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.