Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab...
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 18 Jan 2010 22:06:52 +0000 (14:06 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 18 Jan 2010 22:06:52 +0000 (14:06 -0800)
* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6: (23 commits)
  V4L/DVB (13966): DVB-T regression fix for saa7134 cards
  V4L/DVB (13955): cx25821: fix double unlock in medusa_video_init()
  MAINTAINERS: ivtv-devel is moderated
  MAINTAINERS: Andy Walls is the new ivtv maintainer
  V4L/DVB (13941): rj54n1cb0c: remove compiler warning
  V4L/DVB sh_mobile_ceu: don't check platform_get_irq's return value against zero
  V4L/DVB mx1_camera: don't check platform_get_irq's return value against zero
  V4L/DVB (13934): tda8290: Fix FM radio easy programming standard selection for TDA8295
  V4L/DVB (13900): gspca - sunplus: Fix bridge exchanges.
  V4L/DVB (13887): tda8290: add autodetection support for TDA8295c2
  V4L/DVB (13882): gspca - stv06xx-vv6410: Ensure register STV_SCAN_RATE is zero
  V4L/DVB (13880): gspca - m5602-s5k4aa: Add vflip quirk for the Amilo Xi 2428
  V4L/DVB (13875): gspca - vc032x: Fix a possible crash with the vc0321 bridge.
  V4L/DVB (13868): gspca - sn9c20x: Fix test of unsigned.
  V4L/DVB (13858): ir-keytable: use the right header
  feature-removal-schedule: Add v4l1 drivers obsoleted by gspca sub drivers
  V4L/DVB (13622): gspca - ov534: Fix a compilation warning.
  V4L/DVB (13834): dib8000: fix compilation if !DVB_DIB8000
  V4L/DVB (13831): uvcvideo: Fix oops caused by a race condition in buffer dequeuing
  V4L/DVB (13829): uvcvideo: Fix alternate setting selection in isochronous mode
  ...

23 files changed:
Documentation/feature-removal-schedule.txt
MAINTAINERS
drivers/media/IR/ir-keytable.c
drivers/media/common/tuners/tda8290.c
drivers/media/dvb/frontends/dib8000.h
drivers/media/dvb/frontends/lgdt3305.h
drivers/media/video/gspca/gspca.c
drivers/media/video/gspca/m5602/m5602_s5k4aa.c
drivers/media/video/gspca/ov534.c
drivers/media/video/gspca/sn9c20x.c
drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h
drivers/media/video/gspca/sunplus.c
drivers/media/video/gspca/vc032x.c
drivers/media/video/mx1_camera.c
drivers/media/video/rj54n1cb0c.c
drivers/media/video/saa7134/saa7134-core.c
drivers/media/video/saa7134/saa7134-ts.c
drivers/media/video/sh_mobile_ceu_camera.c
drivers/media/video/uvc/uvc_ctrl.c
drivers/media/video/uvc/uvc_queue.c
drivers/media/video/uvc/uvc_video.c
drivers/media/video/uvc/uvcvideo.h
drivers/staging/cx25821/cx25821-medusa-video.c

index 870d190fe6178676067b4f2adadbfd07b56beacb..0a46833c1b764dfc4e983edfb55030e938e40948 100644 (file)
@@ -493,3 +493,52 @@ Why:       These two features use non-standard interfaces. There are the
 Who:   Corentin Chary <corentin.chary@gmail.com>
 
 ----------------------------
+
+What:  usbvideo quickcam_messenger driver
+When:  2.6.35
+Files: drivers/media/video/usbvideo/quickcam_messenger.[ch]
+Why:   obsolete v4l1 driver replaced by gspca_stv06xx
+Who:   Hans de Goede <hdegoede@redhat.com>
+
+----------------------------
+
+What:  ov511 v4l1 driver
+When:  2.6.35
+Files: drivers/media/video/ov511.[ch]
+Why:   obsolete v4l1 driver replaced by gspca_ov519
+Who:   Hans de Goede <hdegoede@redhat.com>
+
+----------------------------
+
+What:  w9968cf v4l1 driver
+When:  2.6.35
+Files: drivers/media/video/w9968cf*.[ch]
+Why:   obsolete v4l1 driver replaced by gspca_ov519
+Who:   Hans de Goede <hdegoede@redhat.com>
+
+----------------------------
+
+What:  ovcamchip sensor framework
+When:  2.6.35
+Files: drivers/media/video/ovcamchip/*
+Why:   Only used by obsoleted v4l1 drivers
+Who:   Hans de Goede <hdegoede@redhat.com>
+
+----------------------------
+
+What:  stv680 v4l1 driver
+When:  2.6.35
+Files: drivers/media/video/stv680.[ch]
+Why:   obsolete v4l1 driver replaced by gspca_stv0680
+Who:   Hans de Goede <hdegoede@redhat.com>
+
+----------------------------
+
+What:  zc0301 v4l driver
+When:  2.6.35
+Files: drivers/media/video/zc0301/*
+Why:   Duplicate functionality with the gspca_zc3xx driver, zc0301 only
+       supports 2 USB-ID's (because it only supports a limited set of
+       sensors) wich are also supported by the gspca_zc3xx driver
+       (which supports 53 USB-ID's in total)
+Who:   Hans de Goede <hdegoede@redhat.com>
index 3f591629e953af70aede2d977529008fbb61c10b..1858646b52e345246ef2d603279a92bff520080e 100644 (file)
@@ -1637,9 +1637,8 @@ S:        Maintained
 F:     sound/pci/cs5535audio/
 
 CX18 VIDEO4LINUX DRIVER
-M:     Hans Verkuil <hverkuil@xs4all.nl>
 M:     Andy Walls <awalls@radix.net>
-L:     ivtv-devel@ivtvdriver.org
+L:     ivtv-devel@ivtvdriver.org (moderated for non-subscribers)
 L:     linux-media@vger.kernel.org
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
 W:     http://linuxtv.org
@@ -3011,8 +3010,8 @@ S:        Maintained
 F:     drivers/isdn/hardware/eicon/
 
 IVTV VIDEO4LINUX DRIVER
-M:     Hans Verkuil <hverkuil@xs4all.nl>
-L:     ivtv-devel@ivtvdriver.org
+M:     Andy Walls <awalls@radix.net>
+L:     ivtv-devel@ivtvdriver.org (moderated for non-subscribers)
 L:     linux-media@vger.kernel.org
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
 W:     http://www.ivtvdriver.org
index bff7a5356037bc6172cd21e95605572a92ed34b0..b521ed9d6e2e3e75b37507ab1e3c74f516d79fab 100644 (file)
@@ -13,7 +13,7 @@
  */
 
 
-#include <linux/usb/input.h>
+#include <linux/input.h>
 #include <media/ir-common.h>
 
 #define IR_TAB_MIN_SIZE        32
index c190b0dedee47851ada5e30e25d93031c3a586a3..2833137fa8195bdc41c8337267bcbee81168082a 100644 (file)
@@ -144,7 +144,8 @@ static void set_audio(struct dvb_frontend *fe,
        }
 
        if (params->mode == V4L2_TUNER_RADIO) {
-               priv->tda8290_easy_mode = 0x01;         /* Start with MN values */
+               /* Set TDA8295 to FM radio; Start TDA8290 with MN values */
+               priv->tda8290_easy_mode = (priv->ver & TDA8295) ? 0x80 : 0x01;
                tuner_dbg("setting to radio FM\n");
        } else {
                tuner_dbg("setting tda829x to system %s\n", mode);
@@ -672,16 +673,19 @@ static int tda8290_probe(struct tuner_i2c_props *i2c_props)
 static int tda8295_probe(struct tuner_i2c_props *i2c_props)
 {
 #define TDA8295_ID 0x8a
+#define TDA8295C2_ID 0x8b
        unsigned char tda8295_id[] = { 0x2f, 0x00 };
 
        /* detect tda8295 */
        tuner_i2c_xfer_send(i2c_props, &tda8295_id[0], 1);
        tuner_i2c_xfer_recv(i2c_props, &tda8295_id[1], 1);
 
-       if (tda8295_id[1] == TDA8295_ID) {
+       if ((tda8295_id[1] & 0xfe) == TDA8295_ID) {
                if (debug)
-                       printk(KERN_DEBUG "%s: tda8295 detected @ %d-%04x\n",
-                              __func__, i2c_adapter_id(i2c_props->adap),
+                       printk(KERN_DEBUG "%s: %s detected @ %d-%04x\n",
+                              __func__, (tda8295_id[1] == TDA8295_ID) ?
+                              "tda8295c1" : "tda8295c2",
+                              i2c_adapter_id(i2c_props->adap),
                               i2c_props->addr);
                return 0;
        }
index d99619ae983ce4ea9528ba273381c950b5a6e5ff..b1ee20799639e5785b045fb595ed57d05d097347 100644 (file)
@@ -100,7 +100,7 @@ static inline int dib8000_set_tune_state(struct dvb_frontend *fe, enum frontend_
 static inline enum frontend_tune_state dib8000_get_tune_state(struct dvb_frontend *fe)
 {
        printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-    return CT_SHUTDOWN,
+       return CT_SHUTDOWN;
 }
 static inline void dib8000_pwm_agc_reset(struct dvb_frontend *fe)
 {
index 4fa6e52d1fe8a23ee428d9fddc400d6a733d2362..9cb11c9cae53eb4ad097165b9065e589bc5a3325 100644 (file)
@@ -54,13 +54,13 @@ struct lgdt3305_config {
        u16 usref_qam256; /* default: 0x2a80 */
 
        /* disable i2c repeater - 0:repeater enabled 1:repeater disabled */
-       int deny_i2c_rptr:1;
+       unsigned int deny_i2c_rptr:1;
 
        /* spectral inversion - 0:disabled 1:enabled */
-       int spectral_inversion:1;
+       unsigned int spectral_inversion:1;
 
        /* use RF AGC loop - 0:disabled 1:enabled */
-       int rf_agc_loop:1;
+       unsigned int rf_agc_loop:1;
 
        enum lgdt3305_mpeg_mode mpeg_mode;
        enum lgdt3305_tp_clock_edge tpclk_edge;
index e930a67d526b2f2a04e94da7c46ac5c3624c78a2..bd6214d4ab3beac8e9352b45a42ed80516c07346 100644 (file)
@@ -1815,6 +1815,8 @@ static int vidioc_qbuf(struct file *file, void *priv,
        /* put the buffer in the 'queued' queue */
        i = gspca_dev->fr_q;
        gspca_dev->fr_queue[i] = index;
+       if (gspca_dev->fr_i == i)
+               gspca_dev->cur_frame = frame;
        gspca_dev->fr_q = (i + 1) % gspca_dev->nframes;
        PDEBUG(D_FRAM, "qbuf q:%d i:%d o:%d",
                gspca_dev->fr_q,
index aa2f3c7e2cb5467c3cb68879c4b4d7006427b804..1b536f7d30cf599f7620d52585aeb2742660f1dc 100644 (file)
@@ -47,6 +47,12 @@ static
                        DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
                        DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Xa 2528")
                }
+       }, {
+               .ident = "Fujitsu-Siemens Amilo Xi 2428",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Xi 2428")
+               }
        }, {
                .ident = "Fujitsu-Siemens Amilo Xi 2528",
                .matches = {
index 4dbb882c83dcb2c6cb3ebda9536d79a4d908b490..0a6b8f07a69d2898cca1f3fa3ae84ae2da7e1ab4 100644 (file)
@@ -1533,7 +1533,7 @@ static void setexposure_96(struct gspca_dev *gspca_dev)
 static void setsharpness_96(struct gspca_dev *gspca_dev)
 {
        struct sd *sd = (struct sd *) gspca_dev;
-       u8 val;
+       s8 val;
 
        val = sd->sharpness;
        if (val < 0) {                          /* auto */
index 4cff8035614f881445a0770e92310cdaed21bc78..0ca1c06652b1443b8ccd687794f75d364a5c7ee7 100644 (file)
@@ -2319,7 +2319,7 @@ static void do_autogain(struct gspca_dev *gspca_dev, u16 avg_lum)
                }
        }
        if (avg_lum > MAX_AVG_LUM) {
-               if (sd->gain - 1 >= 0) {
+               if (sd->gain >= 1) {
                        sd->gain--;
                        set_gain(gspca_dev);
                }
index 487d40555343f7581148c4656829f282d88bff0b..96c61926d3728f99b11723197458dcf2814ff16d 100644 (file)
@@ -228,6 +228,7 @@ static const struct stv_init stv_bridge_init[] = {
        /* This reg is written twice. Some kind of reset? */
        {NULL,  0x1620, 0x80},
        {NULL,  0x1620, 0x00},
+       {NULL,  0x1443, 0x00},
        {NULL,  0x1423, 0x04},
        {x1500, 0x1500, ARRAY_SIZE(x1500)},
        {x1536, 0x1536, ARRAY_SIZE(x1536)},
index 716df6b15fc5a199105c8afa3584cb1eed29cbc1..306b7d75b4aa2af394e47294dd19974e10346cf0 100644 (file)
@@ -709,7 +709,7 @@ static void spca504B_SetSizeType(struct gspca_dev *gspca_dev)
                spca504B_PollingDataReady(gspca_dev);
 
                /* Init the cam width height with some values get on init ? */
-               reg_w_riv(gspca_dev, 0x31, 0, 0x04);
+               reg_w_riv(gspca_dev, 0x31, 0x0004, 0x00);
                spca504B_WaitCmdStatus(gspca_dev);
                spca504B_PollingDataReady(gspca_dev);
                break;
@@ -807,14 +807,14 @@ static void init_ctl_reg(struct gspca_dev *gspca_dev)
        default:
 /*     case BRIDGE_SPCA533: */
 /*     case BRIDGE_SPCA504B: */
-               reg_w_riv(gspca_dev, 0, 0x00, 0x21ad);  /* hue */
-               reg_w_riv(gspca_dev, 0, 0x01, 0x21ac);  /* sat/hue */
-               reg_w_riv(gspca_dev, 0, 0x00, 0x21a3);  /* gamma */
+               reg_w_riv(gspca_dev, 0, 0x21ad, 0x00);  /* hue */
+               reg_w_riv(gspca_dev, 0, 0x21ac, 0x01);  /* sat/hue */
+               reg_w_riv(gspca_dev, 0, 0x21a3, 0x00);  /* gamma */
                break;
        case BRIDGE_SPCA536:
-               reg_w_riv(gspca_dev, 0, 0x40, 0x20f5);
-               reg_w_riv(gspca_dev, 0, 0x01, 0x20f4);
-               reg_w_riv(gspca_dev, 0, 0x00, 0x2089);
+               reg_w_riv(gspca_dev, 0, 0x20f5, 0x40);
+               reg_w_riv(gspca_dev, 0, 0x20f4, 0x01);
+               reg_w_riv(gspca_dev, 0, 0x2089, 0x00);
                break;
        }
        if (pollreg)
@@ -887,11 +887,11 @@ static int sd_init(struct gspca_dev *gspca_dev)
        switch (sd->bridge) {
        case BRIDGE_SPCA504B:
                reg_w_riv(gspca_dev, 0x1d, 0x00, 0);
-               reg_w_riv(gspca_dev, 0, 0x01, 0x2306);
-               reg_w_riv(gspca_dev, 0, 0x00, 0x0d04);
-               reg_w_riv(gspca_dev, 0, 0x00, 0x2000);
-               reg_w_riv(gspca_dev, 0, 0x13, 0x2301);
-               reg_w_riv(gspca_dev, 0, 0x00, 0x2306);
+               reg_w_riv(gspca_dev, 0x00, 0x2306, 0x01);
+               reg_w_riv(gspca_dev, 0x00, 0x0d04, 0x00);
+               reg_w_riv(gspca_dev, 0x00, 0x2000, 0x00);
+               reg_w_riv(gspca_dev, 0x00, 0x2301, 0x13);
+               reg_w_riv(gspca_dev, 0x00, 0x2306, 0x00);
                /* fall thru */
        case BRIDGE_SPCA533:
                spca504B_PollingDataReady(gspca_dev);
@@ -1000,7 +1000,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
                        spca504B_WaitCmdStatus(gspca_dev);
                        break;
                default:
-                       reg_w_riv(gspca_dev, 0x31, 0, 0x04);
+                       reg_w_riv(gspca_dev, 0x31, 0x0004, 0x00);
                        spca504B_WaitCmdStatus(gspca_dev);
                        spca504B_PollingDataReady(gspca_dev);
                        break;
index c090efcd80454e605e3935cbd3ef2231300e5dee..71921c8784246c9eddb993daaf87eafbfd065a09 100644 (file)
@@ -3009,6 +3009,10 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
                int l;
 
                frame = gspca_get_i_frame(gspca_dev);
+               if (frame == NULL) {
+                       gspca_dev->last_packet_type = DISCARD_PACKET;
+                       return;
+               }
                l = frame->data_end - frame->data;
                if (len > frame->v4l2_buf.length - l)
                        len = frame->v4l2_buf.length - l;
index 2ba14fb5b0311f0f86a42b2148b3fe30e0e7805e..c167cc3de4928cee1f0a28b1dbade61320d1bcf7 100644 (file)
@@ -718,7 +718,7 @@ static int __init mx1_camera_probe(struct platform_device *pdev)
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        irq = platform_get_irq(pdev, 0);
-       if (!res || !irq) {
+       if (!res || (int)irq <= 0) {
                err = -ENODEV;
                goto exit;
        }
index 7e42989ce0e47b8155260c3705ecb58cb21f6604..805226e0d9c1204c8734016612b10a433df23f41 100644 (file)
@@ -563,7 +563,7 @@ static int rj54n1_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
        struct i2c_client *client = sd->priv;
        struct rj54n1 *rj54n1 = to_rj54n1(client);
        struct v4l2_rect *rect = &a->c;
-       unsigned int dummy, output_w, output_h,
+       unsigned int dummy = 0, output_w, output_h,
                input_w = rect->width, input_h = rect->height;
        int ret;
 
index 9f85e917f9f39da8565954f6c38eb45021d30bad..a7ad7810fddcc96454abcc1f806c7d289cd2cb79 100644 (file)
@@ -420,19 +420,6 @@ int saa7134_set_dmabits(struct saa7134_dev *dev)
                ctrl |= SAA7134_MAIN_CTRL_TE5;
                irq  |= SAA7134_IRQ1_INTE_RA2_1 |
                        SAA7134_IRQ1_INTE_RA2_0;
-
-               /* dma: setup channel 5 (= TS) */
-
-               saa_writeb(SAA7134_TS_DMA0, (dev->ts.nr_packets - 1) & 0xff);
-               saa_writeb(SAA7134_TS_DMA1,
-                       ((dev->ts.nr_packets - 1) >> 8) & 0xff);
-               /* TSNOPIT=0, TSCOLAP=0 */
-               saa_writeb(SAA7134_TS_DMA2,
-                       (((dev->ts.nr_packets - 1) >> 16) & 0x3f) | 0x00);
-               saa_writel(SAA7134_RS_PITCH(5), TS_PACKET_SIZE);
-               saa_writel(SAA7134_RS_CONTROL(5), SAA7134_RS_CONTROL_BURST_16 |
-                                                 SAA7134_RS_CONTROL_ME |
-                                                 (dev->ts.pt_ts.dma >> 12));
        }
 
        /* set task conditions + field handling */
index 03488ba4c99c07f66a15e989414b700054ae1281..b9817d74943fa014b9f4861c58e002dec19dcd43 100644 (file)
@@ -250,6 +250,19 @@ int saa7134_ts_start(struct saa7134_dev *dev)
 
        BUG_ON(dev->ts_started);
 
+       /* dma: setup channel 5 (= TS) */
+       saa_writeb(SAA7134_TS_DMA0, (dev->ts.nr_packets - 1) & 0xff);
+       saa_writeb(SAA7134_TS_DMA1,
+               ((dev->ts.nr_packets - 1) >> 8) & 0xff);
+       /* TSNOPIT=0, TSCOLAP=0 */
+       saa_writeb(SAA7134_TS_DMA2,
+               (((dev->ts.nr_packets - 1) >> 16) & 0x3f) | 0x00);
+       saa_writel(SAA7134_RS_PITCH(5), TS_PACKET_SIZE);
+       saa_writel(SAA7134_RS_CONTROL(5), SAA7134_RS_CONTROL_BURST_16 |
+                                         SAA7134_RS_CONTROL_ME |
+                                         (dev->ts.pt_ts.dma >> 12));
+
+       /* reset hardware TS buffers */
        saa_writeb(SAA7134_TS_SERIAL1, 0x00);
        saa_writeb(SAA7134_TS_SERIAL1, 0x03);
        saa_writeb(SAA7134_TS_SERIAL1, 0x00);
index d69363f0d8c9932b21f02ada8f865899b115f336..f09c7140d6b266e96502ab3cc6d74703cf30681e 100644 (file)
@@ -1827,7 +1827,7 @@ static int __devinit sh_mobile_ceu_probe(struct platform_device *pdev)
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        irq = platform_get_irq(pdev, 0);
-       if (!res || !irq) {
+       if (!res || (int)irq <= 0) {
                dev_err(&pdev->dev, "Not enough CEU platform resources.\n");
                err = -ENODEV;
                goto exit;
index 0469d7a876a8987e3cd6421a4120eb01e31641f8..ec8ef8c5560af17bf60057c6d0eb37b310cdd609 100644 (file)
@@ -1393,7 +1393,7 @@ uvc_ctrl_prune_entity(struct uvc_device *dev, struct uvc_entity *entity)
        size = entity->processing.bControlSize;
 
        for (i = 0; i < ARRAY_SIZE(blacklist); ++i) {
-               if (!usb_match_id(dev->intf, &blacklist[i].id))
+               if (!usb_match_one_id(dev->intf, &blacklist[i].id))
                        continue;
 
                if (blacklist[i].index >= 8 * size ||
index f854698c40618a4a5225209f1060933f1aafb430..ea11839cba4a439f92461d899910171d1c9f41bb 100644 (file)
@@ -59,9 +59,9 @@
  *    returns immediately.
  *
  *    When the buffer is full, the completion handler removes it from the irq
- *    queue, marks it as ready (UVC_BUF_STATE_DONE) and wakes its wait queue.
+ *    queue, marks it as done (UVC_BUF_STATE_DONE) and wakes its wait queue.
  *    At that point, any process waiting on the buffer will be woken up. If a
- *    process tries to dequeue a buffer after it has been marked ready, the
+ *    process tries to dequeue a buffer after it has been marked done, the
  *    dequeing will succeed immediately.
  *
  * 2. Buffers are queued, user is waiting on a buffer and the device gets
@@ -201,6 +201,7 @@ static void __uvc_query_buffer(struct uvc_buffer *buf,
                break;
        case UVC_BUF_STATE_QUEUED:
        case UVC_BUF_STATE_ACTIVE:
+       case UVC_BUF_STATE_READY:
                v4l2_buf->flags |= V4L2_BUF_FLAG_QUEUED;
                break;
        case UVC_BUF_STATE_IDLE:
@@ -295,13 +296,15 @@ static int uvc_queue_waiton(struct uvc_buffer *buf, int nonblocking)
 {
        if (nonblocking) {
                return (buf->state != UVC_BUF_STATE_QUEUED &&
-                       buf->state != UVC_BUF_STATE_ACTIVE)
+                       buf->state != UVC_BUF_STATE_ACTIVE &&
+                       buf->state != UVC_BUF_STATE_READY)
                        ? 0 : -EAGAIN;
        }
 
        return wait_event_interruptible(buf->wait,
                buf->state != UVC_BUF_STATE_QUEUED &&
-               buf->state != UVC_BUF_STATE_ACTIVE);
+               buf->state != UVC_BUF_STATE_ACTIVE &&
+               buf->state != UVC_BUF_STATE_READY);
 }
 
 /*
@@ -348,6 +351,7 @@ int uvc_dequeue_buffer(struct uvc_video_queue *queue,
        case UVC_BUF_STATE_IDLE:
        case UVC_BUF_STATE_QUEUED:
        case UVC_BUF_STATE_ACTIVE:
+       case UVC_BUF_STATE_READY:
        default:
                uvc_trace(UVC_TRACE_CAPTURE, "[E] Invalid buffer state %u "
                        "(driver bug?).\n", buf->state);
@@ -489,6 +493,7 @@ struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue,
 
        spin_lock_irqsave(&queue->irqlock, flags);
        list_del(&buf->queue);
+       buf->state = UVC_BUF_STATE_DONE;
        if (!list_empty(&queue->irqqueue))
                nextbuf = list_first_entry(&queue->irqqueue, struct uvc_buffer,
                                           queue);
index 9a9802830d41ea1676f456e335c2e53e8e6fb4cc..7dcf534a0cf350c28844a766335a3f121b0476c2 100644 (file)
@@ -441,7 +441,7 @@ static int uvc_video_decode_start(struct uvc_streaming *stream,
        if (fid != stream->last_fid && buf->buf.bytesused != 0) {
                uvc_trace(UVC_TRACE_FRAME, "Frame complete (FID bit "
                                "toggled).\n");
-               buf->state = UVC_BUF_STATE_DONE;
+               buf->state = UVC_BUF_STATE_READY;
                return -EAGAIN;
        }
 
@@ -470,7 +470,7 @@ static void uvc_video_decode_data(struct uvc_streaming *stream,
        /* Complete the current frame if the buffer size was exceeded. */
        if (len > maxlen) {
                uvc_trace(UVC_TRACE_FRAME, "Frame complete (overflow).\n");
-               buf->state = UVC_BUF_STATE_DONE;
+               buf->state = UVC_BUF_STATE_READY;
        }
 }
 
@@ -482,7 +482,7 @@ static void uvc_video_decode_end(struct uvc_streaming *stream,
                uvc_trace(UVC_TRACE_FRAME, "Frame complete (EOF found).\n");
                if (data[0] == len)
                        uvc_trace(UVC_TRACE_FRAME, "EOF in empty payload.\n");
-               buf->state = UVC_BUF_STATE_DONE;
+               buf->state = UVC_BUF_STATE_READY;
                if (stream->dev->quirks & UVC_QUIRK_STREAM_NO_FID)
                        stream->last_fid ^= UVC_STREAM_FID;
        }
@@ -568,8 +568,7 @@ static void uvc_video_decode_isoc(struct urb *urb, struct uvc_streaming *stream,
                uvc_video_decode_end(stream, buf, mem,
                        urb->iso_frame_desc[i].actual_length);
 
-               if (buf->state == UVC_BUF_STATE_DONE ||
-                   buf->state == UVC_BUF_STATE_ERROR)
+               if (buf->state == UVC_BUF_STATE_READY)
                        buf = uvc_queue_next_buffer(&stream->queue, buf);
        }
 }
@@ -627,8 +626,7 @@ static void uvc_video_decode_bulk(struct urb *urb, struct uvc_streaming *stream,
                if (!stream->bulk.skip_payload && buf != NULL) {
                        uvc_video_decode_end(stream, buf, stream->bulk.header,
                                stream->bulk.payload_size);
-                       if (buf->state == UVC_BUF_STATE_DONE ||
-                           buf->state == UVC_BUF_STATE_ERROR)
+                       if (buf->state == UVC_BUF_STATE_READY)
                                buf = uvc_queue_next_buffer(&stream->queue,
                                                            buf);
                }
@@ -669,7 +667,7 @@ static void uvc_video_encode_bulk(struct urb *urb, struct uvc_streaming *stream,
            stream->bulk.payload_size == stream->bulk.max_payload_size) {
                if (buf->buf.bytesused == stream->queue.buf_used) {
                        stream->queue.buf_used = 0;
-                       buf->state = UVC_BUF_STATE_DONE;
+                       buf->state = UVC_BUF_STATE_READY;
                        uvc_queue_next_buffer(&stream->queue, buf);
                        stream->last_fid ^= UVC_STREAM_FID;
                }
@@ -924,10 +922,8 @@ static int uvc_init_video_bulk(struct uvc_streaming *stream,
 static int uvc_init_video(struct uvc_streaming *stream, gfp_t gfp_flags)
 {
        struct usb_interface *intf = stream->intf;
-       struct usb_host_interface *alts;
-       struct usb_host_endpoint *ep = NULL;
-       int intfnum = stream->intfnum;
-       unsigned int bandwidth, psize, i;
+       struct usb_host_endpoint *ep;
+       unsigned int i;
        int ret;
 
        stream->last_fid = -1;
@@ -936,6 +932,12 @@ static int uvc_init_video(struct uvc_streaming *stream, gfp_t gfp_flags)
        stream->bulk.payload_size = 0;
 
        if (intf->num_altsetting > 1) {
+               struct usb_host_endpoint *best_ep = NULL;
+               unsigned int best_psize = 3 * 1024;
+               unsigned int bandwidth;
+               unsigned int uninitialized_var(altsetting);
+               int intfnum = stream->intfnum;
+
                /* Isochronous endpoint, select the alternate setting. */
                bandwidth = stream->ctrl.dwMaxPayloadTransferSize;
 
@@ -949,6 +951,9 @@ static int uvc_init_video(struct uvc_streaming *stream, gfp_t gfp_flags)
                }
 
                for (i = 0; i < intf->num_altsetting; ++i) {
+                       struct usb_host_interface *alts;
+                       unsigned int psize;
+
                        alts = &intf->altsetting[i];
                        ep = uvc_find_endpoint(alts,
                                stream->header.bEndpointAddress);
@@ -958,21 +963,27 @@ static int uvc_init_video(struct uvc_streaming *stream, gfp_t gfp_flags)
                        /* Check if the bandwidth is high enough. */
                        psize = le16_to_cpu(ep->desc.wMaxPacketSize);
                        psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3));
-                       if (psize >= bandwidth)
-                               break;
+                       if (psize >= bandwidth && psize <= best_psize) {
+                               altsetting = i;
+                               best_psize = psize;
+                               best_ep = ep;
+                       }
                }
 
-               if (i >= intf->num_altsetting) {
+               if (best_ep == NULL) {
                        uvc_trace(UVC_TRACE_VIDEO, "No fast enough alt setting "
                                "for requested bandwidth.\n");
                        return -EIO;
                }
 
-               ret = usb_set_interface(stream->dev->udev, intfnum, i);
+               uvc_trace(UVC_TRACE_VIDEO, "Selecting alternate setting %u "
+                       "(%u B/frame bandwidth).\n", altsetting, best_psize);
+
+               ret = usb_set_interface(stream->dev->udev, intfnum, altsetting);
                if (ret < 0)
                        return ret;
 
-               ret = uvc_init_video_isoc(stream, ep, gfp_flags);
+               ret = uvc_init_video_isoc(stream, best_ep, gfp_flags);
        } else {
                /* Bulk endpoint, proceed to URB initialization. */
                ep = uvc_find_endpoint(&intf->altsetting[0],
index 7ec9a04ced5055f0dde006788aa1437be7f6dedd..2337585001ea01be3d31c4300c9ec303e9580031 100644 (file)
@@ -365,8 +365,9 @@ enum uvc_buffer_state {
        UVC_BUF_STATE_IDLE      = 0,
        UVC_BUF_STATE_QUEUED    = 1,
        UVC_BUF_STATE_ACTIVE    = 2,
-       UVC_BUF_STATE_DONE      = 3,
-       UVC_BUF_STATE_ERROR     = 4,
+       UVC_BUF_STATE_READY     = 3,
+       UVC_BUF_STATE_DONE      = 4,
+       UVC_BUF_STATE_ERROR     = 5,
 };
 
 struct uvc_buffer {
index e4df8134f0594446294eacbb85d57cea2414cba2..1eb079b3d429dc48b8ef9b218e5b3df29c71c83f 100644 (file)
@@ -860,10 +860,8 @@ int medusa_video_init(struct cx25821_dev *dev)
 
        ret_val = medusa_set_videostandard(dev);
 
-       if (ret_val < 0) {
-               mutex_unlock(&dev->lock);
+       if (ret_val < 0)
                return -EINVAL;
-       }
 
        return 1;
 }