diff options
author | Hans de Goede <hdegoede@redhat.com> | 2012-09-09 15:04:05 +0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-09-14 00:53:10 +0400 |
commit | 36adfca94a354b10b4e36684a45e830f6817b067 (patch) | |
tree | bc4d31761f9203b76a9d0ea944f61ed2d5d9aa4b /drivers/media/usb/gspca/gspca.c | |
parent | 844db450e6e2cf710752af1a019a877af390b541 (diff) | |
download | linux-36adfca94a354b10b4e36684a45e830f6817b067.tar.xz |
[media] gspca: Fix input urb creation / destruction surrounding suspend resume
1) We always re-create the input-urb on resume, so we must also always
destroy it on suspend to avoid leaking it
2) If we're going to do an init_transfer, then that will destroy the urb
before starting the stream (nop if there is none), and (re-)create it
once the stream is started. So there is little use in creating it, if
we're going to do an init_transfer immediately afterward
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/usb/gspca/gspca.c')
-rw-r--r-- | drivers/media/usb/gspca/gspca.c | 9 |
1 files changed, 7 insertions, 2 deletions
diff --git a/drivers/media/usb/gspca/gspca.c b/drivers/media/usb/gspca/gspca.c index 7cce0f201d70..2abbf52c781a 100644 --- a/drivers/media/usb/gspca/gspca.c +++ b/drivers/media/usb/gspca/gspca.c @@ -2391,19 +2391,22 @@ int gspca_suspend(struct usb_interface *intf, pm_message_t message) { struct gspca_dev *gspca_dev = usb_get_intfdata(intf); + gspca_input_destroy_urb(gspca_dev); + if (!gspca_dev->streaming) return 0; + mutex_lock(&gspca_dev->usb_lock); gspca_dev->frozen = 1; /* avoid urb error messages */ gspca_dev->usb_err = 0; if (gspca_dev->sd_desc->stopN) gspca_dev->sd_desc->stopN(gspca_dev); destroy_urbs(gspca_dev); - gspca_input_destroy_urb(gspca_dev); gspca_set_alt0(gspca_dev); if (gspca_dev->sd_desc->stop0) gspca_dev->sd_desc->stop0(gspca_dev); mutex_unlock(&gspca_dev->usb_lock); + return 0; } EXPORT_SYMBOL(gspca_suspend); @@ -2417,7 +2420,6 @@ int gspca_resume(struct usb_interface *intf) gspca_dev->frozen = 0; gspca_dev->usb_err = 0; gspca_dev->sd_desc->init(gspca_dev); - gspca_input_create_urb(gspca_dev); /* * Most subdrivers send all ctrl values on sd_start and thus * only write to the device registers on s_ctrl when streaming -> @@ -2427,7 +2429,10 @@ int gspca_resume(struct usb_interface *intf) gspca_dev->streaming = 0; if (streaming) ret = gspca_init_transfer(gspca_dev); + else + gspca_input_create_urb(gspca_dev); mutex_unlock(&gspca_dev->usb_lock); + return ret; } EXPORT_SYMBOL(gspca_resume); |