aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb/dvb-usb
diff options
context:
space:
mode:
authorAntti Palosaari <crope@iki.fi>2012-06-09 20:11:28 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-08-04 06:56:28 -0400
commit3238aafbc3f860d685fc96b5b93a2f14decaec2e (patch)
tree8734065abf0f63e26252e0880419b48c6a7236bf /drivers/media/dvb/dvb-usb
parent36a5c2bdedcba50435e1e9a9c62a99797783b2c4 (diff)
[media] dvb_usb_v2: do not free resources until delayed init is done
It was possible to free resources by unloading module while initialization was still ongoing on delayed work. Use PID to make decision on .disconnect() if caller is our work or some other as work also calls .disconnect() in error case. There could be better solution still... Signed-off-by: Antti Palosaari <crope@iki.fi> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/dvb/dvb-usb')
-rw-r--r--drivers/media/dvb/dvb-usb/dvb_usb.h1
-rw-r--r--drivers/media/dvb/dvb-usb/dvb_usb_init.c21
2 files changed, 9 insertions, 13 deletions
diff --git a/drivers/media/dvb/dvb-usb/dvb_usb.h b/drivers/media/dvb/dvb-usb/dvb_usb.h
index 4394a5d6f161..79f8571b9b20 100644
--- a/drivers/media/dvb/dvb-usb/dvb_usb.h
+++ b/drivers/media/dvb/dvb-usb/dvb_usb.h
@@ -322,6 +322,7 @@ struct dvb_usb_device {
322 struct dvb_usb_rc rc; 322 struct dvb_usb_rc rc;
323 struct usb_device *udev; 323 struct usb_device *udev;
324 struct work_struct probe_work; 324 struct work_struct probe_work;
325 pid_t work_pid;
325 struct usb_interface *intf; 326 struct usb_interface *intf;
326 327
327#define DVB_USB_STATE_INIT 0x000 328#define DVB_USB_STATE_INIT 0x000
diff --git a/drivers/media/dvb/dvb-usb/dvb_usb_init.c b/drivers/media/dvb/dvb-usb/dvb_usb_init.c
index 0a452fc4edc8..9f75bb18ed17 100644
--- a/drivers/media/dvb/dvb-usb/dvb_usb_init.c
+++ b/drivers/media/dvb/dvb-usb/dvb_usb_init.c
@@ -267,10 +267,6 @@ int dvb_usb_device_power_ctrl(struct dvb_usb_device *d, int onoff)
267} 267}
268 268
269/* 269/*
270 * USB
271 */
272
273/*
274 * udev, which is used for the firmware downloading, requires we cannot 270 * udev, which is used for the firmware downloading, requires we cannot
275 * block during module_init(). module_init() calls USB probe() which 271 * block during module_init(). module_init() calls USB probe() which
276 * is this routine. Due to that we delay actual operation using workqueue 272 * is this routine. Due to that we delay actual operation using workqueue
@@ -284,7 +280,9 @@ static void dvb_usbv2_init_work(struct work_struct *work)
284 container_of(work, struct dvb_usb_device, probe_work); 280 container_of(work, struct dvb_usb_device, probe_work);
285 bool cold = false; 281 bool cold = false;
286 282
287 pr_debug("%s:\n", __func__); 283 d->work_pid = current->pid;
284
285 pr_debug("%s: work_pid=%d\n", __func__, d->work_pid);
288 286
289 if (d->props.size_of_priv) { 287 if (d->props.size_of_priv) {
290 d->priv = kzalloc(d->props.size_of_priv, GFP_KERNEL); 288 d->priv = kzalloc(d->props.size_of_priv, GFP_KERNEL);
@@ -405,15 +403,12 @@ void dvb_usbv2_disconnect(struct usb_interface *intf)
405 struct dvb_usb_device *d = usb_get_intfdata(intf); 403 struct dvb_usb_device *d = usb_get_intfdata(intf);
406 const char *name = "generic DVB-USB module"; 404 const char *name = "generic DVB-USB module";
407 405
408 pr_debug("%s:\n", __func__); 406 pr_debug("%s: pid=%d work_pid=%d\n", __func__, current->pid,
407 d->work_pid);
409 408
410 /* 409 /* ensure initialization work is finished until release resources */
411 * FIXME: We should ensure initialization work is finished 410 if (d->work_pid != current->pid)
412 * until exit from this routine (cancel_work_sync / flush_work). 411 cancel_work_sync(&d->probe_work);
413 * Unfortunately usb_driver_release_interface() call finally goes
414 * here too and in that case we endup deadlock. How to perform
415 * operation conditionally only on disconned / unload?
416 */
417 412
418 usb_set_intfdata(intf, NULL); 413 usb_set_intfdata(intf, NULL);
419 if (d) { 414 if (d) {