diff options
author | Hans Verkuil <hverkuil@xs4all.nl> | 2011-01-17 18:25:11 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2011-03-22 15:38:09 -0400 |
commit | 13099294973b14f07915d0342af2be8fa0af589b (patch) | |
tree | 0b755cadc08407c29f0046c83f03df40e7c568cf /drivers/media/radio/dsbr100.c | |
parent | e64d07c92daa5c7973c1d4433f939a4e0fa3beb9 (diff) |
[media] dsbr100: ensure correct disconnect sequence
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/radio/dsbr100.c')
-rw-r--r-- | drivers/media/radio/dsbr100.c | 59 |
1 files changed, 12 insertions, 47 deletions
diff --git a/drivers/media/radio/dsbr100.c b/drivers/media/radio/dsbr100.c index bf2dd6ff042a..3d8cc425fa6b 100644 --- a/drivers/media/radio/dsbr100.c +++ b/drivers/media/radio/dsbr100.c | |||
@@ -129,7 +129,7 @@ devices, that would be 76 and 91. */ | |||
129 | #define STARTED 0 | 129 | #define STARTED 0 |
130 | #define STOPPED 1 | 130 | #define STOPPED 1 |
131 | 131 | ||
132 | #define videodev_to_radio(d) container_of(d, struct dsbr100_device, videodev) | 132 | #define v4l2_dev_to_radio(d) container_of(d, struct dsbr100_device, v4l2_dev) |
133 | 133 | ||
134 | static int usb_dsbr100_probe(struct usb_interface *intf, | 134 | static int usb_dsbr100_probe(struct usb_interface *intf, |
135 | const struct usb_device_id *id); | 135 | const struct usb_device_id *id); |
@@ -151,7 +151,6 @@ struct dsbr100_device { | |||
151 | struct mutex v4l2_lock; | 151 | struct mutex v4l2_lock; |
152 | int curfreq; | 152 | int curfreq; |
153 | int stereo; | 153 | int stereo; |
154 | int removed; | ||
155 | int status; | 154 | int status; |
156 | }; | 155 | }; |
157 | 156 | ||
@@ -346,10 +345,6 @@ static int vidioc_g_tuner(struct file *file, void *priv, | |||
346 | { | 345 | { |
347 | struct dsbr100_device *radio = video_drvdata(file); | 346 | struct dsbr100_device *radio = video_drvdata(file); |
348 | 347 | ||
349 | /* safety check */ | ||
350 | if (radio->removed) | ||
351 | return -EIO; | ||
352 | |||
353 | if (v->index > 0) | 348 | if (v->index > 0) |
354 | return -EINVAL; | 349 | return -EINVAL; |
355 | 350 | ||
@@ -371,16 +366,7 @@ static int vidioc_g_tuner(struct file *file, void *priv, | |||
371 | static int vidioc_s_tuner(struct file *file, void *priv, | 366 | static int vidioc_s_tuner(struct file *file, void *priv, |
372 | struct v4l2_tuner *v) | 367 | struct v4l2_tuner *v) |
373 | { | 368 | { |
374 | struct dsbr100_device *radio = video_drvdata(file); | 369 | return v->index ? -EINVAL : 0; |
375 | |||
376 | /* safety check */ | ||
377 | if (radio->removed) | ||
378 | return -EIO; | ||
379 | |||
380 | if (v->index > 0) | ||
381 | return -EINVAL; | ||
382 | |||
383 | return 0; | ||
384 | } | 370 | } |
385 | 371 | ||
386 | static int vidioc_s_frequency(struct file *file, void *priv, | 372 | static int vidioc_s_frequency(struct file *file, void *priv, |
@@ -389,10 +375,6 @@ static int vidioc_s_frequency(struct file *file, void *priv, | |||
389 | struct dsbr100_device *radio = video_drvdata(file); | 375 | struct dsbr100_device *radio = video_drvdata(file); |
390 | int retval; | 376 | int retval; |
391 | 377 | ||
392 | /* safety check */ | ||
393 | if (radio->removed) | ||
394 | return -EIO; | ||
395 | |||
396 | radio->curfreq = f->frequency; | 378 | radio->curfreq = f->frequency; |
397 | 379 | ||
398 | retval = dsbr100_setfreq(radio); | 380 | retval = dsbr100_setfreq(radio); |
@@ -406,10 +388,6 @@ static int vidioc_g_frequency(struct file *file, void *priv, | |||
406 | { | 388 | { |
407 | struct dsbr100_device *radio = video_drvdata(file); | 389 | struct dsbr100_device *radio = video_drvdata(file); |
408 | 390 | ||
409 | /* safety check */ | ||
410 | if (radio->removed) | ||
411 | return -EIO; | ||
412 | |||
413 | f->type = V4L2_TUNER_RADIO; | 391 | f->type = V4L2_TUNER_RADIO; |
414 | f->frequency = radio->curfreq; | 392 | f->frequency = radio->curfreq; |
415 | return 0; | 393 | return 0; |
@@ -431,10 +409,6 @@ static int vidioc_g_ctrl(struct file *file, void *priv, | |||
431 | { | 409 | { |
432 | struct dsbr100_device *radio = video_drvdata(file); | 410 | struct dsbr100_device *radio = video_drvdata(file); |
433 | 411 | ||
434 | /* safety check */ | ||
435 | if (radio->removed) | ||
436 | return -EIO; | ||
437 | |||
438 | switch (ctrl->id) { | 412 | switch (ctrl->id) { |
439 | case V4L2_CID_AUDIO_MUTE: | 413 | case V4L2_CID_AUDIO_MUTE: |
440 | ctrl->value = radio->status; | 414 | ctrl->value = radio->status; |
@@ -449,10 +423,6 @@ static int vidioc_s_ctrl(struct file *file, void *priv, | |||
449 | struct dsbr100_device *radio = video_drvdata(file); | 423 | struct dsbr100_device *radio = video_drvdata(file); |
450 | int retval; | 424 | int retval; |
451 | 425 | ||
452 | /* safety check */ | ||
453 | if (radio->removed) | ||
454 | return -EIO; | ||
455 | |||
456 | switch (ctrl->id) { | 426 | switch (ctrl->id) { |
457 | case V4L2_CID_AUDIO_MUTE: | 427 | case V4L2_CID_AUDIO_MUTE: |
458 | if (ctrl->value) { | 428 | if (ctrl->value) { |
@@ -494,17 +464,13 @@ static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i) | |||
494 | 464 | ||
495 | static int vidioc_s_input(struct file *filp, void *priv, unsigned int i) | 465 | static int vidioc_s_input(struct file *filp, void *priv, unsigned int i) |
496 | { | 466 | { |
497 | if (i != 0) | 467 | return i ? -EINVAL : 0; |
498 | return -EINVAL; | ||
499 | return 0; | ||
500 | } | 468 | } |
501 | 469 | ||
502 | static int vidioc_s_audio(struct file *file, void *priv, | 470 | static int vidioc_s_audio(struct file *file, void *priv, |
503 | struct v4l2_audio *a) | 471 | struct v4l2_audio *a) |
504 | { | 472 | { |
505 | if (a->index != 0) | 473 | return a->index ? -EINVAL : 0; |
506 | return -EINVAL; | ||
507 | return 0; | ||
508 | } | 474 | } |
509 | 475 | ||
510 | /* USB subsystem interface begins here */ | 476 | /* USB subsystem interface begins here */ |
@@ -519,14 +485,13 @@ static void usb_dsbr100_disconnect(struct usb_interface *intf) | |||
519 | { | 485 | { |
520 | struct dsbr100_device *radio = usb_get_intfdata(intf); | 486 | struct dsbr100_device *radio = usb_get_intfdata(intf); |
521 | 487 | ||
522 | usb_set_intfdata(intf, NULL); | 488 | v4l2_device_get(&radio->v4l2_dev); |
523 | |||
524 | mutex_lock(&radio->v4l2_lock); | 489 | mutex_lock(&radio->v4l2_lock); |
525 | radio->removed = 1; | 490 | usb_set_intfdata(intf, NULL); |
526 | mutex_unlock(&radio->v4l2_lock); | ||
527 | |||
528 | video_unregister_device(&radio->videodev); | 491 | video_unregister_device(&radio->videodev); |
529 | v4l2_device_disconnect(&radio->v4l2_dev); | 492 | v4l2_device_disconnect(&radio->v4l2_dev); |
493 | mutex_unlock(&radio->v4l2_lock); | ||
494 | v4l2_device_put(&radio->v4l2_dev); | ||
530 | } | 495 | } |
531 | 496 | ||
532 | 497 | ||
@@ -576,9 +541,9 @@ static int usb_dsbr100_resume(struct usb_interface *intf) | |||
576 | } | 541 | } |
577 | 542 | ||
578 | /* free data structures */ | 543 | /* free data structures */ |
579 | static void usb_dsbr100_video_device_release(struct video_device *videodev) | 544 | static void usb_dsbr100_release(struct v4l2_device *v4l2_dev) |
580 | { | 545 | { |
581 | struct dsbr100_device *radio = videodev_to_radio(videodev); | 546 | struct dsbr100_device *radio = v4l2_dev_to_radio(v4l2_dev); |
582 | 547 | ||
583 | v4l2_device_unregister(&radio->v4l2_dev); | 548 | v4l2_device_unregister(&radio->v4l2_dev); |
584 | kfree(radio->transfer_buffer); | 549 | kfree(radio->transfer_buffer); |
@@ -627,6 +592,7 @@ static int usb_dsbr100_probe(struct usb_interface *intf, | |||
627 | } | 592 | } |
628 | 593 | ||
629 | v4l2_dev = &radio->v4l2_dev; | 594 | v4l2_dev = &radio->v4l2_dev; |
595 | v4l2_dev->release = usb_dsbr100_release; | ||
630 | 596 | ||
631 | retval = v4l2_device_register(&intf->dev, v4l2_dev); | 597 | retval = v4l2_device_register(&intf->dev, v4l2_dev); |
632 | if (retval < 0) { | 598 | if (retval < 0) { |
@@ -641,10 +607,9 @@ static int usb_dsbr100_probe(struct usb_interface *intf, | |||
641 | radio->videodev.v4l2_dev = v4l2_dev; | 607 | radio->videodev.v4l2_dev = v4l2_dev; |
642 | radio->videodev.fops = &usb_dsbr100_fops; | 608 | radio->videodev.fops = &usb_dsbr100_fops; |
643 | radio->videodev.ioctl_ops = &usb_dsbr100_ioctl_ops; | 609 | radio->videodev.ioctl_ops = &usb_dsbr100_ioctl_ops; |
644 | radio->videodev.release = usb_dsbr100_video_device_release; | 610 | radio->videodev.release = video_device_release_empty; |
645 | radio->videodev.lock = &radio->v4l2_lock; | 611 | radio->videodev.lock = &radio->v4l2_lock; |
646 | 612 | ||
647 | radio->removed = 0; | ||
648 | radio->usbdev = interface_to_usbdev(intf); | 613 | radio->usbdev = interface_to_usbdev(intf); |
649 | radio->curfreq = FREQ_MIN * FREQ_MUL; | 614 | radio->curfreq = FREQ_MIN * FREQ_MUL; |
650 | radio->status = STOPPED; | 615 | radio->status = STOPPED; |