diff options
author | Mauro Carvalho Chehab <m.chehab@samsung.com> | 2014-01-12 08:21:42 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <m.chehab@samsung.com> | 2014-01-12 08:57:06 -0500 |
commit | 8b1fa5798dec77d9d2cd81751772a580474aa17f (patch) | |
tree | 398f8ad4fe2802ea60a9767a88a7c3c25ad5490b | |
parent | 966f4163751b456f526a0b0dc8e6a9814df6abd9 (diff) |
[media] em28xx-audio: return -ENODEV when the device is disconnected
If em28xx is disconnected, return -ENODEV to all PCM callbacks.
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
-rw-r--r-- | drivers/media/usb/em28xx/em28xx-audio.c | 43 |
1 files changed, 41 insertions, 2 deletions
diff --git a/drivers/media/usb/em28xx/em28xx-audio.c b/drivers/media/usb/em28xx/em28xx-audio.c index 13ba631130cd..f3e320098f79 100644 --- a/drivers/media/usb/em28xx/em28xx-audio.c +++ b/drivers/media/usb/em28xx/em28xx-audio.c | |||
@@ -90,6 +90,12 @@ static void em28xx_audio_isocirq(struct urb *urb) | |||
90 | struct snd_pcm_substream *substream; | 90 | struct snd_pcm_substream *substream; |
91 | struct snd_pcm_runtime *runtime; | 91 | struct snd_pcm_runtime *runtime; |
92 | 92 | ||
93 | if (dev->disconnected) { | ||
94 | dprintk("device disconnected while streaming. URB status=%d.\n", urb->status); | ||
95 | atomic_set(&dev->stream_started, 0); | ||
96 | return; | ||
97 | } | ||
98 | |||
93 | switch (urb->status) { | 99 | switch (urb->status) { |
94 | case 0: /* success */ | 100 | case 0: /* success */ |
95 | case -ETIMEDOUT: /* NAK */ | 101 | case -ETIMEDOUT: /* NAK */ |
@@ -248,14 +254,17 @@ static int snd_em28xx_capture_open(struct snd_pcm_substream *substream) | |||
248 | struct snd_pcm_runtime *runtime = substream->runtime; | 254 | struct snd_pcm_runtime *runtime = substream->runtime; |
249 | int ret = 0; | 255 | int ret = 0; |
250 | 256 | ||
251 | dprintk("opening device and trying to acquire exclusive lock\n"); | ||
252 | |||
253 | if (!dev) { | 257 | if (!dev) { |
254 | em28xx_err("BUG: em28xx can't find device struct." | 258 | em28xx_err("BUG: em28xx can't find device struct." |
255 | " Can't proceed with open\n"); | 259 | " Can't proceed with open\n"); |
256 | return -ENODEV; | 260 | return -ENODEV; |
257 | } | 261 | } |
258 | 262 | ||
263 | if (dev->disconnected) | ||
264 | return -ENODEV; | ||
265 | |||
266 | dprintk("opening device and trying to acquire exclusive lock\n"); | ||
267 | |||
259 | runtime->hw = snd_em28xx_hw_capture; | 268 | runtime->hw = snd_em28xx_hw_capture; |
260 | if ((dev->alt == 0 || dev->audio_ifnum) && dev->adev.users == 0) { | 269 | if ((dev->alt == 0 || dev->audio_ifnum) && dev->adev.users == 0) { |
261 | int nonblock = !!(substream->f_flags & O_NONBLOCK); | 270 | int nonblock = !!(substream->f_flags & O_NONBLOCK); |
@@ -324,6 +333,10 @@ static int snd_em28xx_hw_capture_params(struct snd_pcm_substream *substream, | |||
324 | struct snd_pcm_hw_params *hw_params) | 333 | struct snd_pcm_hw_params *hw_params) |
325 | { | 334 | { |
326 | int ret; | 335 | int ret; |
336 | struct em28xx *dev = snd_pcm_substream_chip(substream); | ||
337 | |||
338 | if (dev->disconnected) | ||
339 | return -ENODEV; | ||
327 | 340 | ||
328 | dprintk("Setting capture parameters\n"); | 341 | dprintk("Setting capture parameters\n"); |
329 | 342 | ||
@@ -363,6 +376,9 @@ static int snd_em28xx_prepare(struct snd_pcm_substream *substream) | |||
363 | { | 376 | { |
364 | struct em28xx *dev = snd_pcm_substream_chip(substream); | 377 | struct em28xx *dev = snd_pcm_substream_chip(substream); |
365 | 378 | ||
379 | if (dev->disconnected) | ||
380 | return -ENODEV; | ||
381 | |||
366 | dev->adev.hwptr_done_capture = 0; | 382 | dev->adev.hwptr_done_capture = 0; |
367 | dev->adev.capture_transfer_done = 0; | 383 | dev->adev.capture_transfer_done = 0; |
368 | 384 | ||
@@ -388,6 +404,9 @@ static int snd_em28xx_capture_trigger(struct snd_pcm_substream *substream, | |||
388 | struct em28xx *dev = snd_pcm_substream_chip(substream); | 404 | struct em28xx *dev = snd_pcm_substream_chip(substream); |
389 | int retval = 0; | 405 | int retval = 0; |
390 | 406 | ||
407 | if (dev->disconnected) | ||
408 | return -ENODEV; | ||
409 | |||
391 | switch (cmd) { | 410 | switch (cmd) { |
392 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: /* fall through */ | 411 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: /* fall through */ |
393 | case SNDRV_PCM_TRIGGER_RESUME: /* fall through */ | 412 | case SNDRV_PCM_TRIGGER_RESUME: /* fall through */ |
@@ -414,6 +433,9 @@ static snd_pcm_uframes_t snd_em28xx_capture_pointer(struct snd_pcm_substream | |||
414 | snd_pcm_uframes_t hwptr_done; | 433 | snd_pcm_uframes_t hwptr_done; |
415 | 434 | ||
416 | dev = snd_pcm_substream_chip(substream); | 435 | dev = snd_pcm_substream_chip(substream); |
436 | if (dev->disconnected) | ||
437 | return -ENODEV; | ||
438 | |||
417 | spin_lock_irqsave(&dev->adev.slock, flags); | 439 | spin_lock_irqsave(&dev->adev.slock, flags); |
418 | hwptr_done = dev->adev.hwptr_done_capture; | 440 | hwptr_done = dev->adev.hwptr_done_capture; |
419 | spin_unlock_irqrestore(&dev->adev.slock, flags); | 441 | spin_unlock_irqrestore(&dev->adev.slock, flags); |
@@ -435,6 +457,11 @@ static struct page *snd_pcm_get_vmalloc_page(struct snd_pcm_substream *subs, | |||
435 | static int em28xx_vol_info(struct snd_kcontrol *kcontrol, | 457 | static int em28xx_vol_info(struct snd_kcontrol *kcontrol, |
436 | struct snd_ctl_elem_info *info) | 458 | struct snd_ctl_elem_info *info) |
437 | { | 459 | { |
460 | struct em28xx *dev = snd_kcontrol_chip(kcontrol); | ||
461 | |||
462 | if (dev->disconnected) | ||
463 | return -ENODEV; | ||
464 | |||
438 | info->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | 465 | info->type = SNDRV_CTL_ELEM_TYPE_INTEGER; |
439 | info->count = 2; | 466 | info->count = 2; |
440 | info->value.integer.min = 0; | 467 | info->value.integer.min = 0; |
@@ -453,6 +480,9 @@ static int em28xx_vol_put(struct snd_kcontrol *kcontrol, | |||
453 | int nonblock = 0; | 480 | int nonblock = 0; |
454 | int rc; | 481 | int rc; |
455 | 482 | ||
483 | if (dev->disconnected) | ||
484 | return -ENODEV; | ||
485 | |||
456 | if (substream) | 486 | if (substream) |
457 | nonblock = !!(substream->f_flags & O_NONBLOCK); | 487 | nonblock = !!(substream->f_flags & O_NONBLOCK); |
458 | if (nonblock) { | 488 | if (nonblock) { |
@@ -488,6 +518,9 @@ static int em28xx_vol_get(struct snd_kcontrol *kcontrol, | |||
488 | int nonblock = 0; | 518 | int nonblock = 0; |
489 | int val; | 519 | int val; |
490 | 520 | ||
521 | if (dev->disconnected) | ||
522 | return -ENODEV; | ||
523 | |||
491 | if (substream) | 524 | if (substream) |
492 | nonblock = !!(substream->f_flags & O_NONBLOCK); | 525 | nonblock = !!(substream->f_flags & O_NONBLOCK); |
493 | if (nonblock) { | 526 | if (nonblock) { |
@@ -520,6 +553,9 @@ static int em28xx_vol_put_mute(struct snd_kcontrol *kcontrol, | |||
520 | int nonblock = 0; | 553 | int nonblock = 0; |
521 | int rc; | 554 | int rc; |
522 | 555 | ||
556 | if (dev->disconnected) | ||
557 | return -ENODEV; | ||
558 | |||
523 | if (substream) | 559 | if (substream) |
524 | nonblock = !!(substream->f_flags & O_NONBLOCK); | 560 | nonblock = !!(substream->f_flags & O_NONBLOCK); |
525 | if (nonblock) { | 561 | if (nonblock) { |
@@ -558,6 +594,9 @@ static int em28xx_vol_get_mute(struct snd_kcontrol *kcontrol, | |||
558 | int nonblock = 0; | 594 | int nonblock = 0; |
559 | int val; | 595 | int val; |
560 | 596 | ||
597 | if (dev->disconnected) | ||
598 | return -ENODEV; | ||
599 | |||
561 | if (substream) | 600 | if (substream) |
562 | nonblock = !!(substream->f_flags & O_NONBLOCK); | 601 | nonblock = !!(substream->f_flags & O_NONBLOCK); |
563 | if (nonblock) { | 602 | if (nonblock) { |