diff options
Diffstat (limited to 'drivers/media/usb')
-rw-r--r-- | drivers/media/usb/as102/as102_usb_drv.c | 6 | ||||
-rw-r--r-- | drivers/media/usb/au0828/au0828-core.c | 2 | ||||
-rw-r--r-- | drivers/media/usb/dvb-usb-v2/az6007.c | 19 | ||||
-rw-r--r-- | drivers/media/usb/dvb-usb/af9005-fe.c | 3 | ||||
-rw-r--r-- | drivers/media/usb/dvb-usb/az6027.c | 34 | ||||
-rw-r--r-- | drivers/media/usb/dvb-usb/dtt200u-fe.c | 2 | ||||
-rw-r--r-- | drivers/media/usb/dvb-usb/dw2102.c | 26 | ||||
-rw-r--r-- | drivers/media/usb/dvb-usb/opera1.c | 3 | ||||
-rw-r--r-- | drivers/media/usb/dvb-usb/pctv452e.c | 20 | ||||
-rw-r--r-- | drivers/media/usb/go7007/s2250-board.c | 2 | ||||
-rw-r--r-- | drivers/media/usb/siano/smsusb.c | 3 | ||||
-rw-r--r-- | drivers/media/usb/stk1160/Kconfig | 12 | ||||
-rw-r--r-- | drivers/media/usb/ttusb-dec/ttusb_dec.c | 2 | ||||
-rw-r--r-- | drivers/media/usb/uvc/uvc_driver.c | 137 | ||||
-rw-r--r-- | drivers/media/usb/uvc/uvc_v4l2.c | 79 | ||||
-rw-r--r-- | drivers/media/usb/uvc/uvc_video.c | 20 | ||||
-rw-r--r-- | drivers/media/usb/uvc/uvcvideo.h | 12 |
17 files changed, 222 insertions, 160 deletions
diff --git a/drivers/media/usb/as102/as102_usb_drv.c b/drivers/media/usb/as102/as102_usb_drv.c index 50419e8ae56c..6b380144d6c2 100644 --- a/drivers/media/usb/as102/as102_usb_drv.c +++ b/drivers/media/usb/as102/as102_usb_drv.c @@ -303,10 +303,8 @@ static void as102_usb_release(struct kref *kref) struct as102_dev_t *as102_dev; as102_dev = container_of(kref, struct as102_dev_t, kref); - if (as102_dev != NULL) { - usb_put_dev(as102_dev->bus_adap.usb_dev); - kfree(as102_dev); - } + usb_put_dev(as102_dev->bus_adap.usb_dev); + kfree(as102_dev); } static void as102_usb_disconnect(struct usb_interface *intf) diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c index b3a09d3ac7d2..1e246b47766d 100644 --- a/drivers/media/usb/au0828/au0828-core.c +++ b/drivers/media/usb/au0828/au0828-core.c @@ -250,7 +250,7 @@ static void au0828_media_graph_notify(struct media_entity *new, create_link: if (decoder && mixer) { - ret = media_get_pad_index(decoder, false, + ret = media_get_pad_index(decoder, MEDIA_PAD_FL_SOURCE, PAD_SIGNAL_AUDIO); if (ret >= 0) ret = media_create_pad_link(decoder, ret, diff --git a/drivers/media/usb/dvb-usb-v2/az6007.c b/drivers/media/usb/dvb-usb-v2/az6007.c index 62ee09f28a0b..2dcbb49d66da 100644 --- a/drivers/media/usb/dvb-usb-v2/az6007.c +++ b/drivers/media/usb/dvb-usb-v2/az6007.c @@ -202,7 +202,8 @@ static int az6007_rc_query(struct dvb_usb_device *d) unsigned code; enum rc_proto proto; - az6007_read(d, AZ6007_READ_IR, 0, 0, st->data, 10); + if (az6007_read(d, AZ6007_READ_IR, 0, 0, st->data, 10) < 0) + return -EIO; if (st->data[1] == 0x44) return 0; @@ -248,7 +249,7 @@ static int az6007_ci_read_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address) { - struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data; + struct dvb_usb_device *d = ca->data; struct az6007_device_state *state = d_to_priv(d); int ret; @@ -290,7 +291,7 @@ static int az6007_ci_write_attribute_mem(struct dvb_ca_en50221 *ca, int address, u8 value) { - struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data; + struct dvb_usb_device *d = ca->data; struct az6007_device_state *state = d_to_priv(d); int ret; @@ -321,7 +322,7 @@ static int az6007_ci_read_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address) { - struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data; + struct dvb_usb_device *d = ca->data; struct az6007_device_state *state = d_to_priv(d); int ret; @@ -367,7 +368,7 @@ static int az6007_ci_write_cam_control(struct dvb_ca_en50221 *ca, u8 address, u8 value) { - struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data; + struct dvb_usb_device *d = ca->data; struct az6007_device_state *state = d_to_priv(d); int ret; @@ -398,7 +399,7 @@ failed: static int CI_CamReady(struct dvb_ca_en50221 *ca, int slot) { - struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data; + struct dvb_usb_device *d = ca->data; int ret; u8 req; @@ -429,7 +430,7 @@ static int CI_CamReady(struct dvb_ca_en50221 *ca, int slot) static int az6007_ci_slot_reset(struct dvb_ca_en50221 *ca, int slot) { - struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data; + struct dvb_usb_device *d = ca->data; struct az6007_device_state *state = d_to_priv(d); int ret, i; @@ -485,7 +486,7 @@ static int az6007_ci_slot_shutdown(struct dvb_ca_en50221 *ca, int slot) static int az6007_ci_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot) { - struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data; + struct dvb_usb_device *d = ca->data; struct az6007_device_state *state = d_to_priv(d); int ret; @@ -514,7 +515,7 @@ failed: static int az6007_ci_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open) { - struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data; + struct dvb_usb_device *d = ca->data; struct az6007_device_state *state = d_to_priv(d); int ret; u8 req; diff --git a/drivers/media/usb/dvb-usb/af9005-fe.c b/drivers/media/usb/dvb-usb/af9005-fe.c index 9d6fa0556d7b..404e56b32145 100644 --- a/drivers/media/usb/dvb-usb/af9005-fe.c +++ b/drivers/media/usb/dvb-usb/af9005-fe.c @@ -1412,8 +1412,7 @@ static int af9005_fe_get_frontend(struct dvb_frontend *fe, static void af9005_fe_release(struct dvb_frontend *fe) { - struct af9005_fe_state *state = - (struct af9005_fe_state *)fe->demodulator_priv; + struct af9005_fe_state *state = fe->demodulator_priv; kfree(state); } diff --git a/drivers/media/usb/dvb-usb/az6027.c b/drivers/media/usb/dvb-usb/az6027.c index a31c6f82f4e9..2bc27710427d 100644 --- a/drivers/media/usb/dvb-usb/az6027.c +++ b/drivers/media/usb/dvb-usb/az6027.c @@ -407,8 +407,8 @@ static int az6027_ci_read_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address) { - struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data; - struct az6027_device_state *state = (struct az6027_device_state *)d->priv; + struct dvb_usb_device *d = ca->data; + struct az6027_device_state *state = d->priv; int ret; u8 req; @@ -449,8 +449,8 @@ static int az6027_ci_write_attribute_mem(struct dvb_ca_en50221 *ca, int address, u8 value) { - struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data; - struct az6027_device_state *state = (struct az6027_device_state *)d->priv; + struct dvb_usb_device *d = ca->data; + struct az6027_device_state *state = d->priv; int ret; u8 req; @@ -480,8 +480,8 @@ static int az6027_ci_read_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address) { - struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data; - struct az6027_device_state *state = (struct az6027_device_state *)d->priv; + struct dvb_usb_device *d = ca->data; + struct az6027_device_state *state = d->priv; int ret; u8 req; @@ -526,8 +526,8 @@ static int az6027_ci_write_cam_control(struct dvb_ca_en50221 *ca, u8 address, u8 value) { - struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data; - struct az6027_device_state *state = (struct az6027_device_state *)d->priv; + struct dvb_usb_device *d = ca->data; + struct az6027_device_state *state = d->priv; int ret; u8 req; @@ -557,7 +557,7 @@ failed: static int CI_CamReady(struct dvb_ca_en50221 *ca, int slot) { - struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data; + struct dvb_usb_device *d = ca->data; int ret; u8 req; @@ -588,8 +588,8 @@ static int CI_CamReady(struct dvb_ca_en50221 *ca, int slot) static int az6027_ci_slot_reset(struct dvb_ca_en50221 *ca, int slot) { - struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data; - struct az6027_device_state *state = (struct az6027_device_state *)d->priv; + struct dvb_usb_device *d = ca->data; + struct az6027_device_state *state = d->priv; int ret, i; u8 req; @@ -644,8 +644,8 @@ static int az6027_ci_slot_shutdown(struct dvb_ca_en50221 *ca, int slot) static int az6027_ci_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot) { - struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data; - struct az6027_device_state *state = (struct az6027_device_state *)d->priv; + struct dvb_usb_device *d = ca->data; + struct az6027_device_state *state = d->priv; int ret; u8 req; @@ -673,8 +673,8 @@ failed: static int az6027_ci_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open) { - struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data; - struct az6027_device_state *state = (struct az6027_device_state *)d->priv; + struct dvb_usb_device *d = ca->data; + struct az6027_device_state *state = d->priv; int ret; u8 req; u16 value; @@ -719,7 +719,7 @@ static void az6027_ci_uninit(struct dvb_usb_device *d) if (NULL == d) return; - state = (struct az6027_device_state *)d->priv; + state = d->priv; if (NULL == state) return; @@ -735,7 +735,7 @@ static void az6027_ci_uninit(struct dvb_usb_device *d) static int az6027_ci_init(struct dvb_usb_adapter *a) { struct dvb_usb_device *d = a->dev; - struct az6027_device_state *state = (struct az6027_device_state *)d->priv; + struct az6027_device_state *state = d->priv; int ret; deb_info("%s", __func__); diff --git a/drivers/media/usb/dvb-usb/dtt200u-fe.c b/drivers/media/usb/dvb-usb/dtt200u-fe.c index 9f83560ba63d..586afe22d817 100644 --- a/drivers/media/usb/dvb-usb/dtt200u-fe.c +++ b/drivers/media/usb/dvb-usb/dtt200u-fe.c @@ -195,7 +195,7 @@ static int dtt200u_fe_get_frontend(struct dvb_frontend* fe, static void dtt200u_fe_release(struct dvb_frontend* fe) { - struct dtt200u_fe_state *state = (struct dtt200u_fe_state*) fe->demodulator_priv; + struct dtt200u_fe_state *state = fe->demodulator_priv; kfree(state); } diff --git a/drivers/media/usb/dvb-usb/dw2102.c b/drivers/media/usb/dvb-usb/dw2102.c index 8747960e6146..970b84c3f0b5 100644 --- a/drivers/media/usb/dvb-usb/dw2102.c +++ b/drivers/media/usb/dvb-usb/dw2102.c @@ -830,7 +830,7 @@ static int dw210x_read_mac_address(struct dvb_usb_device *d, u8 mac[6]) for (i = 0; i < 256; i++) { if (dw210x_op_rw(d->udev, 0xb6, 0xa0 , i, ibuf, 2, DW210X_READ_MSG) < 0) { err("read eeprom failed."); - return -1; + return -EIO; } else { eepromline[i%16] = ibuf[0]; eeprom[i] = ibuf[0]; @@ -869,7 +869,7 @@ static int s6x0_read_mac_address(struct dvb_usb_device *d, u8 mac[6]) ret = s6x0_i2c_transfer(&d->i2c_adap, msg, 2); if (ret != 2) { err("read eeprom failed."); - return -1; + return -EIO; } else { eepromline[i % 16] = ibuf[0]; eeprom[i] = ibuf[0]; @@ -903,7 +903,7 @@ static int su3000_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) static int su3000_power_ctrl(struct dvb_usb_device *d, int i) { - struct dw2102_state *state = (struct dw2102_state *)d->priv; + struct dw2102_state *state = d->priv; int ret = 0; info("%s: %d, initialized %d", __func__, i, state->initialized); @@ -946,7 +946,7 @@ static int su3000_read_mac_address(struct dvb_usb_device *d, u8 mac[6]) for (i = 0; i < 6; i++) { obuf[1] = 0xf0 + i; if (i2c_transfer(&d->i2c_adap, msg, 2) != 2) - return -1; + return -EIO; else mac[i] = ibuf[0]; } @@ -978,8 +978,7 @@ static int dw210x_set_voltage(struct dvb_frontend *fe, .len = 2, }; - struct dvb_usb_adapter *udev_adap = - (struct dvb_usb_adapter *)(fe->dvb->priv); + struct dvb_usb_adapter *udev_adap = fe->dvb->priv; if (voltage == SEC_VOLTAGE_18) msg.buf = command_18v; else if (voltage == SEC_VOLTAGE_13) @@ -993,9 +992,8 @@ static int dw210x_set_voltage(struct dvb_frontend *fe, static int s660_set_voltage(struct dvb_frontend *fe, enum fe_sec_voltage voltage) { - struct dvb_usb_adapter *d = - (struct dvb_usb_adapter *)(fe->dvb->priv); - struct dw2102_state *st = (struct dw2102_state *)d->dev->priv; + struct dvb_usb_adapter *d = fe->dvb->priv; + struct dw2102_state *st = d->dev->priv; dw210x_set_voltage(fe, voltage); if (st->old_set_voltage) @@ -1014,8 +1012,7 @@ static void dw210x_led_ctrl(struct dvb_frontend *fe, int offon) .buf = led_off, .len = 1 }; - struct dvb_usb_adapter *udev_adap = - (struct dvb_usb_adapter *)(fe->dvb->priv); + struct dvb_usb_adapter *udev_adap = fe->dvb->priv; if (offon) msg.buf = led_on; @@ -1025,9 +1022,8 @@ static void dw210x_led_ctrl(struct dvb_frontend *fe, int offon) static int tt_s2_4600_read_status(struct dvb_frontend *fe, enum fe_status *status) { - struct dvb_usb_adapter *d = - (struct dvb_usb_adapter *)(fe->dvb->priv); - struct dw2102_state *st = (struct dw2102_state *)d->dev->priv; + struct dvb_usb_adapter *d = fe->dvb->priv; + struct dw2102_state *st = d->dev->priv; int ret; ret = st->fe_read_status(fe, status); @@ -2576,7 +2572,7 @@ static int dw2102_probe(struct usb_interface *intf, static void dw2102_disconnect(struct usb_interface *intf) { struct dvb_usb_device *d = usb_get_intfdata(intf); - struct dw2102_state *st = (struct dw2102_state *)d->priv; + struct dw2102_state *st = d->priv; struct i2c_client *client; /* remove I2C client for tuner */ diff --git a/drivers/media/usb/dvb-usb/opera1.c b/drivers/media/usb/dvb-usb/opera1.c index 0da86f58aff6..98b2177667d2 100644 --- a/drivers/media/usb/dvb-usb/opera1.c +++ b/drivers/media/usb/dvb-usb/opera1.c @@ -172,8 +172,7 @@ static int opera1_set_voltage(struct dvb_frontend *fe, struct i2c_msg msg[] = { {.addr = ADDR_B600_VOLTAGE_13V,.flags = 0,.buf = command_13v,.len = 1}, }; - struct dvb_usb_adapter *udev_adap = - (struct dvb_usb_adapter *)(fe->dvb->priv); + struct dvb_usb_adapter *udev_adap = fe->dvb->priv; if (voltage == SEC_VOLTAGE_18) { msg[0].addr = ADDR_B601_VOLTAGE_18V; msg[0].buf = command_18v; diff --git a/drivers/media/usb/dvb-usb/pctv452e.c b/drivers/media/usb/dvb-usb/pctv452e.c index da42c989e071..2aab49003493 100644 --- a/drivers/media/usb/dvb-usb/pctv452e.c +++ b/drivers/media/usb/dvb-usb/pctv452e.c @@ -108,7 +108,7 @@ struct pctv452e_state { static int tt3650_ci_msg(struct dvb_usb_device *d, u8 cmd, u8 *data, unsigned int write_len, unsigned int read_len) { - struct pctv452e_state *state = (struct pctv452e_state *)d->priv; + struct pctv452e_state *state = d->priv; u8 *buf; u8 id; unsigned int rlen; @@ -159,8 +159,8 @@ static int tt3650_ci_msg_locked(struct dvb_ca_en50221 *ca, u8 cmd, u8 *data, unsigned int write_len, unsigned int read_len) { - struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data; - struct pctv452e_state *state = (struct pctv452e_state *)d->priv; + struct dvb_usb_device *d = ca->data; + struct pctv452e_state *state = d->priv; int ret; mutex_lock(&state->ca_mutex); @@ -292,8 +292,8 @@ static int tt3650_ci_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot) static int tt3650_ci_slot_reset(struct dvb_ca_en50221 *ca, int slot) { - struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data; - struct pctv452e_state *state = (struct pctv452e_state *)d->priv; + struct dvb_usb_device *d = ca->data; + struct pctv452e_state *state = d->priv; u8 buf[1]; int ret; @@ -361,7 +361,7 @@ static void tt3650_ci_uninit(struct dvb_usb_device *d) if (NULL == d) return; - state = (struct pctv452e_state *)d->priv; + state = d->priv; if (NULL == state) return; @@ -379,7 +379,7 @@ static void tt3650_ci_uninit(struct dvb_usb_device *d) static int tt3650_ci_init(struct dvb_usb_adapter *a) { struct dvb_usb_device *d = a->dev; - struct pctv452e_state *state = (struct pctv452e_state *)d->priv; + struct pctv452e_state *state = d->priv; int ret; ci_dbg("%s", __func__); @@ -417,7 +417,7 @@ static int pctv452e_i2c_msg(struct dvb_usb_device *d, u8 addr, const u8 *snd_buf, u8 snd_len, u8 *rcv_buf, u8 rcv_len) { - struct pctv452e_state *state = (struct pctv452e_state *)d->priv; + struct pctv452e_state *state = d->priv; u8 *buf; u8 id; int ret; @@ -516,7 +516,7 @@ static u32 pctv452e_i2c_func(struct i2c_adapter *adapter) static int pctv452e_power_ctrl(struct dvb_usb_device *d, int i) { - struct pctv452e_state *state = (struct pctv452e_state *)d->priv; + struct pctv452e_state *state = d->priv; u8 *b0, *rx; int ret; @@ -567,7 +567,7 @@ ret: static int pctv452e_rc_query(struct dvb_usb_device *d) { - struct pctv452e_state *state = (struct pctv452e_state *)d->priv; + struct pctv452e_state *state = d->priv; u8 *b, *rx; int ret, i; u8 id; diff --git a/drivers/media/usb/go7007/s2250-board.c b/drivers/media/usb/go7007/s2250-board.c index 29dfcc6d0b0a..db1fab96d529 100644 --- a/drivers/media/usb/go7007/s2250-board.c +++ b/drivers/media/usb/go7007/s2250-board.c @@ -620,7 +620,7 @@ static struct i2c_driver s2250_driver = { .driver = { .name = "s2250", }, - .probe_new = s2250_probe, + .probe = s2250_probe, .remove = s2250_remove, .id_table = s2250_id, }; diff --git a/drivers/media/usb/siano/smsusb.c b/drivers/media/usb/siano/smsusb.c index 6f443c542c6d..640737d3b8ae 100644 --- a/drivers/media/usb/siano/smsusb.c +++ b/drivers/media/usb/siano/smsusb.c @@ -179,7 +179,8 @@ static void smsusb_stop_streaming(struct smsusb_device_t *dev) for (i = 0; i < MAX_URBS; i++) { usb_kill_urb(&dev->surbs[i].urb); - cancel_work_sync(&dev->surbs[i].wq); + if (dev->surbs[i].wq.func) + cancel_work_sync(&dev->surbs[i].wq); if (dev->surbs[i].cb) { smscore_putbuffer(dev->coredev, dev->surbs[i].cb); diff --git a/drivers/media/usb/stk1160/Kconfig b/drivers/media/usb/stk1160/Kconfig index 4f50fb7db7b9..bf7c16baa9f8 100644 --- a/drivers/media/usb/stk1160/Kconfig +++ b/drivers/media/usb/stk1160/Kconfig @@ -1,8 +1,9 @@ # SPDX-License-Identifier: GPL-2.0-only -config VIDEO_STK1160_COMMON +config VIDEO_STK1160 tristate "STK1160 USB video capture support" depends on VIDEO_DEV && I2C - + select VIDEOBUF2_VMALLOC + select VIDEO_SAA711X help This is a video4linux driver for STK1160 based video capture devices. @@ -12,10 +13,3 @@ config VIDEO_STK1160_COMMON This driver only provides support for video capture. For audio capture, you need to select the snd-usb-audio driver (i.e. CONFIG_SND_USB_AUDIO). - -config VIDEO_STK1160 - tristate - depends on VIDEO_STK1160_COMMON - default y - select VIDEOBUF2_VMALLOC - select VIDEO_SAA711X diff --git a/drivers/media/usb/ttusb-dec/ttusb_dec.c b/drivers/media/usb/ttusb-dec/ttusb_dec.c index c4474d4c44e2..79faa2560613 100644 --- a/drivers/media/usb/ttusb-dec/ttusb_dec.c +++ b/drivers/media/usb/ttusb-dec/ttusb_dec.c @@ -1128,7 +1128,7 @@ static int ttusb_dec_stop_sec_feed(struct dvb_demux_feed *dvbdmxfeed) { struct ttusb_dec *dec = dvbdmxfeed->demux->priv; u8 b0[] = { 0x00, 0x00 }; - struct filter_info *finfo = (struct filter_info *)dvbdmxfeed->priv; + struct filter_info *finfo = dvbdmxfeed->priv; unsigned long flags; b0[1] = finfo->stream_id; diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c index d631ce4f9f7b..08fcd2ffa727 100644 --- a/drivers/media/usb/uvc/uvc_driver.c +++ b/drivers/media/usb/uvc/uvc_driver.c @@ -184,7 +184,7 @@ static void uvc_stream_delete(struct uvc_streaming *stream) usb_put_intf(stream->intf); - kfree(stream->format); + kfree(stream->formats); kfree(stream->header.bmaControls); kfree(stream); } @@ -221,7 +221,8 @@ static struct uvc_streaming *uvc_stream_new(struct uvc_device *dev, static int uvc_parse_format(struct uvc_device *dev, struct uvc_streaming *streaming, struct uvc_format *format, - u32 **intervals, unsigned char *buffer, int buflen) + struct uvc_frame *frames, u32 **intervals, const unsigned char *buffer, + int buflen) { struct usb_interface *intf = streaming->intf; struct usb_host_interface *alts = intf->cur_altsetting; @@ -235,6 +236,7 @@ static int uvc_parse_format(struct uvc_device *dev, format->type = buffer[2]; format->index = buffer[3]; + format->frames = frames; switch (buffer[2]) { case UVC_VS_FORMAT_UNCOMPRESSED: @@ -339,8 +341,8 @@ static int uvc_parse_format(struct uvc_device *dev, ftype = 0; /* Create a dummy frame descriptor. */ - frame = &format->frame[0]; - memset(&format->frame[0], 0, sizeof(format->frame[0])); + frame = &frames[0]; + memset(frame, 0, sizeof(*frame)); frame->bFrameIntervalType = 1; frame->dwDefaultFrameInterval = 1; frame->dwFrameInterval = *intervals; @@ -370,7 +372,9 @@ static int uvc_parse_format(struct uvc_device *dev, */ while (buflen > 2 && buffer[1] == USB_DT_CS_INTERFACE && buffer[2] == ftype) { - frame = &format->frame[format->nframes]; + unsigned int maxIntervalIndex; + + frame = &frames[format->nframes]; if (ftype != UVC_VS_FRAME_FRAME_BASED) n = buflen > 25 ? buffer[25] : 0; else @@ -405,8 +409,27 @@ static int uvc_parse_format(struct uvc_device *dev, get_unaligned_le32(&buffer[17]); frame->bFrameIntervalType = buffer[21]; } + + /* + * Copy the frame intervals. + * + * Some bogus devices report dwMinFrameInterval equal to + * dwMaxFrameInterval and have dwFrameIntervalStep set to + * zero. Setting all null intervals to 1 fixes the problem and + * some other divisions by zero that could happen. + */ frame->dwFrameInterval = *intervals; + for (i = 0; i < n; ++i) { + interval = get_unaligned_le32(&buffer[26+4*i]); + (*intervals)[i] = interval ? interval : 1; + } + + /* + * Apply more fixes, quirks and workarounds to handle incorrect + * or broken descriptors. + */ + /* * Several UVC chipsets screw up dwMaxVideoFrameBufferSize * completely. Observed behaviours range from setting the @@ -421,30 +444,25 @@ static int uvc_parse_format(struct uvc_device *dev, * frame->wWidth * frame->wHeight / 8; /* - * Some bogus devices report dwMinFrameInterval equal to - * dwMaxFrameInterval and have dwFrameIntervalStep set to - * zero. Setting all null intervals to 1 fixes the problem and - * some other divisions by zero that could happen. + * Clamp the default frame interval to the boundaries. A zero + * bFrameIntervalType value indicates a continuous frame + * interval range, with dwFrameInterval[0] storing the minimum + * value and dwFrameInterval[1] storing the maximum value. */ - for (i = 0; i < n; ++i) { - interval = get_unaligned_le32(&buffer[26+4*i]); - *(*intervals)++ = interval ? interval : 1; - } + maxIntervalIndex = frame->bFrameIntervalType ? n - 1 : 1; + frame->dwDefaultFrameInterval = + clamp(frame->dwDefaultFrameInterval, + frame->dwFrameInterval[0], + frame->dwFrameInterval[maxIntervalIndex]); /* - * Make sure that the default frame interval stays between - * the boundaries. + * Some devices report frame intervals that are not functional. + * If the corresponding quirk is set, restrict operation to the + * first interval only. */ - n -= frame->bFrameIntervalType ? 1 : 2; - frame->dwDefaultFrameInterval = - min(frame->dwFrameInterval[n], - max(frame->dwFrameInterval[0], - frame->dwDefaultFrameInterval)); - if (dev->quirks & UVC_QUIRK_RESTRICT_FRAME_RATE) { frame->bFrameIntervalType = 1; - frame->dwFrameInterval[0] = - frame->dwDefaultFrameInterval; + (*intervals)[0] = frame->dwDefaultFrameInterval; } uvc_dbg(dev, DESCR, "- %ux%u (%u.%u fps)\n", @@ -453,6 +471,8 @@ static int uvc_parse_format(struct uvc_device *dev, (100000000 / frame->dwDefaultFrameInterval) % 10); format->nframes++; + *intervals += n; + buflen -= buffer[0]; buffer += buffer[0]; } @@ -493,7 +513,7 @@ static int uvc_parse_streaming(struct uvc_device *dev, struct uvc_format *format; struct uvc_frame *frame; struct usb_host_interface *alts = &intf->altsetting[0]; - unsigned char *_buffer, *buffer = alts->extra; + const unsigned char *_buffer, *buffer = alts->extra; int _buflen, buflen = alts->extralen; unsigned int nformats = 0, nframes = 0, nintervals = 0; unsigned int size, i, n, p; @@ -677,7 +697,7 @@ static int uvc_parse_streaming(struct uvc_device *dev, frame = (struct uvc_frame *)&format[nformats]; interval = (u32 *)&frame[nframes]; - streaming->format = format; + streaming->formats = format; streaming->nformats = 0; /* Parse the format descriptors. */ @@ -687,8 +707,7 @@ static int uvc_parse_streaming(struct uvc_device *dev, case UVC_VS_FORMAT_MJPEG: case UVC_VS_FORMAT_DV: case UVC_VS_FORMAT_FRAME_BASED: - format->frame = frame; - ret = uvc_parse_format(dev, streaming, format, + ret = uvc_parse_format(dev, streaming, format, frame, &interval, buffer, buflen); if (ret < 0) goto error; @@ -1147,7 +1166,7 @@ static int uvc_parse_standard_control(struct uvc_device *dev, static int uvc_parse_control(struct uvc_device *dev) { struct usb_host_interface *alts = dev->intf->cur_altsetting; - unsigned char *buffer = alts->extra; + const unsigned char *buffer = alts->extra; int buflen = alts->extralen; int ret; @@ -3011,15 +3030,33 @@ static const struct usb_device_id uvc_ids[] = { .bInterfaceSubClass = 1, .bInterfaceProtocol = 0, .driver_info = (kernel_ulong_t)&uvc_ctrl_power_line_limited }, - /* Acer EasyCamera */ + /* Intel D410/ASR depth camera */ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, - .idVendor = 0x5986, - .idProduct = 0x1180, + .idVendor = 0x8086, + .idProduct = 0x0ad2, .bInterfaceClass = USB_CLASS_VIDEO, .bInterfaceSubClass = 1, .bInterfaceProtocol = 0, - .driver_info = (kernel_ulong_t)&uvc_ctrl_power_line_limited }, + .driver_info = UVC_INFO_META(V4L2_META_FMT_D4XX) }, + /* Intel D415/ASRC depth camera */ + { .match_flags = USB_DEVICE_ID_MATCH_DEVICE + | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = 0x8086, + .idProduct = 0x0ad3, + .bInterfaceClass = USB_CLASS_VIDEO, + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 0, + .driver_info = UVC_INFO_META(V4L2_META_FMT_D4XX) }, + /* Intel D430/AWG depth camera */ + { .match_flags = USB_DEVICE_ID_MATCH_DEVICE + | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = 0x8086, + .idProduct = 0x0ad4, + .bInterfaceClass = USB_CLASS_VIDEO, + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 0, + .driver_info = UVC_INFO_META(V4L2_META_FMT_D4XX) }, /* Intel RealSense D4M */ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, @@ -3029,6 +3066,42 @@ static const struct usb_device_id uvc_ids[] = { .bInterfaceSubClass = 1, .bInterfaceProtocol = 0, .driver_info = UVC_INFO_META(V4L2_META_FMT_D4XX) }, + /* Intel D435/AWGC depth camera */ + { .match_flags = USB_DEVICE_ID_MATCH_DEVICE + | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = 0x8086, + .idProduct = 0x0b07, + .bInterfaceClass = USB_CLASS_VIDEO, + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 0, + .driver_info = UVC_INFO_META(V4L2_META_FMT_D4XX) }, + /* Intel D435i depth camera */ + { .match_flags = USB_DEVICE_ID_MATCH_DEVICE + | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = 0x8086, + .idProduct = 0x0b3a, + .bInterfaceClass = USB_CLASS_VIDEO, + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 0, + .driver_info = UVC_INFO_META(V4L2_META_FMT_D4XX) }, + /* Intel D405 Depth Camera */ + { .match_flags = USB_DEVICE_ID_MATCH_DEVICE + | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = 0x8086, + .idProduct = 0x0b5b, + .bInterfaceClass = USB_CLASS_VIDEO, + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 0, + .driver_info = UVC_INFO_META(V4L2_META_FMT_D4XX) }, + /* Intel D455 Depth Camera */ + { .match_flags = USB_DEVICE_ID_MATCH_DEVICE + | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = 0x8086, + .idProduct = 0x0b5c, + .bInterfaceClass = USB_CLASS_VIDEO, + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 0, + .driver_info = UVC_INFO_META(V4L2_META_FMT_D4XX) }, /* Generic USB Video Class */ { USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, UVC_PC_PROTOCOL_UNDEFINED) }, { USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, UVC_PC_PROTOCOL_15) }, diff --git a/drivers/media/usb/uvc/uvc_v4l2.c b/drivers/media/usb/uvc/uvc_v4l2.c index 35453f81c1d9..5ac2a424b13d 100644 --- a/drivers/media/usb/uvc/uvc_v4l2.c +++ b/drivers/media/usb/uvc/uvc_v4l2.c @@ -161,7 +161,7 @@ free_map: * the Video Probe and Commit negotiation, but some hardware don't implement * that feature. */ -static u32 uvc_try_frame_interval(struct uvc_frame *frame, u32 interval) +static u32 uvc_try_frame_interval(const struct uvc_frame *frame, u32 interval) { unsigned int i; @@ -210,10 +210,11 @@ static u32 uvc_v4l2_get_bytesperline(const struct uvc_format *format, static int uvc_v4l2_try_format(struct uvc_streaming *stream, struct v4l2_format *fmt, struct uvc_streaming_control *probe, - struct uvc_format **uvc_format, struct uvc_frame **uvc_frame) + const struct uvc_format **uvc_format, + const struct uvc_frame **uvc_frame) { - struct uvc_format *format = NULL; - struct uvc_frame *frame = NULL; + const struct uvc_format *format = NULL; + const struct uvc_frame *frame = NULL; u16 rw, rh; unsigned int d, maxd; unsigned int i; @@ -235,7 +236,7 @@ static int uvc_v4l2_try_format(struct uvc_streaming *stream, * format otherwise. */ for (i = 0; i < stream->nformats; ++i) { - format = &stream->format[i]; + format = &stream->formats[i]; if (format->fcc == fmt->fmt.pix.pixelformat) break; } @@ -255,14 +256,14 @@ static int uvc_v4l2_try_format(struct uvc_streaming *stream, maxd = (unsigned int)-1; for (i = 0; i < format->nframes; ++i) { - u16 w = format->frame[i].wWidth; - u16 h = format->frame[i].wHeight; + u16 w = format->frames[i].wWidth; + u16 h = format->frames[i].wHeight; d = min(w, rw) * min(h, rh); d = w*h + rw*rh - 2*d; if (d < maxd) { maxd = d; - frame = &format->frame[i]; + frame = &format->frames[i]; } if (maxd == 0) @@ -319,8 +320,8 @@ static int uvc_v4l2_try_format(struct uvc_streaming *stream, * accepted the requested format as-is. */ for (i = 0; i < stream->nformats; ++i) { - if (probe->bFormatIndex == stream->format[i].index) { - format = &stream->format[i]; + if (probe->bFormatIndex == stream->formats[i].index) { + format = &stream->formats[i]; break; } } @@ -331,8 +332,8 @@ static int uvc_v4l2_try_format(struct uvc_streaming *stream, probe->bFormatIndex); for (i = 0; i < format->nframes; ++i) { - if (probe->bFrameIndex == format->frame[i].bFrameIndex) { - frame = &format->frame[i]; + if (probe->bFrameIndex == format->frames[i].bFrameIndex) { + frame = &format->frames[i]; break; } } @@ -363,8 +364,8 @@ static int uvc_v4l2_try_format(struct uvc_streaming *stream, static int uvc_v4l2_get_format(struct uvc_streaming *stream, struct v4l2_format *fmt) { - struct uvc_format *format; - struct uvc_frame *frame; + const struct uvc_format *format; + const struct uvc_frame *frame; int ret = 0; if (fmt->type != stream->type) @@ -398,8 +399,8 @@ static int uvc_v4l2_set_format(struct uvc_streaming *stream, struct v4l2_format *fmt) { struct uvc_streaming_control probe; - struct uvc_format *format; - struct uvc_frame *frame; + const struct uvc_format *format; + const struct uvc_frame *frame; int ret; if (fmt->type != stream->type) @@ -465,8 +466,8 @@ static int uvc_v4l2_set_streamparm(struct uvc_streaming *stream, { struct uvc_streaming_control probe; struct v4l2_fract timeperframe; - struct uvc_format *format; - struct uvc_frame *frame; + const struct uvc_format *format; + const struct uvc_frame *frame; u32 interval, maxd; unsigned int i; int ret; @@ -501,19 +502,19 @@ static int uvc_v4l2_set_streamparm(struct uvc_streaming *stream, for (i = 0; i < format->nframes && maxd != 0; i++) { u32 d, ival; - if (&format->frame[i] == stream->cur_frame) + if (&format->frames[i] == stream->cur_frame) continue; - if (format->frame[i].wWidth != stream->cur_frame->wWidth || - format->frame[i].wHeight != stream->cur_frame->wHeight) + if (format->frames[i].wWidth != stream->cur_frame->wWidth || + format->frames[i].wHeight != stream->cur_frame->wHeight) continue; - ival = uvc_try_frame_interval(&format->frame[i], interval); + ival = uvc_try_frame_interval(&format->frames[i], interval); d = abs((s32)ival - interval); if (d >= maxd) continue; - frame = &format->frame[i]; + frame = &format->frames[i]; probe.bFrameIndex = frame->bFrameIndex; probe.dwFrameInterval = ival; maxd = d; @@ -697,7 +698,7 @@ static int uvc_ioctl_querycap(struct file *file, void *fh, static int uvc_ioctl_enum_fmt(struct uvc_streaming *stream, struct v4l2_fmtdesc *fmt) { - struct uvc_format *format; + const struct uvc_format *format; enum v4l2_buf_type type = fmt->type; u32 index = fmt->index; @@ -708,7 +709,7 @@ static int uvc_ioctl_enum_fmt(struct uvc_streaming *stream, fmt->index = index; fmt->type = type; - format = &stream->format[fmt->index]; + format = &stream->formats[fmt->index]; fmt->flags = 0; if (format->flags & UVC_FMT_FLAG_COMPRESSED) fmt->flags |= V4L2_FMT_FLAG_COMPRESSED; @@ -1249,15 +1250,15 @@ static int uvc_ioctl_enum_framesizes(struct file *file, void *fh, { struct uvc_fh *handle = fh; struct uvc_streaming *stream = handle->stream; - struct uvc_format *format = NULL; - struct uvc_frame *frame = NULL; + const struct uvc_format *format = NULL; + const struct uvc_frame *frame = NULL; unsigned int index; unsigned int i; /* Look for the given pixel format */ for (i = 0; i < stream->nformats; i++) { - if (stream->format[i].fcc == fsize->pixel_format) { - format = &stream->format[i]; + if (stream->formats[i].fcc == fsize->pixel_format) { + format = &stream->formats[i]; break; } } @@ -1266,10 +1267,10 @@ static int uvc_ioctl_enum_framesizes(struct file *file, void *fh, /* Skip duplicate frame sizes */ for (i = 0, index = 0; i < format->nframes; i++) { - if (frame && frame->wWidth == format->frame[i].wWidth && - frame->wHeight == format->frame[i].wHeight) + if (frame && frame->wWidth == format->frames[i].wWidth && + frame->wHeight == format->frames[i].wHeight) continue; - frame = &format->frame[i]; + frame = &format->frames[i]; if (index == fsize->index) break; index++; @@ -1289,16 +1290,16 @@ static int uvc_ioctl_enum_frameintervals(struct file *file, void *fh, { struct uvc_fh *handle = fh; struct uvc_streaming *stream = handle->stream; - struct uvc_format *format = NULL; - struct uvc_frame *frame = NULL; + const struct uvc_format *format = NULL; + const struct uvc_frame *frame = NULL; unsigned int nintervals; unsigned int index; unsigned int i; /* Look for the given pixel format and frame size */ for (i = 0; i < stream->nformats; i++) { - if (stream->format[i].fcc == fival->pixel_format) { - format = &stream->format[i]; + if (stream->formats[i].fcc == fival->pixel_format) { + format = &stream->formats[i]; break; } } @@ -1307,9 +1308,9 @@ static int uvc_ioctl_enum_frameintervals(struct file *file, void *fh, index = fival->index; for (i = 0; i < format->nframes; i++) { - if (format->frame[i].wWidth == fival->width && - format->frame[i].wHeight == fival->height) { - frame = &format->frame[i]; + if (format->frames[i].wWidth == fival->width && + format->frames[i].wHeight == fival->height) { + frame = &format->frames[i]; nintervals = frame->bFrameIntervalType ?: 1; if (index < nintervals) break; diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c index d4b023d4de7c..28dde08ec6c5 100644 --- a/drivers/media/usb/uvc/uvc_video.c +++ b/drivers/media/usb/uvc/uvc_video.c @@ -137,8 +137,8 @@ static const struct usb_device_id elgato_cam_link_4k = { static void uvc_fixup_video_ctrl(struct uvc_streaming *stream, struct uvc_streaming_control *ctrl) { - struct uvc_format *format = NULL; - struct uvc_frame *frame = NULL; + const struct uvc_format *format = NULL; + const struct uvc_frame *frame = NULL; unsigned int i; /* @@ -166,8 +166,8 @@ static void uvc_fixup_video_ctrl(struct uvc_streaming *stream, } for (i = 0; i < stream->nformats; ++i) { - if (stream->format[i].index == ctrl->bFormatIndex) { - format = &stream->format[i]; + if (stream->formats[i].index == ctrl->bFormatIndex) { + format = &stream->formats[i]; break; } } @@ -176,8 +176,8 @@ static void uvc_fixup_video_ctrl(struct uvc_streaming *stream, return; for (i = 0; i < format->nframes; ++i) { - if (format->frame[i].bFrameIndex == ctrl->bFrameIndex) { - frame = &format->frame[i]; + if (format->frames[i].bFrameIndex == ctrl->bFrameIndex) { + frame = &format->frames[i]; break; } } @@ -2100,8 +2100,8 @@ int uvc_video_resume(struct uvc_streaming *stream, int reset) int uvc_video_init(struct uvc_streaming *stream) { struct uvc_streaming_control *probe = &stream->ctrl; - struct uvc_format *format = NULL; - struct uvc_frame *frame = NULL; + const struct uvc_format *format = NULL; + const struct uvc_frame *frame = NULL; struct uvc_urb *uvc_urb; unsigned int i; int ret; @@ -2161,7 +2161,7 @@ int uvc_video_init(struct uvc_streaming *stream) * available format otherwise. */ for (i = stream->nformats; i > 0; --i) { - format = &stream->format[i-1]; + format = &stream->formats[i-1]; if (format->index == probe->bFormatIndex) break; } @@ -2179,7 +2179,7 @@ int uvc_video_init(struct uvc_streaming *stream) * descriptor is not found, use the first available frame. */ for (i = format->nframes; i > 0; --i) { - frame = &format->frame[i-1]; + frame = &format->frames[i-1]; if (frame->bFrameIndex == probe->bFrameIndex) break; } diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h index 9a596c8d894a..6fb0a78b1b00 100644 --- a/drivers/media/usb/uvc/uvcvideo.h +++ b/drivers/media/usb/uvc/uvcvideo.h @@ -251,7 +251,7 @@ struct uvc_frame { u32 dwMaxVideoFrameBufferSize; u8 bFrameIntervalType; u32 dwDefaultFrameInterval; - u32 *dwFrameInterval; + const u32 *dwFrameInterval; }; struct uvc_format { @@ -265,7 +265,7 @@ struct uvc_format { u32 flags; unsigned int nframes; - struct uvc_frame *frame; + const struct uvc_frame *frames; }; struct uvc_streaming_header { @@ -438,12 +438,12 @@ struct uvc_streaming { enum v4l2_buf_type type; unsigned int nformats; - struct uvc_format *format; + const struct uvc_format *formats; struct uvc_streaming_control ctrl; - struct uvc_format *def_format; - struct uvc_format *cur_format; - struct uvc_frame *cur_frame; + const struct uvc_format *def_format; + const struct uvc_format *cur_format; + const struct uvc_frame *cur_frame; /* * Protect access to ctrl, cur_format, cur_frame and hardware video |