diff options
author | Hans de Goede <hdegoede@redhat.com> | 2012-09-09 07:04:05 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-09-13 16:53:10 -0400 |
commit | 36adfca94a354b10b4e36684a45e830f6817b067 (patch) | |
tree | bc4d31761f9203b76a9d0ea944f61ed2d5d9aa4b /drivers/media/usb/gspca | |
parent | 844db450e6e2cf710752af1a019a877af390b541 (diff) |
[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')
-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) | |||
2391 | { | 2391 | { |
2392 | struct gspca_dev *gspca_dev = usb_get_intfdata(intf); | 2392 | struct gspca_dev *gspca_dev = usb_get_intfdata(intf); |
2393 | 2393 | ||
2394 | gspca_input_destroy_urb(gspca_dev); | ||
2395 | |||
2394 | if (!gspca_dev->streaming) | 2396 | if (!gspca_dev->streaming) |
2395 | return 0; | 2397 | return 0; |
2398 | |||
2396 | mutex_lock(&gspca_dev->usb_lock); | 2399 | mutex_lock(&gspca_dev->usb_lock); |
2397 | gspca_dev->frozen = 1; /* avoid urb error messages */ | 2400 | gspca_dev->frozen = 1; /* avoid urb error messages */ |
2398 | gspca_dev->usb_err = 0; | 2401 | gspca_dev->usb_err = 0; |
2399 | if (gspca_dev->sd_desc->stopN) | 2402 | if (gspca_dev->sd_desc->stopN) |
2400 | gspca_dev->sd_desc->stopN(gspca_dev); | 2403 | gspca_dev->sd_desc->stopN(gspca_dev); |
2401 | destroy_urbs(gspca_dev); | 2404 | destroy_urbs(gspca_dev); |
2402 | gspca_input_destroy_urb(gspca_dev); | ||
2403 | gspca_set_alt0(gspca_dev); | 2405 | gspca_set_alt0(gspca_dev); |
2404 | if (gspca_dev->sd_desc->stop0) | 2406 | if (gspca_dev->sd_desc->stop0) |
2405 | gspca_dev->sd_desc->stop0(gspca_dev); | 2407 | gspca_dev->sd_desc->stop0(gspca_dev); |
2406 | mutex_unlock(&gspca_dev->usb_lock); | 2408 | mutex_unlock(&gspca_dev->usb_lock); |
2409 | |||
2407 | return 0; | 2410 | return 0; |
2408 | } | 2411 | } |
2409 | EXPORT_SYMBOL(gspca_suspend); | 2412 | EXPORT_SYMBOL(gspca_suspend); |
@@ -2417,7 +2420,6 @@ int gspca_resume(struct usb_interface *intf) | |||
2417 | gspca_dev->frozen = 0; | 2420 | gspca_dev->frozen = 0; |
2418 | gspca_dev->usb_err = 0; | 2421 | gspca_dev->usb_err = 0; |
2419 | gspca_dev->sd_desc->init(gspca_dev); | 2422 | gspca_dev->sd_desc->init(gspca_dev); |
2420 | gspca_input_create_urb(gspca_dev); | ||
2421 | /* | 2423 | /* |
2422 | * Most subdrivers send all ctrl values on sd_start and thus | 2424 | * Most subdrivers send all ctrl values on sd_start and thus |
2423 | * only write to the device registers on s_ctrl when streaming -> | 2425 | * only write to the device registers on s_ctrl when streaming -> |
@@ -2427,7 +2429,10 @@ int gspca_resume(struct usb_interface *intf) | |||
2427 | gspca_dev->streaming = 0; | 2429 | gspca_dev->streaming = 0; |
2428 | if (streaming) | 2430 | if (streaming) |
2429 | ret = gspca_init_transfer(gspca_dev); | 2431 | ret = gspca_init_transfer(gspca_dev); |
2432 | else | ||
2433 | gspca_input_create_urb(gspca_dev); | ||
2430 | mutex_unlock(&gspca_dev->usb_lock); | 2434 | mutex_unlock(&gspca_dev->usb_lock); |
2435 | |||
2431 | return ret; | 2436 | return ret; |
2432 | } | 2437 | } |
2433 | EXPORT_SYMBOL(gspca_resume); | 2438 | EXPORT_SYMBOL(gspca_resume); |