提交 990862a2 编写于 作者: M Mauro Carvalho Chehab

[media] cx231xx: fix device disconnect checks

The driver were using DEV_MISCONFIGURED on some places, and
DEV_DISCONNECTED on others. In a matter of fact, DEV_MISCONFIGURED
were set only during the usb disconnect callback, with
was confusing.

Also, the alsa driver never checks if the device is present,
before doing some dangerous things.

Remove DEV_MISCONFIGURED, replacing it by DEV_DISCONNECTED.

Also, fixes the other usecases for DEV_DISCONNECTED.
Signed-off-by: NMauro Carvalho Chehab <mchehab@redhat.com>
上级 db702a7a
...@@ -111,6 +111,9 @@ static void cx231xx_audio_isocirq(struct urb *urb) ...@@ -111,6 +111,9 @@ static void cx231xx_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->state & DEV_DISCONNECTED)
return;
switch (urb->status) { switch (urb->status) {
case 0: /* success */ case 0: /* success */
case -ETIMEDOUT: /* NAK */ case -ETIMEDOUT: /* NAK */
...@@ -196,6 +199,9 @@ static void cx231xx_audio_bulkirq(struct urb *urb) ...@@ -196,6 +199,9 @@ static void cx231xx_audio_bulkirq(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->state & DEV_DISCONNECTED)
return;
switch (urb->status) { switch (urb->status) {
case 0: /* success */ case 0: /* success */
case -ETIMEDOUT: /* NAK */ case -ETIMEDOUT: /* NAK */
...@@ -273,6 +279,9 @@ static int cx231xx_init_audio_isoc(struct cx231xx *dev) ...@@ -273,6 +279,9 @@ static int cx231xx_init_audio_isoc(struct cx231xx *dev)
cx231xx_info("%s: Starting ISO AUDIO transfers\n", __func__); cx231xx_info("%s: Starting ISO AUDIO transfers\n", __func__);
if (dev->state & DEV_DISCONNECTED)
return -ENODEV;
sb_size = CX231XX_ISO_NUM_AUDIO_PACKETS * dev->adev.max_pkt_size; sb_size = CX231XX_ISO_NUM_AUDIO_PACKETS * dev->adev.max_pkt_size;
for (i = 0; i < CX231XX_AUDIO_BUFS; i++) { for (i = 0; i < CX231XX_AUDIO_BUFS; i++) {
...@@ -331,6 +340,9 @@ static int cx231xx_init_audio_bulk(struct cx231xx *dev) ...@@ -331,6 +340,9 @@ static int cx231xx_init_audio_bulk(struct cx231xx *dev)
cx231xx_info("%s: Starting BULK AUDIO transfers\n", __func__); cx231xx_info("%s: Starting BULK AUDIO transfers\n", __func__);
if (dev->state & DEV_DISCONNECTED)
return -ENODEV;
sb_size = CX231XX_NUM_AUDIO_PACKETS * dev->adev.max_pkt_size; sb_size = CX231XX_NUM_AUDIO_PACKETS * dev->adev.max_pkt_size;
for (i = 0; i < CX231XX_AUDIO_BUFS; i++) { for (i = 0; i < CX231XX_AUDIO_BUFS; i++) {
...@@ -432,6 +444,11 @@ static int snd_cx231xx_capture_open(struct snd_pcm_substream *substream) ...@@ -432,6 +444,11 @@ static int snd_cx231xx_capture_open(struct snd_pcm_substream *substream)
return -ENODEV; return -ENODEV;
} }
if (dev->state & DEV_DISCONNECTED) {
cx231xx_errdev("Can't open. the device was removed.\n");
return -ENODEV;
}
/* Sets volume, mute, etc */ /* Sets volume, mute, etc */
dev->mute = 0; dev->mute = 0;
...@@ -571,6 +588,9 @@ static int snd_cx231xx_capture_trigger(struct snd_pcm_substream *substream, ...@@ -571,6 +588,9 @@ static int snd_cx231xx_capture_trigger(struct snd_pcm_substream *substream,
struct cx231xx *dev = snd_pcm_substream_chip(substream); struct cx231xx *dev = snd_pcm_substream_chip(substream);
int retval; int retval;
if (dev->state & DEV_DISCONNECTED)
return -ENODEV;
spin_lock(&dev->adev.slock); spin_lock(&dev->adev.slock);
switch (cmd) { switch (cmd) {
case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_START:
......
...@@ -1337,6 +1337,8 @@ static void cx231xx_usb_disconnect(struct usb_interface *interface) ...@@ -1337,6 +1337,8 @@ static void cx231xx_usb_disconnect(struct usb_interface *interface)
if (!dev->udev) if (!dev->udev)
return; return;
dev->state |= DEV_DISCONNECTED;
flush_request_modules(dev); flush_request_modules(dev);
/* wait until all current v4l2 io is finished then deallocate /* wait until all current v4l2 io is finished then deallocate
...@@ -1354,16 +1356,13 @@ static void cx231xx_usb_disconnect(struct usb_interface *interface) ...@@ -1354,16 +1356,13 @@ static void cx231xx_usb_disconnect(struct usb_interface *interface)
/* Even having users, it is safe to remove the RC i2c driver */ /* Even having users, it is safe to remove the RC i2c driver */
cx231xx_ir_exit(dev); cx231xx_ir_exit(dev);
dev->state |= DEV_MISCONFIGURED;
if (dev->USE_ISO) if (dev->USE_ISO)
cx231xx_uninit_isoc(dev); cx231xx_uninit_isoc(dev);
else else
cx231xx_uninit_bulk(dev); cx231xx_uninit_bulk(dev);
dev->state |= DEV_DISCONNECTED;
wake_up_interruptible(&dev->wait_frame); wake_up_interruptible(&dev->wait_frame);
wake_up_interruptible(&dev->wait_stream); wake_up_interruptible(&dev->wait_stream);
} else { } else {
dev->state |= DEV_DISCONNECTED;
} }
cx231xx_close_extension(dev); cx231xx_close_extension(dev);
......
...@@ -196,7 +196,7 @@ static inline int dvb_isoc_copy(struct cx231xx *dev, struct urb *urb) ...@@ -196,7 +196,7 @@ static inline int dvb_isoc_copy(struct cx231xx *dev, struct urb *urb)
if (!dev) if (!dev)
return 0; return 0;
if ((dev->state & DEV_DISCONNECTED) || (dev->state & DEV_MISCONFIGURED)) if (dev->state & DEV_DISCONNECTED)
return 0; return 0;
if (urb->status < 0) { if (urb->status < 0) {
...@@ -228,7 +228,7 @@ static inline int dvb_bulk_copy(struct cx231xx *dev, struct urb *urb) ...@@ -228,7 +228,7 @@ static inline int dvb_bulk_copy(struct cx231xx *dev, struct urb *urb)
if (!dev) if (!dev)
return 0; return 0;
if ((dev->state & DEV_DISCONNECTED) || (dev->state & DEV_MISCONFIGURED)) if (dev->state & DEV_DISCONNECTED)
return 0; return 0;
if (urb->status < 0) { if (urb->status < 0) {
......
...@@ -93,7 +93,7 @@ static inline int cx231xx_isoc_vbi_copy(struct cx231xx *dev, struct urb *urb) ...@@ -93,7 +93,7 @@ static inline int cx231xx_isoc_vbi_copy(struct cx231xx *dev, struct urb *urb)
if (!dev) if (!dev)
return 0; return 0;
if ((dev->state & DEV_DISCONNECTED) || (dev->state & DEV_MISCONFIGURED)) if (dev->state & DEV_DISCONNECTED)
return 0; return 0;
if (urb->status < 0) { if (urb->status < 0) {
......
...@@ -337,7 +337,7 @@ static inline int cx231xx_isoc_copy(struct cx231xx *dev, struct urb *urb) ...@@ -337,7 +337,7 @@ static inline int cx231xx_isoc_copy(struct cx231xx *dev, struct urb *urb)
if (!dev) if (!dev)
return 0; return 0;
if ((dev->state & DEV_DISCONNECTED) || (dev->state & DEV_MISCONFIGURED)) if (dev->state & DEV_DISCONNECTED)
return 0; return 0;
if (urb->status < 0) { if (urb->status < 0) {
...@@ -440,7 +440,7 @@ static inline int cx231xx_bulk_copy(struct cx231xx *dev, struct urb *urb) ...@@ -440,7 +440,7 @@ static inline int cx231xx_bulk_copy(struct cx231xx *dev, struct urb *urb)
if (!dev) if (!dev)
return 0; return 0;
if ((dev->state & DEV_DISCONNECTED) || (dev->state & DEV_MISCONFIGURED)) if (dev->state & DEV_DISCONNECTED)
return 0; return 0;
if (urb->status < 0) { if (urb->status < 0) {
...@@ -1000,12 +1000,6 @@ static int check_dev(struct cx231xx *dev) ...@@ -1000,12 +1000,6 @@ static int check_dev(struct cx231xx *dev)
cx231xx_errdev("v4l2 ioctl: device not present\n"); cx231xx_errdev("v4l2 ioctl: device not present\n");
return -ENODEV; return -ENODEV;
} }
if (dev->state & DEV_MISCONFIGURED) {
cx231xx_errdev("v4l2 ioctl: device is misconfigured; "
"close and open it again\n");
return -EIO;
}
return 0; return 0;
} }
...@@ -2347,7 +2341,8 @@ static int cx231xx_v4l2_close(struct file *filp) ...@@ -2347,7 +2341,8 @@ static int cx231xx_v4l2_close(struct file *filp)
return 0; return 0;
} }
if (dev->users == 1) { dev->users--;
if (!dev->users) {
videobuf_stop(&fh->vb_vidq); videobuf_stop(&fh->vb_vidq);
videobuf_mmap_free(&fh->vb_vidq); videobuf_mmap_free(&fh->vb_vidq);
...@@ -2374,7 +2369,6 @@ static int cx231xx_v4l2_close(struct file *filp) ...@@ -2374,7 +2369,6 @@ static int cx231xx_v4l2_close(struct file *filp)
cx231xx_set_alt_setting(dev, INDEX_VIDEO, 0); cx231xx_set_alt_setting(dev, INDEX_VIDEO, 0);
} }
kfree(fh); kfree(fh);
dev->users--;
wake_up_interruptible_nr(&dev->open, 1); wake_up_interruptible_nr(&dev->open, 1);
return 0; return 0;
} }
......
...@@ -377,7 +377,6 @@ struct cx231xx_board { ...@@ -377,7 +377,6 @@ struct cx231xx_board {
enum cx231xx_dev_state { enum cx231xx_dev_state {
DEV_INITIALIZED = 0x01, DEV_INITIALIZED = 0x01,
DEV_DISCONNECTED = 0x02, DEV_DISCONNECTED = 0x02,
DEV_MISCONFIGURED = 0x04,
}; };
enum AFE_MODE { enum AFE_MODE {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册