]> Pileus Git - ~andy/linux/commitdiff
[media] cx231xx: fix device disconnect checks
authorMauro Carvalho Chehab <mchehab@redhat.com>
Tue, 10 Jan 2012 11:48:50 +0000 (09:48 -0200)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Wed, 11 Jan 2012 00:35:31 +0000 (22:35 -0200)
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: Mauro Carvalho Chehab <mchehab@redhat.com>
drivers/media/video/cx231xx/cx231xx-audio.c
drivers/media/video/cx231xx/cx231xx-cards.c
drivers/media/video/cx231xx/cx231xx-dvb.c
drivers/media/video/cx231xx/cx231xx-vbi.c
drivers/media/video/cx231xx/cx231xx-video.c
drivers/media/video/cx231xx/cx231xx.h

index 30d13c15739a7d32a3a66636f90cb9aa4edde2df..e5742a0e19a0d1295803e970a5c31ca72ece4f9f 100644 (file)
@@ -111,6 +111,9 @@ static void cx231xx_audio_isocirq(struct urb *urb)
        struct snd_pcm_substream *substream;
        struct snd_pcm_runtime *runtime;
 
+       if (dev->state & DEV_DISCONNECTED)
+               return;
+
        switch (urb->status) {
        case 0:         /* success */
        case -ETIMEDOUT:        /* NAK */
@@ -196,6 +199,9 @@ static void cx231xx_audio_bulkirq(struct urb *urb)
        struct snd_pcm_substream *substream;
        struct snd_pcm_runtime *runtime;
 
+       if (dev->state & DEV_DISCONNECTED)
+               return;
+
        switch (urb->status) {
        case 0:         /* success */
        case -ETIMEDOUT:        /* NAK */
@@ -273,6 +279,9 @@ static int cx231xx_init_audio_isoc(struct cx231xx *dev)
 
        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;
 
        for (i = 0; i < CX231XX_AUDIO_BUFS; i++) {
@@ -331,6 +340,9 @@ static int cx231xx_init_audio_bulk(struct cx231xx *dev)
 
        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;
 
        for (i = 0; i < CX231XX_AUDIO_BUFS; i++) {
@@ -432,6 +444,11 @@ static int snd_cx231xx_capture_open(struct snd_pcm_substream *substream)
                return -ENODEV;
        }
 
+       if (dev->state & DEV_DISCONNECTED) {
+               cx231xx_errdev("Can't open. the device was removed.\n");
+               return -ENODEV;
+       }
+
        /* Sets volume, mute, etc */
        dev->mute = 0;
 
@@ -571,6 +588,9 @@ static int snd_cx231xx_capture_trigger(struct snd_pcm_substream *substream,
        struct cx231xx *dev = snd_pcm_substream_chip(substream);
        int retval;
 
+       if (dev->state & DEV_DISCONNECTED)
+               return -ENODEV;
+
        spin_lock(&dev->adev.slock);
        switch (cmd) {
        case SNDRV_PCM_TRIGGER_START:
index 1f2fbbfebc763ece0c375505aa6162d1561af2c6..7577e6e50136f7f7b5545ba1509fa0370b6bba11 100644 (file)
@@ -1337,6 +1337,8 @@ static void cx231xx_usb_disconnect(struct usb_interface *interface)
        if (!dev->udev)
                return;
 
+       dev->state |= DEV_DISCONNECTED;
+
        flush_request_modules(dev);
 
        /* wait until all current v4l2 io is finished then deallocate
@@ -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 */
                cx231xx_ir_exit(dev);
 
-               dev->state |= DEV_MISCONFIGURED;
                if (dev->USE_ISO)
                        cx231xx_uninit_isoc(dev);
                else
                        cx231xx_uninit_bulk(dev);
-               dev->state |= DEV_DISCONNECTED;
                wake_up_interruptible(&dev->wait_frame);
                wake_up_interruptible(&dev->wait_stream);
        } else {
-               dev->state |= DEV_DISCONNECTED;
        }
 
        cx231xx_close_extension(dev);
index da9a4a0aab7923c96086e7bfc68115911da7e40d..7c4e360ba9bcba325177a881e7d0f9ee052c4fce 100644 (file)
@@ -196,7 +196,7 @@ static inline int dvb_isoc_copy(struct cx231xx *dev, struct urb *urb)
        if (!dev)
                return 0;
 
-       if ((dev->state & DEV_DISCONNECTED) || (dev->state & DEV_MISCONFIGURED))
+       if (dev->state & DEV_DISCONNECTED)
                return 0;
 
        if (urb->status < 0) {
@@ -228,7 +228,7 @@ static inline int dvb_bulk_copy(struct cx231xx *dev, struct urb *urb)
        if (!dev)
                return 0;
 
-       if ((dev->state & DEV_DISCONNECTED) || (dev->state & DEV_MISCONFIGURED))
+       if (dev->state & DEV_DISCONNECTED)
                return 0;
 
        if (urb->status < 0) {
index 1c7a4daafecf56f2dc382ebc60b291f197dbbb45..9c5967e1d0c6bcb893e74c0a32588f78a8d03821 100644 (file)
@@ -93,7 +93,7 @@ static inline int cx231xx_isoc_vbi_copy(struct cx231xx *dev, struct urb *urb)
        if (!dev)
                return 0;
 
-       if ((dev->state & DEV_DISCONNECTED) || (dev->state & DEV_MISCONFIGURED))
+       if (dev->state & DEV_DISCONNECTED)
                return 0;
 
        if (urb->status < 0) {
index 6e81f970dc7d8e35d48975e141c5e75fbfdf878f..829a41b0c9ef5c77edc7095164debac2120f284c 100644 (file)
@@ -337,7 +337,7 @@ static inline int cx231xx_isoc_copy(struct cx231xx *dev, struct urb *urb)
        if (!dev)
                return 0;
 
-       if ((dev->state & DEV_DISCONNECTED) || (dev->state & DEV_MISCONFIGURED))
+       if (dev->state & DEV_DISCONNECTED)
                return 0;
 
        if (urb->status < 0) {
@@ -440,7 +440,7 @@ static inline int cx231xx_bulk_copy(struct cx231xx *dev, struct urb *urb)
        if (!dev)
                return 0;
 
-       if ((dev->state & DEV_DISCONNECTED) || (dev->state & DEV_MISCONFIGURED))
+       if (dev->state & DEV_DISCONNECTED)
                return 0;
 
        if (urb->status < 0) {
@@ -1000,12 +1000,6 @@ static int check_dev(struct cx231xx *dev)
                cx231xx_errdev("v4l2 ioctl: device not present\n");
                return -ENODEV;
        }
-
-       if (dev->state & DEV_MISCONFIGURED) {
-               cx231xx_errdev("v4l2 ioctl: device is misconfigured; "
-                              "close and open it again\n");
-               return -EIO;
-       }
        return 0;
 }
 
@@ -2347,7 +2341,8 @@ static int cx231xx_v4l2_close(struct file *filp)
                        return 0;
                }
 
-       if (dev->users == 1) {
+       dev->users--;
+       if (!dev->users) {
                videobuf_stop(&fh->vb_vidq);
                videobuf_mmap_free(&fh->vb_vidq);
 
@@ -2374,7 +2369,6 @@ static int cx231xx_v4l2_close(struct file *filp)
                cx231xx_set_alt_setting(dev, INDEX_VIDEO, 0);
        }
        kfree(fh);
-       dev->users--;
        wake_up_interruptible_nr(&dev->open, 1);
        return 0;
 }
index 5d498a4112d7aee84ded8aede93f9673d3200d45..e17447554a0d6eed2de8deb94360019e20114cea 100644 (file)
@@ -377,7 +377,6 @@ struct cx231xx_board {
 enum cx231xx_dev_state {
        DEV_INITIALIZED = 0x01,
        DEV_DISCONNECTED = 0x02,
-       DEV_MISCONFIGURED = 0x04,
 };
 
 enum AFE_MODE {