diff options
Diffstat (limited to 'drivers/media/usb')
25 files changed, 413 insertions, 199 deletions
diff --git a/drivers/media/usb/airspy/airspy.c b/drivers/media/usb/airspy/airspy.c index 87c129304..92d9d4214 100644 --- a/drivers/media/usb/airspy/airspy.c +++ b/drivers/media/usb/airspy/airspy.c @@ -1072,7 +1072,7 @@ static int airspy_probe(struct usb_interface *intf, if (ret) { dev_err(s->dev, "Failed to register as video device (%d)\n", ret); - goto err_unregister_v4l2_dev; + goto err_free_controls; } dev_info(s->dev, "Registered as %s\n", video_device_node_name(&s->vdev)); @@ -1081,7 +1081,6 @@ static int airspy_probe(struct usb_interface *intf, err_free_controls: v4l2_ctrl_handler_free(&s->hdl); -err_unregister_v4l2_dev: v4l2_device_unregister(&s->v4l2_dev); err_free_mem: kfree(s); diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c index cc22b3277..321ea5cf1 100644 --- a/drivers/media/usb/au0828/au0828-core.c +++ b/drivers/media/usb/au0828/au0828-core.c @@ -131,22 +131,36 @@ static int recv_control_msg(struct au0828_dev *dev, u16 request, u32 value, return status; } +#ifdef CONFIG_MEDIA_CONTROLLER +static void au0828_media_graph_notify(struct media_entity *new, + void *notify_data); +#endif + static void au0828_unregister_media_device(struct au0828_dev *dev) { - #ifdef CONFIG_MEDIA_CONTROLLER - if (dev->media_dev && - media_devnode_is_registered(&dev->media_dev->devnode)) { - /* clear enable_source, disable_source */ - dev->media_dev->source_priv = NULL; - dev->media_dev->enable_source = NULL; - dev->media_dev->disable_source = NULL; - - media_device_unregister(dev->media_dev); - media_device_cleanup(dev->media_dev); - kfree(dev->media_dev); - dev->media_dev = NULL; + struct media_device *mdev = dev->media_dev; + struct media_entity_notify *notify, *nextp; + + if (!mdev || !media_devnode_is_registered(&mdev->devnode)) + return; + + /* Remove au0828 entity_notify callbacks */ + list_for_each_entry_safe(notify, nextp, &mdev->entity_notify, list) { + if (notify->notify != au0828_media_graph_notify) + continue; + media_device_unregister_entity_notify(mdev, notify); } + + /* clear enable_source, disable_source */ + dev->media_dev->source_priv = NULL; + dev->media_dev->enable_source = NULL; + dev->media_dev->disable_source = NULL; + + media_device_unregister(dev->media_dev); + media_device_cleanup(dev->media_dev); + kfree(dev->media_dev); + dev->media_dev = NULL; #endif } diff --git a/drivers/media/usb/au0828/au0828-video.c b/drivers/media/usb/au0828/au0828-video.c index 32d7db964..7d0ec4cb2 100644 --- a/drivers/media/usb/au0828/au0828-video.c +++ b/drivers/media/usb/au0828/au0828-video.c @@ -679,8 +679,6 @@ int au0828_v4l2_device_register(struct usb_interface *interface, if (retval) { pr_err("%s() v4l2_device_register failed\n", __func__); - mutex_unlock(&dev->lock); - kfree(dev); return retval; } @@ -691,8 +689,6 @@ int au0828_v4l2_device_register(struct usb_interface *interface, if (retval) { pr_err("%s() v4l2_ctrl_handler_init failed\n", __func__); - mutex_unlock(&dev->lock); - kfree(dev); return retval; } dev->v4l2_dev.ctrl_handler = &dev->v4l2_ctrl_hdl; diff --git a/drivers/media/usb/au0828/au0828.h b/drivers/media/usb/au0828/au0828.h index 87f32846f..dd7b378fe 100644 --- a/drivers/media/usb/au0828/au0828.h +++ b/drivers/media/usb/au0828/au0828.h @@ -55,7 +55,6 @@ #define NTSC_STD_H 480 #define AU0828_INTERLACED_DEFAULT 1 -#define V4L2_CID_PRIVATE_SHARPNESS (V4L2_CID_PRIVATE_BASE + 0) /* Defination for AU0828 USB transfer */ #define AU0828_MAX_ISO_BUFS 12 /* maybe resize this value in the future */ diff --git a/drivers/media/usb/cx231xx/cx231xx-417.c b/drivers/media/usb/cx231xx/cx231xx-417.c index 9a3dd944e..fd8b39534 100644 --- a/drivers/media/usb/cx231xx/cx231xx-417.c +++ b/drivers/media/usb/cx231xx/cx231xx-417.c @@ -360,7 +360,7 @@ static int wait_for_mci_complete(struct cx231xx *dev) if (count++ > 100) { dprintk(3, "ERROR: Timeout - gpio=%x\n", gpio); - return -1; + return -EIO; } } return 0; @@ -856,7 +856,7 @@ static int cx231xx_find_mailbox(struct cx231xx *dev) } } dprintk(3, "Mailbox signature values not found!\n"); - return -1; + return -EIO; } static void mci_write_memory_to_gpio(struct cx231xx *dev, u32 address, u32 value, @@ -960,13 +960,14 @@ static int cx231xx_load_firmware(struct cx231xx *dev) p_fw = p_current_fw; if (p_current_fw == NULL) { dprintk(2, "FAIL!!!\n"); - return -1; + return -ENOMEM; } p_buffer = vmalloc(4096); if (p_buffer == NULL) { dprintk(2, "FAIL!!!\n"); - return -1; + vfree(p_current_fw); + return -ENOMEM; } dprintk(2, "%s()\n", __func__); @@ -989,7 +990,9 @@ static int cx231xx_load_firmware(struct cx231xx *dev) if (retval != 0) { dev_err(dev->dev, "%s: Error with mc417_register_write\n", __func__); - return -1; + vfree(p_current_fw); + vfree(p_buffer); + return retval; } retval = reject_firmware(&firmware, CX231xx_FIRM_IMAGE_NAME, @@ -1001,7 +1004,9 @@ static int cx231xx_load_firmware(struct cx231xx *dev) CX231xx_FIRM_IMAGE_NAME); dev_err(dev->dev, "Please fix your hotplug setup, the board will not work without firmware loaded!\n"); - return -1; + vfree(p_current_fw); + vfree(p_buffer); + return retval; } if (firmware->size != CX231xx_FIRM_IMAGE_SIZE) { @@ -1009,14 +1014,18 @@ static int cx231xx_load_firmware(struct cx231xx *dev) "ERROR: Firmware size mismatch (have %zd, expected %d)\n", firmware->size, CX231xx_FIRM_IMAGE_SIZE); release_firmware(firmware); - return -1; + vfree(p_current_fw); + vfree(p_buffer); + return -EINVAL; } if (0 != memcmp(firmware->data, magic, 8)) { dev_err(dev->dev, "ERROR: Firmware magic mismatch, wrong file?\n"); release_firmware(firmware); - return -1; + vfree(p_current_fw); + vfree(p_buffer); + return -EINVAL; } initGPIO(dev); @@ -1131,21 +1140,21 @@ static int cx231xx_initialize_codec(struct cx231xx *dev) if (retval < 0) { dev_err(dev->dev, "%s: mailbox < 0, error\n", __func__); - return -1; + return retval; } dev->cx23417_mailbox = retval; retval = cx231xx_api_cmd(dev, CX2341X_ENC_PING_FW, 0, 0); if (retval < 0) { dev_err(dev->dev, "ERROR: cx23417 firmware ping failed!\n"); - return -1; + return retval; } retval = cx231xx_api_cmd(dev, CX2341X_ENC_GET_VERSION, 0, 1, &version); if (retval < 0) { dev_err(dev->dev, "ERROR: cx23417 firmware get encoder: version failed!\n"); - return -1; + return retval; } dprintk(1, "cx23417 firmware version is 0x%08x\n", version); msleep(200); diff --git a/drivers/media/usb/cx231xx/cx231xx-core.c b/drivers/media/usb/cx231xx/cx231xx-core.c index f497888d9..630f4fc51 100644 --- a/drivers/media/usb/cx231xx/cx231xx-core.c +++ b/drivers/media/usb/cx231xx/cx231xx-core.c @@ -752,7 +752,8 @@ EXPORT_SYMBOL_GPL(cx231xx_set_mode); int cx231xx_ep5_bulkout(struct cx231xx *dev, u8 *firmware, u16 size) { int errCode = 0; - int actlen, ret = -ENOMEM; + int actlen = -1; + int ret = -ENOMEM; u32 *buffer; buffer = kzalloc(4096, GFP_KERNEL); @@ -1304,6 +1305,9 @@ int cx231xx_dev_init(struct cx231xx *dev) cx231xx_i2c_register(&dev->i2c_bus[1]); cx231xx_i2c_register(&dev->i2c_bus[2]); + errCode = cx231xx_i2c_mux_create(dev); + if (errCode < 0) + return errCode; cx231xx_i2c_mux_register(dev, 0); cx231xx_i2c_mux_register(dev, 1); @@ -1426,8 +1430,7 @@ EXPORT_SYMBOL_GPL(cx231xx_dev_init); void cx231xx_dev_uninit(struct cx231xx *dev) { /* Un Initialize I2C bus */ - cx231xx_i2c_mux_unregister(dev, 1); - cx231xx_i2c_mux_unregister(dev, 0); + cx231xx_i2c_mux_unregister(dev); cx231xx_i2c_unregister(&dev->i2c_bus[2]); cx231xx_i2c_unregister(&dev->i2c_bus[1]); cx231xx_i2c_unregister(&dev->i2c_bus[0]); diff --git a/drivers/media/usb/cx231xx/cx231xx-i2c.c b/drivers/media/usb/cx231xx/cx231xx-i2c.c index a29c345b0..473cd3433 100644 --- a/drivers/media/usb/cx231xx/cx231xx-i2c.c +++ b/drivers/media/usb/cx231xx/cx231xx-i2c.c @@ -557,40 +557,41 @@ int cx231xx_i2c_unregister(struct cx231xx_i2c *bus) * cx231xx_i2c_mux_select() * switch i2c master number 1 between port1 and port3 */ -static int cx231xx_i2c_mux_select(struct i2c_adapter *adap, - void *mux_priv, u32 chan_id) +static int cx231xx_i2c_mux_select(struct i2c_mux_core *muxc, u32 chan_id) { - struct cx231xx *dev = mux_priv; + struct cx231xx *dev = i2c_mux_priv(muxc); return cx231xx_enable_i2c_port_3(dev, chan_id); } +int cx231xx_i2c_mux_create(struct cx231xx *dev) +{ + dev->muxc = i2c_mux_alloc(&dev->i2c_bus[1].i2c_adap, dev->dev, 2, 0, 0, + cx231xx_i2c_mux_select, NULL); + if (!dev->muxc) + return -ENOMEM; + dev->muxc->priv = dev; + return 0; +} + int cx231xx_i2c_mux_register(struct cx231xx *dev, int mux_no) { - struct i2c_adapter *i2c_parent = &dev->i2c_bus[1].i2c_adap; - /* what is the correct mux_dev? */ - struct device *mux_dev = dev->dev; - - dev->i2c_mux_adap[mux_no] = i2c_add_mux_adapter(i2c_parent, - mux_dev, - dev /* mux_priv */, - 0, - mux_no /* chan_id */, - 0 /* class */, - &cx231xx_i2c_mux_select, - NULL); - - if (!dev->i2c_mux_adap[mux_no]) + int rc; + + rc = i2c_mux_add_adapter(dev->muxc, + 0, + mux_no /* chan_id */, + 0 /* class */); + if (rc) dev_warn(dev->dev, "i2c mux %d register FAILED\n", mux_no); - return 0; + return rc; } -void cx231xx_i2c_mux_unregister(struct cx231xx *dev, int mux_no) +void cx231xx_i2c_mux_unregister(struct cx231xx *dev) { - i2c_del_mux_adapter(dev->i2c_mux_adap[mux_no]); - dev->i2c_mux_adap[mux_no] = NULL; + i2c_mux_del_adapters(dev->muxc); } struct i2c_adapter *cx231xx_get_i2c_adap(struct cx231xx *dev, int i2c_port) @@ -603,9 +604,9 @@ struct i2c_adapter *cx231xx_get_i2c_adap(struct cx231xx *dev, int i2c_port) case I2C_2: return &dev->i2c_bus[2].i2c_adap; case I2C_1_MUX_1: - return dev->i2c_mux_adap[0]; + return dev->muxc->adapter[0]; case I2C_1_MUX_3: - return dev->i2c_mux_adap[1]; + return dev->muxc->adapter[1]; default: return NULL; } diff --git a/drivers/media/usb/cx231xx/cx231xx.h b/drivers/media/usb/cx231xx/cx231xx.h index 69f6d2087..90c867683 100644 --- a/drivers/media/usb/cx231xx/cx231xx.h +++ b/drivers/media/usb/cx231xx/cx231xx.h @@ -624,6 +624,7 @@ struct cx231xx { /* I2C adapters: Master 1 & 2 (External) & Master 3 (Internal only) */ struct cx231xx_i2c i2c_bus[3]; + struct i2c_mux_core *muxc; struct i2c_adapter *i2c_mux_adap[2]; unsigned int xc_fw_load_done:1; @@ -760,8 +761,9 @@ int cx231xx_reset_analog_tuner(struct cx231xx *dev); void cx231xx_do_i2c_scan(struct cx231xx *dev, int i2c_port); int cx231xx_i2c_register(struct cx231xx_i2c *bus); int cx231xx_i2c_unregister(struct cx231xx_i2c *bus); +int cx231xx_i2c_mux_create(struct cx231xx *dev); int cx231xx_i2c_mux_register(struct cx231xx *dev, int mux_no); -void cx231xx_i2c_mux_unregister(struct cx231xx *dev, int mux_no); +void cx231xx_i2c_mux_unregister(struct cx231xx *dev); struct i2c_adapter *cx231xx_get_i2c_adap(struct cx231xx *dev, int i2c_port); /* Internal block control functions */ diff --git a/drivers/media/usb/dvb-usb-v2/af9015.c b/drivers/media/usb/dvb-usb-v2/af9015.c index 56f43ce32..1bb2d64d5 100644 --- a/drivers/media/usb/dvb-usb-v2/af9015.c +++ b/drivers/media/usb/dvb-usb-v2/af9015.c @@ -398,6 +398,8 @@ error: } #define AF9015_EEPROM_SIZE 256 +/* 2^31 + 2^29 - 2^25 + 2^22 - 2^19 - 2^16 + 1 */ +#define GOLDEN_RATIO_PRIME_32 0x9e370001UL /* hash (and dump) eeprom */ static int af9015_eeprom_hash(struct dvb_usb_device *d) diff --git a/drivers/media/usb/dvb-usb-v2/af9035.h b/drivers/media/usb/dvb-usb-v2/af9035.h index c927c1c0f..dc5849c6b 100644 --- a/drivers/media/usb/dvb-usb-v2/af9035.h +++ b/drivers/media/usb/dvb-usb-v2/af9035.h @@ -118,20 +118,20 @@ static const u32 clock_lut_it9135[] = { * Values 0, 3 and 5 are seen to this day. 0 for single TS and 3/5 for dual TS. */ -#define EEPROM_BASE_AF9035 0x42fd -#define EEPROM_BASE_IT9135 0x499c +#define EEPROM_BASE_AF9035 0x42f5 +#define EEPROM_BASE_IT9135 0x4994 #define EEPROM_SHIFT 0x10 -#define EEPROM_IR_MODE 0x10 -#define EEPROM_TS_MODE 0x29 -#define EEPROM_2ND_DEMOD_ADDR 0x2a -#define EEPROM_IR_TYPE 0x2c -#define EEPROM_1_IF_L 0x30 -#define EEPROM_1_IF_H 0x31 -#define EEPROM_1_TUNER_ID 0x34 -#define EEPROM_2_IF_L 0x40 -#define EEPROM_2_IF_H 0x41 -#define EEPROM_2_TUNER_ID 0x44 +#define EEPROM_IR_MODE 0x18 +#define EEPROM_TS_MODE 0x31 +#define EEPROM_2ND_DEMOD_ADDR 0x32 +#define EEPROM_IR_TYPE 0x34 +#define EEPROM_1_IF_L 0x38 +#define EEPROM_1_IF_H 0x39 +#define EEPROM_1_TUNER_ID 0x3c +#define EEPROM_2_IF_L 0x48 +#define EEPROM_2_IF_H 0x49 +#define EEPROM_2_TUNER_ID 0x4c /* USB commands */ #define CMD_MEM_RD 0x00 diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c index fa72642d4..eb7af8cb8 100644 --- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c +++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c @@ -1333,10 +1333,7 @@ static int rtl2832u_tuner_attach(struct dvb_usb_adapter *adap) case TUNER_RTL2832_R828D: pdata.clk = dev->rtl2832_platform_data.clk; pdata.tuner = dev->tuner; - pdata.i2c_client = dev->i2c_client_demod; - pdata.bulk_read = dev->rtl2832_platform_data.bulk_read; - pdata.bulk_write = dev->rtl2832_platform_data.bulk_write; - pdata.update_bits = dev->rtl2832_platform_data.update_bits; + pdata.regmap = dev->rtl2832_platform_data.regmap; pdata.dvb_frontend = adap->fe[0]; pdata.dvb_usb_device = d; pdata.v4l2_subdev = subdev; diff --git a/drivers/media/usb/dvb-usb/az6027.c b/drivers/media/usb/dvb-usb/az6027.c index 977c07a2f..b76437965 100644 --- a/drivers/media/usb/dvb-usb/az6027.c +++ b/drivers/media/usb/dvb-usb/az6027.c @@ -1090,6 +1090,7 @@ static struct usb_device_id az6027_usb_table[] = { { USB_DEVICE(USB_VID_TECHNISAT, USB_PID_TECHNISAT_USB2_HDCI_V2) }, { USB_DEVICE(USB_VID_ELGATO, USB_PID_ELGATO_EYETV_SAT) }, { USB_DEVICE(USB_VID_ELGATO, USB_PID_ELGATO_EYETV_SAT_V2) }, + { USB_DEVICE(USB_VID_ELGATO, USB_PID_ELGATO_EYETV_SAT_V3) }, { }, }; @@ -1138,7 +1139,7 @@ static struct dvb_usb_device_properties az6027_properties = { .i2c_algo = &az6027_i2c_algo, - .num_device_descs = 7, + .num_device_descs = 8, .devices = { { .name = "AZUREWAVE DVB-S/S2 USB2.0 (AZ6027)", @@ -1168,6 +1169,10 @@ static struct dvb_usb_device_properties az6027_properties = { .name = "Elgato EyeTV Sat", .cold_ids = { &az6027_usb_table[6], NULL }, .warm_ids = { NULL }, + }, { + .name = "Elgato EyeTV Sat", + .cold_ids = { &az6027_usb_table[7], NULL }, + .warm_ids = { NULL }, }, { NULL }, } diff --git a/drivers/media/usb/dvb-usb/dib0700_core.c b/drivers/media/usb/dvb-usb/dib0700_core.c index bea4b5909..128e89613 100644 --- a/drivers/media/usb/dvb-usb/dib0700_core.c +++ b/drivers/media/usb/dvb-usb/dib0700_core.c @@ -517,7 +517,7 @@ int dib0700_download_firmware(struct usb_device *udev, const struct firmware *fw if (nb_packet_buffer_size < 1) nb_packet_buffer_size = 1; - /* get the fimware version */ + /* get the firmware version */ usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), REQUEST_GET_VERSION, USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, diff --git a/drivers/media/usb/dvb-usb/dib0700_devices.c b/drivers/media/usb/dvb-usb/dib0700_devices.c index 9b719ef6e..ad25ce34a 100644 --- a/drivers/media/usb/dvb-usb/dib0700_devices.c +++ b/drivers/media/usb/dvb-usb/dib0700_devices.c @@ -3814,6 +3814,7 @@ struct usb_device_id dib0700_usb_id_table[] = { { USB_DEVICE(USB_VID_PCTV, USB_PID_PCTV_2002E) }, { USB_DEVICE(USB_VID_PCTV, USB_PID_PCTV_2002E_SE) }, { USB_DEVICE(USB_VID_PCTV, USB_PID_DIBCOM_STK8096PVR) }, + { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK8096PVR) }, { 0 } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table); @@ -5017,7 +5018,8 @@ struct dvb_usb_device_properties dib0700_devices[] = { .num_device_descs = 1, .devices = { { "DiBcom STK8096-PVR reference design", - { &dib0700_usb_id_table[83], NULL }, + { &dib0700_usb_id_table[83], + &dib0700_usb_id_table[84], NULL}, { NULL }, }, }, diff --git a/drivers/media/usb/dvb-usb/dibusb-common.c b/drivers/media/usb/dvb-usb/dibusb-common.c index 35de60959..6eea4e688 100644 --- a/drivers/media/usb/dvb-usb/dibusb-common.c +++ b/drivers/media/usb/dvb-usb/dibusb-common.c @@ -184,6 +184,8 @@ int dibusb_read_eeprom_byte(struct dvb_usb_device *d, u8 offs, u8 *val) } EXPORT_SYMBOL(dibusb_read_eeprom_byte); +#if IS_ENABLED(CONFIG_DVB_DIB3000MC) + /* 3000MC/P stuff */ // Config Adjacent channels Perf -cal22 static struct dibx000_agc_config dib3000p_mt2060_agc_config = { @@ -242,8 +244,6 @@ static struct dibx000_agc_config dib3000p_panasonic_agc_config = { .agc2_slope2 = 0x1e, }; -#if IS_ENABLED(CONFIG_DVB_DIB3000MC) - static struct dib3000mc_config mod3000p_dib3000p_config = { &dib3000p_panasonic_agc_config, diff --git a/drivers/media/usb/dvb-usb/dw2102.c b/drivers/media/usb/dvb-usb/dw2102.c index eaa1d906d..ec5d4caf3 100644 --- a/drivers/media/usb/dvb-usb/dw2102.c +++ b/drivers/media/usb/dvb-usb/dw2102.c @@ -13,6 +13,7 @@ * * see Documentation/dvb/README.dvb-usb for more information */ +#include "dvb-usb-ids.h" #include "dw2102.h" #include "si21xx.h" #include "stv0299.h" @@ -38,61 +39,6 @@ /* Max transfer size done by I2C transfer functions */ #define MAX_XFER_SIZE 64 -#ifndef USB_PID_DW2102 -#define USB_PID_DW2102 0x2102 -#endif - -#ifndef USB_PID_DW2104 -#define USB_PID_DW2104 0x2104 -#endif - -#ifndef USB_PID_DW3101 -#define USB_PID_DW3101 0x3101 -#endif - -#ifndef USB_PID_CINERGY_S -#define USB_PID_CINERGY_S 0x0064 -#endif - -#ifndef USB_PID_TEVII_S630 -#define USB_PID_TEVII_S630 0xd630 -#endif - -#ifndef USB_PID_TEVII_S650 -#define USB_PID_TEVII_S650 0xd650 -#endif - -#ifndef USB_PID_TEVII_S660 -#define USB_PID_TEVII_S660 0xd660 -#endif - -#ifndef USB_PID_TEVII_S662 -#define USB_PID_TEVII_S662 0xd662 -#endif - -#ifndef USB_PID_TEVII_S480_1 -#define USB_PID_TEVII_S480_1 0xd481 -#endif - -#ifndef USB_PID_TEVII_S480_2 -#define USB_PID_TEVII_S480_2 0xd482 -#endif - -#ifndef USB_PID_PROF_1100 -#define USB_PID_PROF_1100 0xb012 -#endif - -#ifndef USB_PID_TEVII_S421 -#define USB_PID_TEVII_S421 0xd421 -#endif - -#ifndef USB_PID_TEVII_S632 -#define USB_PID_TEVII_S632 0xd632 -#endif - -#ifndef USB_PID_GOTVIEW_SAT_HD -#define USB_PID_GOTVIEW_SAT_HD 0x5456 -#endif #define DW210X_READ_MSG 0 #define DW210X_WRITE_MSG 1 @@ -1709,7 +1655,7 @@ static struct usb_device_id dw2102_table[] = { [CYPRESS_DW2101] = {USB_DEVICE(USB_VID_CYPRESS, 0x2101)}, [CYPRESS_DW2104] = {USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW2104)}, [TEVII_S650] = {USB_DEVICE(0x9022, USB_PID_TEVII_S650)}, - [TERRATEC_CINERGY_S] = {USB_DEVICE(USB_VID_TERRATEC, USB_PID_CINERGY_S)}, + [TERRATEC_CINERGY_S] = {USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_S)}, [CYPRESS_DW3101] = {USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW3101)}, [TEVII_S630] = {USB_DEVICE(0x9022, USB_PID_TEVII_S630)}, [PROF_1100] = {USB_DEVICE(0x3011, USB_PID_PROF_1100)}, @@ -1801,7 +1747,7 @@ static int dw2102_load_firmware(struct usb_device *dev, dw210x_op_rw(dev, 0xbf, 0x0040, 0, &reset, 0, DW210X_WRITE_MSG); break; - case USB_PID_CINERGY_S: + case USB_PID_TERRATEC_CINERGY_S: case USB_PID_DW2102: dw210x_op_rw(dev, 0xbf, 0x0040, 0, &reset, 0, DW210X_WRITE_MSG); @@ -1843,6 +1789,9 @@ static int dw2102_load_firmware(struct usb_device *dev, msleep(100); kfree(p); } + + if (le16_to_cpu(dev->descriptor.idProduct) == 0x2101) + release_firmware(fw); return ret; } diff --git a/drivers/media/usb/dvb-usb/pctv452e.c b/drivers/media/usb/dvb-usb/pctv452e.c index ec397c4b7..c05de1b08 100644 --- a/drivers/media/usb/dvb-usb/pctv452e.c +++ b/drivers/media/usb/dvb-usb/pctv452e.c @@ -995,11 +995,11 @@ static struct dvb_usb_device_properties tt_connect_s2_3600_properties = { /* parameter for the MPEG2-data transfer */ .stream = { .type = USB_ISOC, - .count = 7, + .count = 4, .endpoint = 0x02, .u = { .isoc = { - .framesperurb = 4, + .framesperurb = 64, .framesize = 940, .interval = 1 } diff --git a/drivers/media/usb/em28xx/Kconfig b/drivers/media/usb/em28xx/Kconfig index e382210c4..d917b0a2b 100644 --- a/drivers/media/usb/em28xx/Kconfig +++ b/drivers/media/usb/em28xx/Kconfig @@ -59,6 +59,8 @@ config VIDEO_EM28XX_DVB select DVB_DRX39XYJ if MEDIA_SUBDRV_AUTOSELECT select DVB_SI2168 if MEDIA_SUBDRV_AUTOSELECT select MEDIA_TUNER_SI2157 if MEDIA_SUBDRV_AUTOSELECT + select DVB_TC90522 if MEDIA_SUBDRV_AUTOSELECT + select MEDIA_TUNER_QM1D1C0042 if MEDIA_SUBDRV_AUTOSELECT ---help--- This adds support for DVB cards based on the Empiatech em28xx chips. diff --git a/drivers/media/usb/em28xx/em28xx-cards.c b/drivers/media/usb/em28xx/em28xx-cards.c index d08453fcc..9227495e2 100644 --- a/drivers/media/usb/em28xx/em28xx-cards.c +++ b/drivers/media/usb/em28xx/em28xx-cards.c @@ -492,6 +492,44 @@ static struct em28xx_reg_seq terratec_t2_stick_hd[] = { {-1, -1, -1, -1}, }; +static struct em28xx_reg_seq plex_px_bcud[] = { + {EM2874_R80_GPIO_P0_CTRL, 0xff, 0xff, 0}, + {0x0d, 0xff, 0xff, 0}, + {EM2874_R50_IR_CONFIG, 0x01, 0xff, 0}, + {EM28XX_R06_I2C_CLK, 0x40, 0xff, 0}, + {EM2874_R80_GPIO_P0_CTRL, 0xfd, 0xff, 100}, + {EM28XX_R12_VINENABLE, 0x20, 0x20, 0}, + {0x0d, 0x42, 0xff, 1000}, + {EM2874_R80_GPIO_P0_CTRL, 0xfc, 0xff, 10}, + {EM2874_R80_GPIO_P0_CTRL, 0xfd, 0xff, 10}, + {0x73, 0xfd, 0xff, 100}, + {-1, -1, -1, -1}, +}; + +/* + * 2040:0265 Hauppauge WinTV-dualHD DVB + * reg 0x80/0x84: + * GPIO_0: Yellow LED tuner 1, 0=on, 1=off + * GPIO_1: Green LED tuner 1, 0=on, 1=off + * GPIO_2: Yellow LED tuner 2, 0=on, 1=off + * GPIO_3: Green LED tuner 2, 0=on, 1=off + * GPIO_5: Reset #2, 0=active + * GPIO_6: Reset #1, 0=active + */ +static struct em28xx_reg_seq hauppauge_dualhd_dvb[] = { + {EM2874_R80_GPIO_P0_CTRL, 0xff, 0xff, 0}, + {0x0d, 0xff, 0xff, 200}, + {0x50, 0x04, 0xff, 300}, + {EM2874_R80_GPIO_P0_CTRL, 0xbf, 0xff, 100}, /* demod 1 reset */ + {EM2874_R80_GPIO_P0_CTRL, 0xff, 0xff, 100}, + {EM2874_R80_GPIO_P0_CTRL, 0xdf, 0xff, 100}, /* demod 2 reset */ + {EM2874_R80_GPIO_P0_CTRL, 0xff, 0xff, 100}, + {EM2874_R5F_TS_ENABLE, 0x44, 0xff, 50}, + {EM2874_R5D_TS1_PKT_SIZE, 0x05, 0xff, 50}, + {EM2874_R5E_TS2_PKT_SIZE, 0x05, 0xff, 50}, + {-1, -1, -1, -1}, +}; + /* * Button definitions */ @@ -571,6 +609,22 @@ static struct em28xx_led terratec_grabby_leds[] = { {-1, 0, 0, 0}, }; +static struct em28xx_led hauppauge_dualhd_leds[] = { + { + .role = EM28XX_LED_DIGITAL_CAPTURING, + .gpio_reg = EM2874_R80_GPIO_P0_CTRL, + .gpio_mask = EM_GPIO_1, + .inverted = 1, + }, + { + .role = EM28XX_LED_DIGITAL_CAPTURING_TS2, + .gpio_reg = EM2874_R80_GPIO_P0_CTRL, + .gpio_mask = EM_GPIO_3, + .inverted = 1, + }, + {-1, 0, 0, 0}, +}; + /* * Board definitions */ @@ -2306,6 +2360,35 @@ struct em28xx_board em28xx_boards[] = { .has_dvb = 1, .ir_codes = RC_MAP_TERRATEC_SLIM_2, }, + + /* + * 3275:0085 PLEX PX-BCUD. + * Empia EM28178, TOSHIBA TC90532XBG, Sharp QM1D1C0042 + */ + [EM28178_BOARD_PLEX_PX_BCUD] = { + .name = "PLEX PX-BCUD", + .xclk = EM28XX_XCLK_FREQUENCY_4_3MHZ, + .def_i2c_bus = 1, + .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE, + .tuner_type = TUNER_ABSENT, + .tuner_gpio = plex_px_bcud, + .has_dvb = 1, + }, + /* + * 2040:0265 Hauppauge WinTV-dualHD (DVB version). + * Empia EM28274, 2x Silicon Labs Si2168, 2x Silicon Labs Si2157 + */ + [EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_DVB] = { + .name = "Hauppauge WinTV-dualHD DVB", + .def_i2c_bus = 1, + .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE | + EM28XX_I2C_FREQ_400_KHZ, + .tuner_type = TUNER_ABSENT, + .tuner_gpio = hauppauge_dualhd_dvb, + .has_dvb = 1, + .ir_codes = RC_MAP_HAUPPAUGE, + .leds = hauppauge_dualhd_leds, + }, }; EXPORT_SYMBOL_GPL(em28xx_boards); @@ -2429,6 +2512,8 @@ struct usb_device_id em28xx_id_table[] = { .driver_info = EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950 }, { USB_DEVICE(0x2040, 0x651f), .driver_info = EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850 }, + { USB_DEVICE(0x2040, 0x0265), + .driver_info = EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_DVB }, { USB_DEVICE(0x0438, 0xb002), .driver_info = EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600 }, { USB_DEVICE(0x2001, 0xf112), @@ -2495,6 +2580,8 @@ struct usb_device_id em28xx_id_table[] = { .driver_info = EM2861_BOARD_LEADTEK_VC100 }, { USB_DEVICE(0xeb1a, 0x8179), .driver_info = EM28178_BOARD_TERRATEC_T2_STICK_HD }, + { USB_DEVICE(0x3275, 0x0085), + .driver_info = EM28178_BOARD_PLEX_PX_BCUD }, { }, }; MODULE_DEVICE_TABLE(usb, em28xx_id_table); @@ -2861,6 +2948,7 @@ static void em28xx_card_setup(struct em28xx *dev) case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850: case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950: case EM2884_BOARD_HAUPPAUGE_WINTV_HVR_930C: + case EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_DVB: { struct tveeprom tv; diff --git a/drivers/media/usb/em28xx/em28xx-dvb.c b/drivers/media/usb/em28xx/em28xx-dvb.c index 3ef56ae62..7ec9ce2cd 100644 --- a/drivers/media/usb/em28xx/em28xx-dvb.c +++ b/drivers/media/usb/em28xx/em28xx-dvb.c @@ -58,6 +58,8 @@ #include "ts2020.h" #include "si2168.h" #include "si2157.h" +#include "tc90522.h" +#include "qm1d1c0042.h" MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>"); MODULE_LICENSE("GPL"); @@ -787,6 +789,68 @@ static int em28xx_mt352_terratec_xs_init(struct dvb_frontend *fe) return 0; } +static void px_bcud_init(struct em28xx *dev) +{ + int i; + struct { + unsigned char r[4]; + int len; + } regs1[] = { + {{ 0x0e, 0x77 }, 2}, + {{ 0x0f, 0x77 }, 2}, + {{ 0x03, 0x90 }, 2}, + }, regs2[] = { + {{ 0x07, 0x01 }, 2}, + {{ 0x08, 0x10 }, 2}, + {{ 0x13, 0x00 }, 2}, + {{ 0x17, 0x00 }, 2}, + {{ 0x03, 0x01 }, 2}, + {{ 0x10, 0xb1 }, 2}, + {{ 0x11, 0x40 }, 2}, + {{ 0x85, 0x7a }, 2}, + {{ 0x87, 0x04 }, 2}, + }; + static struct em28xx_reg_seq gpio[] = { + {EM28XX_R06_I2C_CLK, 0x40, 0xff, 300}, + {EM2874_R80_GPIO_P0_CTRL, 0xfd, 0xff, 60}, + {EM28XX_R15_RGAIN, 0x20, 0xff, 0}, + {EM28XX_R16_GGAIN, 0x20, 0xff, 0}, + {EM28XX_R17_BGAIN, 0x20, 0xff, 0}, + {EM28XX_R18_ROFFSET, 0x00, 0xff, 0}, + {EM28XX_R19_GOFFSET, 0x00, 0xff, 0}, + {EM28XX_R1A_BOFFSET, 0x00, 0xff, 0}, + {EM28XX_R23_UOFFSET, 0x00, 0xff, 0}, + {EM28XX_R24_VOFFSET, 0x00, 0xff, 0}, + {EM28XX_R26_COMPR, 0x00, 0xff, 0}, + {0x13, 0x08, 0xff, 0}, + {EM28XX_R12_VINENABLE, 0x27, 0xff, 0}, + {EM28XX_R0C_USBSUSP, 0x10, 0xff, 0}, + {EM28XX_R27_OUTFMT, 0x00, 0xff, 0}, + {EM28XX_R10_VINMODE, 0x00, 0xff, 0}, + {EM28XX_R11_VINCTRL, 0x11, 0xff, 0}, + {EM2874_R50_IR_CONFIG, 0x01, 0xff, 0}, + {EM2874_R5F_TS_ENABLE, 0x80, 0xff, 0}, + {EM28XX_R06_I2C_CLK, 0x46, 0xff, 0}, + }; + em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x46); + /* sleeping ISDB-T */ + dev->dvb->i2c_client_demod->addr = 0x14; + for (i = 0; i < ARRAY_SIZE(regs1); i++) + i2c_master_send(dev->dvb->i2c_client_demod, regs1[i].r, + regs1[i].len); + /* sleeping ISDB-S */ + dev->dvb->i2c_client_demod->addr = 0x15; + for (i = 0; i < ARRAY_SIZE(regs2); i++) + i2c_master_send(dev->dvb->i2c_client_demod, regs2[i].r, + regs2[i].len); + for (i = 0; i < ARRAY_SIZE(gpio); i++) { + em28xx_write_reg_bits(dev, gpio[i].reg, gpio[i].val, + gpio[i].mask); + if (gpio[i].sleep > 0) + msleep(gpio[i].sleep); + } +}; + static struct mt352_config terratec_xs_mt352_cfg = { .demod_address = (0x1e >> 1), .no_tuner = 1, @@ -1762,6 +1826,127 @@ static int em28xx_dvb_init(struct em28xx *dev) dvb->i2c_client_tuner = client; } break; + + case EM28178_BOARD_PLEX_PX_BCUD: + { + struct i2c_client *client; + struct i2c_board_info info; + struct tc90522_config tc90522_config; + struct qm1d1c0042_config qm1d1c0042_config; + + /* attach demod */ + memset(&tc90522_config, 0, sizeof(tc90522_config)); + memset(&info, 0, sizeof(struct i2c_board_info)); + strlcpy(info.type, "tc90522sat", I2C_NAME_SIZE); + info.addr = 0x15; + info.platform_data = &tc90522_config; + request_module("tc90522"); + client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], &info); + if (client == NULL || client->dev.driver == NULL) { + result = -ENODEV; + goto out_free; + } + dvb->i2c_client_demod = client; + if (!try_module_get(client->dev.driver->owner)) { + i2c_unregister_device(client); + result = -ENODEV; + goto out_free; + } + + /* attach tuner */ + memset(&qm1d1c0042_config, 0, + sizeof(qm1d1c0042_config)); + qm1d1c0042_config.fe = tc90522_config.fe; + qm1d1c0042_config.lpf = 1; + memset(&info, 0, sizeof(struct i2c_board_info)); + strlcpy(info.type, "qm1d1c0042", I2C_NAME_SIZE); + info.addr = 0x61; + info.platform_data = &qm1d1c0042_config; + request_module(info.type); + client = i2c_new_device(tc90522_config.tuner_i2c, + &info); + if (client == NULL || client->dev.driver == NULL) { + module_put(dvb->i2c_client_demod->dev.driver->owner); + i2c_unregister_device(dvb->i2c_client_demod); + result = -ENODEV; + goto out_free; + } + dvb->i2c_client_tuner = client; + if (!try_module_get(client->dev.driver->owner)) { + i2c_unregister_device(client); + module_put(dvb->i2c_client_demod->dev.driver->owner); + i2c_unregister_device(dvb->i2c_client_demod); + result = -ENODEV; + goto out_free; + } + dvb->fe[0] = tc90522_config.fe; + px_bcud_init(dev); + } + break; + case EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_DVB: + { + struct i2c_adapter *adapter; + struct i2c_client *client; + struct i2c_board_info info; + struct si2168_config si2168_config; + struct si2157_config si2157_config; + + /* attach demod */ + memset(&si2168_config, 0, sizeof(si2168_config)); + si2168_config.i2c_adapter = &adapter; + si2168_config.fe = &dvb->fe[0]; + si2168_config.ts_mode = SI2168_TS_SERIAL; + memset(&info, 0, sizeof(struct i2c_board_info)); + strlcpy(info.type, "si2168", I2C_NAME_SIZE); + info.addr = 0x64; + info.platform_data = &si2168_config; + request_module(info.type); + client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], &info); + if (client == NULL || client->dev.driver == NULL) { + result = -ENODEV; + goto out_free; + } + + if (!try_module_get(client->dev.driver->owner)) { + i2c_unregister_device(client); + result = -ENODEV; + goto out_free; + } + + dvb->i2c_client_demod = client; + + /* attach tuner */ + memset(&si2157_config, 0, sizeof(si2157_config)); + si2157_config.fe = dvb->fe[0]; + si2157_config.if_port = 1; +#ifdef CONFIG_MEDIA_CONTROLLER_DVB + si2157_config.mdev = dev->media_dev; +#endif + memset(&info, 0, sizeof(struct i2c_board_info)); + strlcpy(info.type, "si2157", I2C_NAME_SIZE); + info.addr = 0x60; + info.platform_data = &si2157_config; + request_module(info.type); + client = i2c_new_device(adapter, &info); + if (client == NULL || client->dev.driver == NULL) { + module_put(dvb->i2c_client_demod->dev.driver->owner); + i2c_unregister_device(dvb->i2c_client_demod); + result = -ENODEV; + goto out_free; + } + + if (!try_module_get(client->dev.driver->owner)) { + i2c_unregister_device(client); + module_put(dvb->i2c_client_demod->dev.driver->owner); + i2c_unregister_device(dvb->i2c_client_demod); + result = -ENODEV; + goto out_free; + } + + dvb->i2c_client_tuner = client; + + } + break; default: em28xx_errdev("/2: The frontend of your DVB/ATSC card" " isn't supported yet\n"); diff --git a/drivers/media/usb/em28xx/em28xx-reg.h b/drivers/media/usb/em28xx/em28xx-reg.h index 13cbb7f3e..afe7a66d7 100644 --- a/drivers/media/usb/em28xx/em28xx-reg.h +++ b/drivers/media/usb/em28xx/em28xx-reg.h @@ -193,6 +193,19 @@ /* em2874 registers */ #define EM2874_R50_IR_CONFIG 0x50 #define EM2874_R51_IR 0x51 +#define EM2874_R5D_TS1_PKT_SIZE 0x5d +#define EM2874_R5E_TS2_PKT_SIZE 0x5e + /* + * For both TS1 and TS2, In isochronous mode: + * 0x01 188 bytes + * 0x02 376 bytes + * 0x03 564 bytes + * 0x04 752 bytes + * 0x05 940 bytes + * In bulk mode: + * 0x01..0xff total packet count in 188-byte + */ + #define EM2874_R5F_TS_ENABLE 0x5f /* em2874/174/84, em25xx, em276x/7x/8x GPIO registers */ diff --git a/drivers/media/usb/em28xx/em28xx.h b/drivers/media/usb/em28xx/em28xx.h index 267444961..d148463b2 100644 --- a/drivers/media/usb/em28xx/em28xx.h +++ b/drivers/media/usb/em28xx/em28xx.h @@ -145,6 +145,8 @@ #define EM2861_BOARD_LEADTEK_VC100 95 #define EM28178_BOARD_TERRATEC_T2_STICK_HD 96 #define EM2884_BOARD_ELGATO_EYETV_HYBRID_2008 97 +#define EM28178_BOARD_PLEX_PX_BCUD 98 +#define EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_DVB 99 /* Limits minimum and default number of buffers */ #define EM28XX_MIN_BUF 4 @@ -406,6 +408,7 @@ enum em28xx_adecoder { enum em28xx_led_role { EM28XX_LED_ANALOG_CAPTURING = 0, EM28XX_LED_DIGITAL_CAPTURING, + EM28XX_LED_DIGITAL_CAPTURING_TS2, EM28XX_LED_ILLUMINATION, EM28XX_NUM_LED_ROLES, /* must be the last */ }; diff --git a/drivers/media/usb/go7007/go7007-v4l2.c b/drivers/media/usb/go7007/go7007-v4l2.c index 358c1c186..ea01ee5df 100644 --- a/drivers/media/usb/go7007/go7007-v4l2.c +++ b/drivers/media/usb/go7007/go7007-v4l2.c @@ -1125,7 +1125,7 @@ int go7007_v4l2_init(struct go7007 *go) vdev->queue = &go->vidq; video_set_drvdata(vdev, go); vdev->v4l2_dev = &go->v4l2_dev; - if (!v4l2_device_has_op(&go->v4l2_dev, video, querystd)) + if (!v4l2_device_has_op(&go->v4l2_dev, 0, video, querystd)) v4l2_disable_ioctl(vdev, VIDIOC_QUERYSTD); if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER)) { v4l2_disable_ioctl(vdev, VIDIOC_S_FREQUENCY); diff --git a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c index 967424f73..203418f87 100644 --- a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c +++ b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c @@ -3672,11 +3672,10 @@ static int pvr2_send_request_ex(struct pvr2_hdw *hdw, hdw->cmd_debug_state = 1; - if (write_len) { + if (write_len && write_data) hdw->cmd_debug_code = ((unsigned char *)write_data)[0]; - } else { + else hdw->cmd_debug_code = 0; - } hdw->cmd_debug_write_len = write_len; hdw->cmd_debug_read_len = read_len; @@ -3688,7 +3687,7 @@ static int pvr2_send_request_ex(struct pvr2_hdw *hdw, setup_timer(&timer, pvr2_ctl_timeout, (unsigned long)hdw); timer.expires = jiffies + timeout; - if (write_len) { + if (write_len && write_data) { hdw->cmd_debug_state = 2; /* Transfer write data to internal buffer */ for (idx = 0; idx < write_len; idx++) { @@ -3795,7 +3794,7 @@ static int pvr2_send_request_ex(struct pvr2_hdw *hdw, goto done; } } - if (read_len) { + if (read_len && read_data) { /* Validate results of read request */ if ((hdw->ctl_read_urb->status != 0) && (hdw->ctl_read_urb->status != -ENOENT) && diff --git a/drivers/media/usb/uvc/uvc_v4l2.c b/drivers/media/usb/uvc/uvc_v4l2.c index 12690c1ea..c04bc6afb 100644 --- a/drivers/media/usb/uvc/uvc_v4l2.c +++ b/drivers/media/usb/uvc/uvc_v4l2.c @@ -1274,8 +1274,6 @@ struct uvc_xu_control_mapping32 { static int uvc_v4l2_get_xu_mapping(struct uvc_xu_control_mapping *kp, const struct uvc_xu_control_mapping32 __user *up) { - struct uvc_menu_info __user *umenus; - struct uvc_menu_info __user *kmenus; compat_caddr_t p; if (!access_ok(VERIFY_READ, up, sizeof(*up)) || @@ -1292,17 +1290,7 @@ static int uvc_v4l2_get_xu_mapping(struct uvc_xu_control_mapping *kp, if (__get_user(p, &up->menu_info)) return -EFAULT; - umenus = compat_ptr(p); - if (!access_ok(VERIFY_READ, umenus, kp->menu_count * sizeof(*umenus))) - return -EFAULT; - - kmenus = compat_alloc_user_space(kp->menu_count * sizeof(*kmenus)); - if (kmenus == NULL) - return -EFAULT; - kp->menu_info = kmenus; - - if (copy_in_user(kmenus, umenus, kp->menu_count * sizeof(*umenus))) - return -EFAULT; + kp->menu_info = compat_ptr(p); return 0; } @@ -1310,10 +1298,6 @@ static int uvc_v4l2_get_xu_mapping(struct uvc_xu_control_mapping *kp, static int uvc_v4l2_put_xu_mapping(const struct uvc_xu_control_mapping *kp, struct uvc_xu_control_mapping32 __user *up) { - struct uvc_menu_info __user *umenus; - struct uvc_menu_info __user *kmenus = kp->menu_info; - compat_caddr_t p; - if (!access_ok(VERIFY_WRITE, up, sizeof(*up)) || __copy_to_user(up, kp, offsetof(typeof(*up), menu_info)) || __put_user(kp->menu_count, &up->menu_count)) @@ -1322,16 +1306,6 @@ static int uvc_v4l2_put_xu_mapping(const struct uvc_xu_control_mapping *kp, if (__clear_user(up->reserved, sizeof(up->reserved))) return -EFAULT; - if (kp->menu_count == 0) - return 0; - - if (get_user(p, &up->menu_info)) - return -EFAULT; - umenus = compat_ptr(p); - - if (copy_in_user(umenus, kmenus, kp->menu_count * sizeof(*umenus))) - return -EFAULT; - return 0; } @@ -1346,8 +1320,6 @@ struct uvc_xu_control_query32 { static int uvc_v4l2_get_xu_query(struct uvc_xu_control_query *kp, const struct uvc_xu_control_query32 __user *up) { - u8 __user *udata; - u8 __user *kdata; compat_caddr_t p; if (!access_ok(VERIFY_READ, up, sizeof(*up)) || @@ -1361,17 +1333,7 @@ static int uvc_v4l2_get_xu_query(struct uvc_xu_control_query *kp, if (__get_user(p, &up->data)) return -EFAULT; - udata = compat_ptr(p); - if (!access_ok(VERIFY_READ, udata, kp->size)) - return -EFAULT; - - kdata = compat_alloc_user_space(kp->size); - if (kdata == NULL) - return -EFAULT; - kp->data = kdata; - - if (copy_in_user(kdata, udata, kp->size)) - return -EFAULT; + kp->data = compat_ptr(p); return 0; } @@ -1379,26 +1341,10 @@ static int uvc_v4l2_get_xu_query(struct uvc_xu_control_query *kp, static int uvc_v4l2_put_xu_query(const struct uvc_xu_control_query *kp, struct uvc_xu_control_query32 __user *up) { - u8 __user *udata; - u8 __user *kdata = kp->data; - compat_caddr_t p; - if (!access_ok(VERIFY_WRITE, up, sizeof(*up)) || __copy_to_user(up, kp, offsetof(typeof(*up), data))) return -EFAULT; - if (kp->size == 0) - return 0; - - if (get_user(p, &up->data)) - return -EFAULT; - udata = compat_ptr(p); - if (!access_ok(VERIFY_READ, udata, kp->size)) - return -EFAULT; - - if (copy_in_user(udata, kdata, kp->size)) - return -EFAULT; - return 0; } |