Commit 8b1fa579 authored by Mauro Carvalho Chehab's avatar Mauro Carvalho Chehab

[media] em28xx-audio: return -ENODEV when the device is disconnected

If em28xx is disconnected, return -ENODEV to all PCM callbacks.
Signed-off-by: default avatarMauro Carvalho Chehab <m.chehab@samsung.com>
parent 966f4163
...@@ -90,6 +90,12 @@ static void em28xx_audio_isocirq(struct urb *urb) ...@@ -90,6 +90,12 @@ static void em28xx_audio_isocirq(struct urb *urb)
struct snd_pcm_substream *substream; struct snd_pcm_substream *substream;
struct snd_pcm_runtime *runtime; struct snd_pcm_runtime *runtime;
if (dev->disconnected) {
dprintk("device disconnected while streaming. URB status=%d.\n", urb->status);
atomic_set(&dev->stream_started, 0);
return;
}
switch (urb->status) { switch (urb->status) {
case 0: /* success */ case 0: /* success */
case -ETIMEDOUT: /* NAK */ case -ETIMEDOUT: /* NAK */
...@@ -248,14 +254,17 @@ static int snd_em28xx_capture_open(struct snd_pcm_substream *substream) ...@@ -248,14 +254,17 @@ static int snd_em28xx_capture_open(struct snd_pcm_substream *substream)
struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_runtime *runtime = substream->runtime;
int ret = 0; int ret = 0;
dprintk("opening device and trying to acquire exclusive lock\n");
if (!dev) { if (!dev) {
em28xx_err("BUG: em28xx can't find device struct." em28xx_err("BUG: em28xx can't find device struct."
" Can't proceed with open\n"); " Can't proceed with open\n");
return -ENODEV; return -ENODEV;
} }
if (dev->disconnected)
return -ENODEV;
dprintk("opening device and trying to acquire exclusive lock\n");
runtime->hw = snd_em28xx_hw_capture; runtime->hw = snd_em28xx_hw_capture;
if ((dev->alt == 0 || dev->audio_ifnum) && dev->adev.users == 0) { if ((dev->alt == 0 || dev->audio_ifnum) && dev->adev.users == 0) {
int nonblock = !!(substream->f_flags & O_NONBLOCK); int nonblock = !!(substream->f_flags & O_NONBLOCK);
...@@ -324,6 +333,10 @@ static int snd_em28xx_hw_capture_params(struct snd_pcm_substream *substream, ...@@ -324,6 +333,10 @@ static int snd_em28xx_hw_capture_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *hw_params) struct snd_pcm_hw_params *hw_params)
{ {
int ret; int ret;
struct em28xx *dev = snd_pcm_substream_chip(substream);
if (dev->disconnected)
return -ENODEV;
dprintk("Setting capture parameters\n"); dprintk("Setting capture parameters\n");
...@@ -363,6 +376,9 @@ static int snd_em28xx_prepare(struct snd_pcm_substream *substream) ...@@ -363,6 +376,9 @@ static int snd_em28xx_prepare(struct snd_pcm_substream *substream)
{ {
struct em28xx *dev = snd_pcm_substream_chip(substream); struct em28xx *dev = snd_pcm_substream_chip(substream);
if (dev->disconnected)
return -ENODEV;
dev->adev.hwptr_done_capture = 0; dev->adev.hwptr_done_capture = 0;
dev->adev.capture_transfer_done = 0; dev->adev.capture_transfer_done = 0;
...@@ -388,6 +404,9 @@ static int snd_em28xx_capture_trigger(struct snd_pcm_substream *substream, ...@@ -388,6 +404,9 @@ static int snd_em28xx_capture_trigger(struct snd_pcm_substream *substream,
struct em28xx *dev = snd_pcm_substream_chip(substream); struct em28xx *dev = snd_pcm_substream_chip(substream);
int retval = 0; int retval = 0;
if (dev->disconnected)
return -ENODEV;
switch (cmd) { switch (cmd) {
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: /* fall through */ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: /* fall through */
case SNDRV_PCM_TRIGGER_RESUME: /* fall through */ 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,6 +433,9 @@ static snd_pcm_uframes_t snd_em28xx_capture_pointer(struct snd_pcm_substream
snd_pcm_uframes_t hwptr_done; snd_pcm_uframes_t hwptr_done;
dev = snd_pcm_substream_chip(substream); dev = snd_pcm_substream_chip(substream);
if (dev->disconnected)
return -ENODEV;
spin_lock_irqsave(&dev->adev.slock, flags); spin_lock_irqsave(&dev->adev.slock, flags);
hwptr_done = dev->adev.hwptr_done_capture; hwptr_done = dev->adev.hwptr_done_capture;
spin_unlock_irqrestore(&dev->adev.slock, flags); 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,6 +457,11 @@ static struct page *snd_pcm_get_vmalloc_page(struct snd_pcm_substream *subs,
static int em28xx_vol_info(struct snd_kcontrol *kcontrol, static int em28xx_vol_info(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *info) struct snd_ctl_elem_info *info)
{ {
struct em28xx *dev = snd_kcontrol_chip(kcontrol);
if (dev->disconnected)
return -ENODEV;
info->type = SNDRV_CTL_ELEM_TYPE_INTEGER; info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
info->count = 2; info->count = 2;
info->value.integer.min = 0; info->value.integer.min = 0;
...@@ -453,6 +480,9 @@ static int em28xx_vol_put(struct snd_kcontrol *kcontrol, ...@@ -453,6 +480,9 @@ static int em28xx_vol_put(struct snd_kcontrol *kcontrol,
int nonblock = 0; int nonblock = 0;
int rc; int rc;
if (dev->disconnected)
return -ENODEV;
if (substream) if (substream)
nonblock = !!(substream->f_flags & O_NONBLOCK); nonblock = !!(substream->f_flags & O_NONBLOCK);
if (nonblock) { if (nonblock) {
...@@ -488,6 +518,9 @@ static int em28xx_vol_get(struct snd_kcontrol *kcontrol, ...@@ -488,6 +518,9 @@ static int em28xx_vol_get(struct snd_kcontrol *kcontrol,
int nonblock = 0; int nonblock = 0;
int val; int val;
if (dev->disconnected)
return -ENODEV;
if (substream) if (substream)
nonblock = !!(substream->f_flags & O_NONBLOCK); nonblock = !!(substream->f_flags & O_NONBLOCK);
if (nonblock) { if (nonblock) {
...@@ -520,6 +553,9 @@ static int em28xx_vol_put_mute(struct snd_kcontrol *kcontrol, ...@@ -520,6 +553,9 @@ static int em28xx_vol_put_mute(struct snd_kcontrol *kcontrol,
int nonblock = 0; int nonblock = 0;
int rc; int rc;
if (dev->disconnected)
return -ENODEV;
if (substream) if (substream)
nonblock = !!(substream->f_flags & O_NONBLOCK); nonblock = !!(substream->f_flags & O_NONBLOCK);
if (nonblock) { if (nonblock) {
...@@ -558,6 +594,9 @@ static int em28xx_vol_get_mute(struct snd_kcontrol *kcontrol, ...@@ -558,6 +594,9 @@ static int em28xx_vol_get_mute(struct snd_kcontrol *kcontrol,
int nonblock = 0; int nonblock = 0;
int val; int val;
if (dev->disconnected)
return -ENODEV;
if (substream) if (substream)
nonblock = !!(substream->f_flags & O_NONBLOCK); nonblock = !!(substream->f_flags & O_NONBLOCK);
if (nonblock) { if (nonblock) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment