From b824bb4b12548fedd622686d443310d574eb084e Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 25 Jun 2011 17:39:19 -0300 Subject: [PATCH] [media] pwc: Get rid of error_status and unplugged variables Having 2 ways of tracking disconnection is too much, remove both and instead simply set pdev->udev to NULL on disconnect. Also check for pdev->udev being NULL in all possible entry paths. Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/pwc/pwc-if.c | 38 ++++++++++++++----------------- drivers/media/video/pwc/pwc-v4l.c | 24 +++++++++++++++++++ drivers/media/video/pwc/pwc.h | 2 -- 3 files changed, 41 insertions(+), 23 deletions(-) diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c index 907db23fdb5..6bff33b357b 100644 --- a/drivers/media/video/pwc/pwc-if.c +++ b/drivers/media/video/pwc/pwc-if.c @@ -570,14 +570,7 @@ static void pwc_isoc_cleanup(struct pwc_device *pdev) 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) - */ - if (pdev->error_status != EPIPE) { - PWC_DEBUG_OPEN("Setting alternate interface 0.\n"); - usb_set_interface(pdev->udev, 0, 0); - } + usb_set_interface(pdev->udev, 0, 0); pdev->iso_init = 0; PWC_DEBUG_OPEN("<< pwc_isoc_cleanup()\n"); @@ -719,6 +712,9 @@ static int pwc_video_open(struct file *file) PWC_DEBUG_OPEN(">> video_open called(vdev = 0x%p).\n", vdev); pdev = video_get_drvdata(vdev); + if (!pdev->udev) + return -ENODEV; + if (pdev->vopen) { PWC_DEBUG_OPEN("I'm busy, someone is using the device.\n"); return -EBUSY; @@ -760,7 +756,6 @@ static int pwc_video_open(struct file *file) /* Reset buffers & parameters */ pdev->visoc_errors = 0; - pdev->error_status = 0; pwc_construct(pdev); /* set min/max sizes correct */ /* Set some defaults */ @@ -837,7 +832,7 @@ static int pwc_video_close(struct file *file) pwc_free_buffers(pdev); /* Turn off LEDS and power down camera, but only when not unplugged */ - if (!pdev->unplugged) { + if (pdev->udev) { /* Turn LEDs off */ if (pwc_set_leds(pdev, 0, 0) < 0) PWC_DEBUG_MODULE("Failed to set LED on/off time.\n"); @@ -859,8 +854,8 @@ static ssize_t pwc_video_read(struct file *file, char __user *buf, struct video_device *vdev = file->private_data; struct pwc_device *pdev = video_get_drvdata(vdev); - if (pdev->error_status) - return -pdev->error_status; + if (!pdev->udev) + return -ENODEV; return vb2_read(&pdev->vb_queue, buf, count, ppos, file->f_flags & O_NONBLOCK); @@ -871,7 +866,7 @@ static unsigned int pwc_video_poll(struct file *file, poll_table *wait) struct video_device *vdev = file->private_data; struct pwc_device *pdev = video_get_drvdata(vdev); - if (pdev->error_status) + if (!pdev->udev) return POLL_ERR; return vb2_poll(&pdev->vb_queue, file, wait); @@ -923,8 +918,8 @@ static int buffer_prepare(struct vb2_buffer *vb) struct pwc_device *pdev = vb2_get_drv_priv(vb->vb2_queue); /* Don't allow queing new buffers after device disconnection */ - if (pdev->error_status) - return -pdev->error_status; + if (!pdev->udev) + return -ENODEV; return 0; } @@ -964,6 +959,9 @@ static int start_streaming(struct vb2_queue *vq) { struct pwc_device *pdev = vb2_get_drv_priv(vq); + if (!pdev->udev) + return -ENODEV; + return pwc_isoc_init(pdev); } @@ -971,7 +969,8 @@ static int stop_streaming(struct vb2_queue *vq) { struct pwc_device *pdev = vb2_get_drv_priv(vq); - pwc_isoc_cleanup(pdev); + if (pdev->udev) + pwc_isoc_cleanup(pdev); pwc_cleanup_queued_bufs(pdev); return 0; @@ -1389,15 +1388,12 @@ static void usb_pwc_disconnect(struct usb_interface *intf) struct pwc_device *pdev = usb_get_intfdata(intf); mutex_lock(&pdev->modlock); - usb_set_intfdata (intf, NULL); - - /* We got unplugged; this is signalled by an EPIPE error code */ - pdev->error_status = EPIPE; - pdev->unplugged = 1; + usb_set_intfdata(intf, NULL); /* No need to keep the urbs around after disconnection */ pwc_isoc_cleanup(pdev); pwc_cleanup_queued_bufs(pdev); + pdev->udev = NULL; mutex_unlock(&pdev->modlock); diff --git a/drivers/media/video/pwc/pwc-v4l.c b/drivers/media/video/pwc/pwc-v4l.c index cda38837adc..8bd0a681990 100644 --- a/drivers/media/video/pwc/pwc-v4l.c +++ b/drivers/media/video/pwc/pwc-v4l.c @@ -288,6 +288,9 @@ static int pwc_vidioc_set_fmt(struct pwc_device *pdev, struct v4l2_format *f) { int ret, fps, snapshot, compression, pixelformat; + if (!pdev->udev) + return -ENODEV; + ret = pwc_vidioc_try_fmt(pdev, f); if (ret<0) return ret; @@ -346,6 +349,9 @@ static int pwc_querycap(struct file *file, void *fh, struct v4l2_capability *cap struct video_device *vdev = video_devdata(file); struct pwc_device *pdev = video_drvdata(file); + if (!pdev->udev) + return -ENODEV; + strcpy(cap->driver, PWC_NAME); strlcpy(cap->card, vdev->name, sizeof(cap->card)); usb_make_path(pdev->udev, cap->bus_info, sizeof(cap->bus_info)); @@ -414,6 +420,9 @@ static int pwc_g_ctrl(struct file *file, void *fh, struct v4l2_control *c) struct pwc_device *pdev = video_drvdata(file); int ret; + if (!pdev->udev) + return -ENODEV; + switch (c->id) { case V4L2_CID_BRIGHTNESS: c->value = pwc_get_brightness(pdev); @@ -517,6 +526,9 @@ static int pwc_s_ctrl(struct file *file, void *fh, struct v4l2_control *c) struct pwc_device *pdev = video_drvdata(file); int ret; + if (!pdev->udev) + return -ENODEV; + switch (c->id) { case V4L2_CID_BRIGHTNESS: c->value <<= 9; @@ -692,6 +704,9 @@ static int pwc_qbuf(struct file *file, void *fh, struct v4l2_buffer *buf) { struct pwc_device *pdev = video_drvdata(file); + if (!pdev->udev) + return -ENODEV; + return vb2_qbuf(&pdev->vb_queue, buf); } @@ -699,6 +714,9 @@ static int pwc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf) { struct pwc_device *pdev = video_drvdata(file); + if (!pdev->udev) + return -ENODEV; + return vb2_dqbuf(&pdev->vb_queue, buf, file->f_flags & O_NONBLOCK); } @@ -706,6 +724,9 @@ static int pwc_streamon(struct file *file, void *fh, enum v4l2_buf_type i) { struct pwc_device *pdev = video_drvdata(file); + if (!pdev->udev) + return -ENODEV; + return vb2_streamon(&pdev->vb_queue, i); } @@ -713,6 +734,9 @@ static int pwc_streamoff(struct file *file, void *fh, enum v4l2_buf_type i) { struct pwc_device *pdev = video_drvdata(file); + if (!pdev->udev) + return -ENODEV; + return vb2_streamoff(&pdev->vb_queue, i); } diff --git a/drivers/media/video/pwc/pwc.h b/drivers/media/video/pwc/pwc.h index cfe82319f34..13b85246a26 100644 --- a/drivers/media/video/pwc/pwc.h +++ b/drivers/media/video/pwc/pwc.h @@ -161,7 +161,6 @@ struct pwc_device int release; /* release number */ int features; /* feature bits */ char serial[30]; /* serial number (string) */ - int error_status; /* set when something goes wrong */ int usb_init; /* set when the cam has been initialized */ /*** Video data ***/ @@ -180,7 +179,6 @@ struct pwc_device char vsnapshot; /* snapshot mode */ char vsync; /* used by isoc handler */ char vmirror; /* for ToUCaM series */ - char unplugged; int cmd_len; unsigned char cmd_buf[13]; -- 2.39.5