diff options
author | Greg Kroah-Hartman <gregkh@suse.de> | 2006-03-01 15:59:52 -0800 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2006-03-01 15:59:52 -0800 |
commit | e449d88200084a27997993b78956a6f2b252f2df (patch) | |
tree | ac004a1ce27b9c3a2cb6e25241a81417fb090a43 /usb | |
parent | e946d6a860ccbbc527c85411ff97104eb7904018 (diff) | |
download | patches-e449d88200084a27997993b78956a6f2b252f2df.tar.gz |
usb patches added
Diffstat (limited to 'usb')
-rw-r--r-- | usb/cypress_m8-add-support-for-the-nokia-ca42-version-2-cable.patch | 182 | ||||
-rw-r--r-- | usb/usb-et61x51-driver-updates.patch | 1211 | ||||
-rw-r--r-- | usb/usb-kzalloc-conversion-for-rest-of-drivers-usb.patch | 690 | ||||
-rw-r--r-- | usb/usb-kzalloc-conversion-in-drivers-usb-gadget.patch | 186 | ||||
-rw-r--r-- | usb/usb-pl2303-and-tiocmiwait.patch | 39 | ||||
-rw-r--r-- | usb/usb-serial-dynamic-id.patch | 6 | ||||
-rw-r--r-- | usb/usb-sn9c10x-driver-updates.patch | 1073 | ||||
-rw-r--r-- | usb/usb-support-for-usb-to-serial-cable-from-speed-dragon-multimedia.patch | 42 | ||||
-rw-r--r-- | usb/usb-uhci-increase-port-reset-completion-delay-for-hp-controllers.patch | 59 | ||||
-rw-r--r-- | usb/usb-zc0301-driver-updates-2.patch | 496 |
10 files changed, 3981 insertions, 3 deletions
diff --git a/usb/cypress_m8-add-support-for-the-nokia-ca42-version-2-cable.patch b/usb/cypress_m8-add-support-for-the-nokia-ca42-version-2-cable.patch new file mode 100644 index 0000000000000..a7910af76c86f --- /dev/null +++ b/usb/cypress_m8-add-support-for-the-nokia-ca42-version-2-cable.patch @@ -0,0 +1,182 @@ +From linux-usb-devel-admin@lists.sourceforge.net Wed Mar 1 15:19:12 2006 +Message-ID: <4405CFA4.3010604@austin.rr.com> +From: Lonnie Mendez <lmendez19@austin.rr.com> +To: linux-usb-devel@lists.sourceforge.net +Subject: USB: cypress_m8: add support for the Nokia ca42-version 2 cable +Date: Wed, 01 Mar 2006 10:45:24 -0600 + +This patch adds support for the Nokia ca42 version 2 cable to the +cypress_m8 driver. The device was tested by others with this patch and +found to be compatible with the cypress_m8 driver. A special note +should be taken that this cable seems to vary in the type of chipset +used. This patch supports the cable with product id 0x4101. + +Signed-off-by: Lonnie Mendez <lmendez19@austin.rr.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + + +--- + drivers/usb/serial/cypress_m8.c | 70 ++++++++++++++++++++++++++++++++++++++++ + drivers/usb/serial/cypress_m8.h | 5 ++ + 2 files changed, 75 insertions(+) + +--- gregkh-2.6.orig/drivers/usb/serial/cypress_m8.c ++++ gregkh-2.6/drivers/usb/serial/cypress_m8.c +@@ -98,10 +98,16 @@ static struct usb_device_id id_table_cyp + { } /* Terminating entry */ + }; + ++static struct usb_device_id id_table_nokiaca42v2 [] = { ++ { USB_DEVICE(VENDOR_ID_DAZZLE, PRODUCT_ID_CA42) }, ++ { } /* Terminating entry */ ++}; ++ + static struct usb_device_id id_table_combined [] = { + { USB_DEVICE(VENDOR_ID_DELORME, PRODUCT_ID_EARTHMATEUSB) }, + { USB_DEVICE(VENDOR_ID_DELORME, PRODUCT_ID_EARTHMATEUSB_LT20) }, + { USB_DEVICE(VENDOR_ID_CYPRESS, PRODUCT_ID_CYPHIDCOM) }, ++ { USB_DEVICE(VENDOR_ID_DAZZLE, PRODUCT_ID_CA42) }, + { } /* Terminating entry */ + }; + +@@ -149,6 +155,7 @@ struct cypress_buf { + /* function prototypes for the Cypress USB to serial device */ + static int cypress_earthmate_startup (struct usb_serial *serial); + static int cypress_hidcom_startup (struct usb_serial *serial); ++static int cypress_ca42v2_startup (struct usb_serial *serial); + static void cypress_shutdown (struct usb_serial *serial); + static int cypress_open (struct usb_serial_port *port, struct file *filp); + static void cypress_close (struct usb_serial_port *port, struct file *filp); +@@ -235,6 +242,34 @@ static struct usb_serial_driver cypress_ + .write_int_callback = cypress_write_int_callback, + }; + ++static struct usb_serial_driver cypress_ca42v2_device = { ++ .driver = { ++ .owner = THIS_MODULE, ++ .name = "nokiaca42v2", ++ }, ++ .description = "Nokia CA-42 V2 Adapter", ++ .id_table = id_table_nokiaca42v2, ++ .num_interrupt_in = 1, ++ .num_interrupt_out = 1, ++ .num_bulk_in = NUM_DONT_CARE, ++ .num_bulk_out = NUM_DONT_CARE, ++ .num_ports = 1, ++ .attach = cypress_ca42v2_startup, ++ .shutdown = cypress_shutdown, ++ .open = cypress_open, ++ .close = cypress_close, ++ .write = cypress_write, ++ .write_room = cypress_write_room, ++ .ioctl = cypress_ioctl, ++ .set_termios = cypress_set_termios, ++ .tiocmget = cypress_tiocmget, ++ .tiocmset = cypress_tiocmset, ++ .chars_in_buffer = cypress_chars_in_buffer, ++ .throttle = cypress_throttle, ++ .unthrottle = cypress_unthrottle, ++ .read_int_callback = cypress_read_int_callback, ++ .write_int_callback = cypress_write_int_callback, ++}; + + /***************************************************************************** + * Cypress serial helper functions +@@ -286,6 +321,12 @@ static int cypress_serial_control (struc + __FUNCTION__); + new_baudrate = priv->baud_rate; + } ++ } else if (priv->chiptype == CT_CA42V2) { ++ if ( (new_baudrate = mask_to_rate(baud_mask)) == -1) { ++ err("%s - failed setting baud rate, unsupported speed", ++ __FUNCTION__); ++ new_baudrate = priv->baud_rate; ++ } + } else if (priv->chiptype == CT_GENERIC) { + if ( (new_baudrate = mask_to_rate(baud_mask)) == -1) { + err("%s - failed setting baud rate, unsupported speed", +@@ -499,6 +540,25 @@ static int cypress_hidcom_startup (struc + } /* cypress_hidcom_startup */ + + ++static int cypress_ca42v2_startup (struct usb_serial *serial) ++{ ++ struct cypress_private *priv; ++ ++ dbg("%s", __FUNCTION__); ++ ++ if (generic_startup(serial)) { ++ dbg("%s - Failed setting up port %d", __FUNCTION__, ++ serial->port[0]->number); ++ return 1; ++ } ++ ++ priv = usb_get_serial_port_data(serial->port[0]); ++ priv->chiptype = CT_CA42V2; ++ ++ return 0; ++} /* cypress_ca42v2_startup */ ++ ++ + static void cypress_shutdown (struct usb_serial *serial) + { + struct cypress_private *priv; +@@ -943,6 +1003,10 @@ static void cypress_set_termios (struct + *(tty->termios) = tty_std_termios; + tty->termios->c_cflag = B9600 | CS8 | CREAD | HUPCL | + CLOCAL; ++ } else if (priv->chiptype == CT_CA42V2) { ++ *(tty->termios) = tty_std_termios; ++ tty->termios->c_cflag = B9600 | CS8 | CREAD | HUPCL | ++ CLOCAL; + } + priv->termios_initialized = 1; + } +@@ -1541,6 +1605,9 @@ static int __init cypress_init(void) + retval = usb_serial_register(&cypress_hidcom_device); + if (retval) + goto failed_hidcom_register; ++ retval = usb_serial_register(&cypress_ca42v2_device); ++ if (retval) ++ goto failed_ca42v2_register; + retval = usb_register(&cypress_driver); + if (retval) + goto failed_usb_register; +@@ -1549,6 +1616,8 @@ static int __init cypress_init(void) + return 0; + failed_usb_register: + usb_deregister(&cypress_driver); ++failed_ca42v2_register: ++ usb_serial_deregister(&cypress_ca42v2_device); + failed_hidcom_register: + usb_serial_deregister(&cypress_hidcom_device); + failed_em_register: +@@ -1565,6 +1634,7 @@ static void __exit cypress_exit (void) + usb_deregister (&cypress_driver); + usb_serial_deregister (&cypress_earthmate_device); + usb_serial_deregister (&cypress_hidcom_device); ++ usb_serial_deregister (&cypress_ca42v2_device); + } + + +--- gregkh-2.6.orig/drivers/usb/serial/cypress_m8.h ++++ gregkh-2.6/drivers/usb/serial/cypress_m8.h +@@ -18,6 +18,10 @@ + /* Cypress HID->COM RS232 Adapter */ + #define VENDOR_ID_CYPRESS 0x04b4 + #define PRODUCT_ID_CYPHIDCOM 0x5500 ++ ++/* Nokia CA-42 USB to serial cable */ ++#define VENDOR_ID_DAZZLE 0x07d0 ++#define PRODUCT_ID_CA42 0x4101 + /* End of device listing */ + + /* Used for setting / requesting serial line settings */ +@@ -34,6 +38,7 @@ + + #define CT_EARTHMATE 0x01 + #define CT_CYPHIDCOM 0x02 ++#define CT_CA42V2 0x03 + #define CT_GENERIC 0x0F + /* End of chiptype definitions */ + diff --git a/usb/usb-et61x51-driver-updates.patch b/usb/usb-et61x51-driver-updates.patch new file mode 100644 index 0000000000000..b2b1b194f4af2 --- /dev/null +++ b/usb/usb-et61x51-driver-updates.patch @@ -0,0 +1,1211 @@ +From luca.risolia@studio.unibo.it Fri Feb 24 21:52:39 2006 +Date: Sat, 25 Feb 2006 06:54:18 +0000 +From: Luca Risolia <luca.risolia@studio.unibo.it> +To: Greg Kroah-Hartman <gregkh@suse.de> +Subject: USB: ET61X[12]51 driver updates +Message-ID: <20060225065418.GB31623@studio.unibo.it> +Content-Disposition: inline + +USB: ET61X[12]51 driver updates + +Changes: + new, - removed, * cleanup, @ bugfix + +@ Fix stream_interrupt() +@ Fix vidioc_enum_input() and split vidioc_gs_input() +@ Need usb_get|put_dev() when disconnecting, if the device is open +* Use wait_event_interruptible_timeout() instead of wait_event_interruptible() + when waiting for video frames +* replace wake_up_interruptible(&wait_stream) with wake_up(&wait_stream) +* Cleanups and updates in the documentation +* Use mutexes instead of semaphores ++ Use per-device sensor structures ++ Add support for PAS202BCA image sensors ++ Add frame_timeout module parameter + +Signed-off-by: Luca Risolia <luca.risolia@studio.unibo.it> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + Documentation/usb/et61x251.txt | 10 + drivers/usb/media/et61x251.h | 28 ++ + drivers/usb/media/et61x251_core.c | 321 +++++++++++++++++--------------- + drivers/usb/media/et61x251_sensor.h | 5 + drivers/usb/media/et61x251_tas5130d1b.c | 10 + 5 files changed, 213 insertions(+), 161 deletions(-) + +--- gregkh-2.6.orig/Documentation/usb/et61x251.txt ++++ gregkh-2.6/Documentation/usb/et61x251.txt +@@ -176,6 +176,14 @@ Description: Force the application to + 1 = force memory unmapping (save memory) + Default: 0 + ------------------------------------------------------------------------------- ++Name: frame_timeout ++Type: uint array (min = 0, max = 64) ++Syntax: <n[,...]> ++Description: Timeout for a video frame in seconds. This parameter is ++ specific for each detected camera. This parameter can be ++ changed at runtime thanks to the /sys filesystem interface. ++Default: 2 ++------------------------------------------------------------------------------- + Name: debug + Type: ushort + Syntax: <n> +@@ -266,7 +274,7 @@ the V4L2 interface. + + + 10. Notes for V4L2 application developers +-======================================== ++========================================= + This driver follows the V4L2 API specifications. In particular, it enforces two + rules: + +--- gregkh-2.6.orig/drivers/usb/media/et61x251_core.c ++++ gregkh-2.6/drivers/usb/media/et61x251_core.c +@@ -25,11 +25,9 @@ + #include <linux/moduleparam.h> + #include <linux/errno.h> + #include <linux/slab.h> +-#include <linux/string.h> + #include <linux/device.h> + #include <linux/fs.h> + #include <linux/delay.h> +-#include <linux/stddef.h> + #include <linux/compiler.h> + #include <linux/ioctl.h> + #include <linux/poll.h> +@@ -50,8 +48,8 @@ + #define ET61X251_MODULE_AUTHOR "(C) 2006 Luca Risolia" + #define ET61X251_AUTHOR_EMAIL "<luca.risolia@studio.unibo.it>" + #define ET61X251_MODULE_LICENSE "GPL" +-#define ET61X251_MODULE_VERSION "1:1.01" +-#define ET61X251_MODULE_VERSION_CODE KERNEL_VERSION(1, 0, 1) ++#define ET61X251_MODULE_VERSION "1:1.02" ++#define ET61X251_MODULE_VERSION_CODE KERNEL_VERSION(1, 0, 2) + + /*****************************************************************************/ + +@@ -90,6 +88,16 @@ MODULE_PARM_DESC(force_munmap, + "\nDefault value is "__MODULE_STRING(SN9C102_FORCE_MUNMAP)"." + "\n"); + ++static unsigned int frame_timeout[] = {[0 ... ET61X251_MAX_DEVICES-1] = ++ ET61X251_FRAME_TIMEOUT}; ++module_param_array(frame_timeout, uint, NULL, 0644); ++MODULE_PARM_DESC(frame_timeout, ++ "\n<n[,...]> Timeout for a video frame in seconds." ++ "\nThis parameter is specific for each detected camera." ++ "\nDefault value is " ++ __MODULE_STRING(ET61X251_FRAME_TIMEOUT)"." ++ "\n"); ++ + #ifdef ET61X251_DEBUG + static unsigned short debug = ET61X251_DEBUG_LEVEL; + module_param(debug, ushort, 0644); +@@ -111,8 +119,8 @@ static u32 + et61x251_request_buffers(struct et61x251_device* cam, u32 count, + enum et61x251_io_method io) + { +- struct v4l2_pix_format* p = &(cam->sensor->pix_format); +- struct v4l2_rect* r = &(cam->sensor->cropcap.bounds); ++ struct v4l2_pix_format* p = &(cam->sensor.pix_format); ++ struct v4l2_rect* r = &(cam->sensor.cropcap.bounds); + const size_t imagesize = cam->module_param.force_munmap || + io == IO_READ ? + (p->width * p->height * p->priv) / 8 : +@@ -268,8 +276,8 @@ et61x251_i2c_try_read(struct et61x251_de + int err = 0, res; + + data[0] = address; +- data[1] = cam->sensor->i2c_slave_id; +- data[2] = cam->sensor->rsta | 0x10; ++ data[1] = cam->sensor.i2c_slave_id; ++ data[2] = cam->sensor.rsta | 0x10; + data[3] = !(et61x251_read_reg(cam, 0x8b) & 0x02); + res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00, 0x41, + 0, 0x88, data, 4, ET61X251_CTRL_TIMEOUT); +@@ -301,8 +309,8 @@ et61x251_i2c_try_write(struct et61x251_d + int err = 0, res; + + data[0] = address; +- data[1] = cam->sensor->i2c_slave_id; +- data[2] = cam->sensor->rsta | 0x12; ++ data[1] = cam->sensor.i2c_slave_id; ++ data[2] = cam->sensor.rsta | 0x12; + res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00, 0x41, + 0, 0x88, data, 3, ET61X251_CTRL_TIMEOUT); + if (res < 0) +@@ -334,9 +342,6 @@ et61x251_i2c_raw_write(struct et61x251_d + u8* data = cam->control_buffer; + int err = 0, res; + +- if (!cam->sensor) +- return -1; +- + data[0] = data2; + data[1] = data3; + data[2] = data4; +@@ -350,8 +355,8 @@ et61x251_i2c_raw_write(struct et61x251_d + err += res; + + data[0] = address; +- data[1] = cam->sensor->i2c_slave_id; +- data[2] = cam->sensor->rsta | 0x02 | (n << 4); ++ data[1] = cam->sensor.i2c_slave_id; ++ data[2] = cam->sensor.rsta | 0x02 | (n << 4); + res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00, 0x41, + 0, 0x88, data, 3, ET61X251_CTRL_TIMEOUT); + if (res < 0) +@@ -364,11 +369,11 @@ et61x251_i2c_raw_write(struct et61x251_d + if (res < 0) + err += res; + +- err += et61x251_i2c_wait(cam, cam->sensor); ++ err += et61x251_i2c_wait(cam, &cam->sensor); + + if (err) + DBG(3, "I2C raw write failed for %s image sensor", +- cam->sensor->name); ++ cam->sensor.name); + + PDBGG("I2C raw write: %u bytes, address = 0x%02X, data1 = 0x%02X, " + "data2 = 0x%02X, data3 = 0x%02X, data4 = 0x%02X, data5 = 0x%02X," +@@ -382,19 +387,13 @@ et61x251_i2c_raw_write(struct et61x251_d + + int et61x251_i2c_read(struct et61x251_device* cam, u8 address) + { +- if (!cam->sensor) +- return -1; +- +- return et61x251_i2c_try_read(cam, cam->sensor, address); ++ return et61x251_i2c_try_read(cam, &cam->sensor, address); + } + + + int et61x251_i2c_write(struct et61x251_device* cam, u8 address, u8 value) + { +- if (!cam->sensor) +- return -1; +- +- return et61x251_i2c_try_write(cam, cam->sensor, address, value); ++ return et61x251_i2c_try_write(cam, &cam->sensor, address, value); + } + + /*****************************************************************************/ +@@ -417,7 +416,7 @@ static void et61x251_urb_complete(struct + if ((*f)) + (*f)->state = F_QUEUED; + DBG(3, "Stream interrupted"); +- wake_up_interruptible(&cam->wait_stream); ++ wake_up(&cam->wait_stream); + } + + if (cam->state & DEV_DISCONNECTED) +@@ -435,9 +434,9 @@ static void et61x251_urb_complete(struct + (*f) = list_entry(cam->inqueue.next, struct et61x251_frame_t, + frame); + +- imagesize = (cam->sensor->pix_format.width * +- cam->sensor->pix_format.height * +- cam->sensor->pix_format.priv) / 8; ++ imagesize = (cam->sensor.pix_format.width * ++ cam->sensor.pix_format.height * ++ cam->sensor.pix_format.priv) / 8; + + for (i = 0; i < urb->number_of_packets; i++) { + unsigned int len, status; +@@ -476,7 +475,7 @@ start_of_frame: + + if ((*f)->state == F_GRABBING) { + if (sof && (*f)->buf.bytesused) { +- if (cam->sensor->pix_format.pixelformat == ++ if (cam->sensor.pix_format.pixelformat == + V4L2_PIX_FMT_ET61X251) + goto end_of_frame; + else { +@@ -521,7 +520,7 @@ end_of_frame: + goto resubmit_urb; + + if (sof && +- cam->sensor->pix_format.pixelformat == ++ cam->sensor.pix_format.pixelformat == + V4L2_PIX_FMT_ET61X251) + goto start_of_frame; + } +@@ -650,21 +649,21 @@ static int et61x251_stop_transfer(struct + + static int et61x251_stream_interrupt(struct et61x251_device* cam) + { +- int err = 0; ++ long timeout; + + cam->stream = STREAM_INTERRUPT; +- err = wait_event_timeout(cam->wait_stream, +- (cam->stream == STREAM_OFF) || +- (cam->state & DEV_DISCONNECTED), +- ET61X251_URB_TIMEOUT); ++ timeout = wait_event_timeout(cam->wait_stream, ++ (cam->stream == STREAM_OFF) || ++ (cam->state & DEV_DISCONNECTED), ++ ET61X251_URB_TIMEOUT); + if (cam->state & DEV_DISCONNECTED) + return -ENODEV; +- else if (err) { ++ else if (cam->stream != STREAM_OFF) { + cam->state |= DEV_MISCONFIGURED; + DBG(1, "URB timeout reached. The camera is misconfigured. To " + "use it, close and open /dev/video%d again.", + cam->v4ldev->minor); +- return err; ++ return -EIO; + } + + return 0; +@@ -709,18 +708,18 @@ static ssize_t et61x251_show_reg(struct + struct et61x251_device* cam; + ssize_t count; + +- if (down_interruptible(&et61x251_sysfs_lock)) ++ if (mutex_lock_interruptible(&et61x251_sysfs_lock)) + return -ERESTARTSYS; + + cam = video_get_drvdata(to_video_device(cd)); + if (!cam) { +- up(&et61x251_sysfs_lock); ++ mutex_unlock(&et61x251_sysfs_lock); + return -ENODEV; + } + + count = sprintf(buf, "%u\n", cam->sysfs.reg); + +- up(&et61x251_sysfs_lock); ++ mutex_unlock(&et61x251_sysfs_lock); + + return count; + } +@@ -733,18 +732,18 @@ et61x251_store_reg(struct class_device* + u8 index; + ssize_t count; + +- if (down_interruptible(&et61x251_sysfs_lock)) ++ if (mutex_lock_interruptible(&et61x251_sysfs_lock)) + return -ERESTARTSYS; + + cam = video_get_drvdata(to_video_device(cd)); + if (!cam) { +- up(&et61x251_sysfs_lock); ++ mutex_unlock(&et61x251_sysfs_lock); + return -ENODEV; + } + + index = et61x251_strtou8(buf, len, &count); + if (index > 0x8e || !count) { +- up(&et61x251_sysfs_lock); ++ mutex_unlock(&et61x251_sysfs_lock); + return -EINVAL; + } + +@@ -753,7 +752,7 @@ et61x251_store_reg(struct class_device* + DBG(2, "Moved ET61X[12]51 register index to 0x%02X", cam->sysfs.reg); + DBG(3, "Written bytes: %zd", count); + +- up(&et61x251_sysfs_lock); ++ mutex_unlock(&et61x251_sysfs_lock); + + return count; + } +@@ -765,17 +764,17 @@ static ssize_t et61x251_show_val(struct + ssize_t count; + int val; + +- if (down_interruptible(&et61x251_sysfs_lock)) ++ if (mutex_lock_interruptible(&et61x251_sysfs_lock)) + return -ERESTARTSYS; + + cam = video_get_drvdata(to_video_device(cd)); + if (!cam) { +- up(&et61x251_sysfs_lock); ++ mutex_unlock(&et61x251_sysfs_lock); + return -ENODEV; + } + + if ((val = et61x251_read_reg(cam, cam->sysfs.reg)) < 0) { +- up(&et61x251_sysfs_lock); ++ mutex_unlock(&et61x251_sysfs_lock); + return -EIO; + } + +@@ -783,7 +782,7 @@ static ssize_t et61x251_show_val(struct + + DBG(3, "Read bytes: %zd", count); + +- up(&et61x251_sysfs_lock); ++ mutex_unlock(&et61x251_sysfs_lock); + + return count; + } +@@ -797,24 +796,24 @@ et61x251_store_val(struct class_device* + ssize_t count; + int err; + +- if (down_interruptible(&et61x251_sysfs_lock)) ++ if (mutex_lock_interruptible(&et61x251_sysfs_lock)) + return -ERESTARTSYS; + + cam = video_get_drvdata(to_video_device(cd)); + if (!cam) { +- up(&et61x251_sysfs_lock); ++ mutex_unlock(&et61x251_sysfs_lock); + return -ENODEV; + } + + value = et61x251_strtou8(buf, len, &count); + if (!count) { +- up(&et61x251_sysfs_lock); ++ mutex_unlock(&et61x251_sysfs_lock); + return -EINVAL; + } + + err = et61x251_write_reg(cam, value, cam->sysfs.reg); + if (err) { +- up(&et61x251_sysfs_lock); ++ mutex_unlock(&et61x251_sysfs_lock); + return -EIO; + } + +@@ -822,7 +821,7 @@ et61x251_store_val(struct class_device* + cam->sysfs.reg, value); + DBG(3, "Written bytes: %zd", count); + +- up(&et61x251_sysfs_lock); ++ mutex_unlock(&et61x251_sysfs_lock); + + return count; + } +@@ -833,12 +832,12 @@ static ssize_t et61x251_show_i2c_reg(str + struct et61x251_device* cam; + ssize_t count; + +- if (down_interruptible(&et61x251_sysfs_lock)) ++ if (mutex_lock_interruptible(&et61x251_sysfs_lock)) + return -ERESTARTSYS; + + cam = video_get_drvdata(to_video_device(cd)); + if (!cam) { +- up(&et61x251_sysfs_lock); ++ mutex_unlock(&et61x251_sysfs_lock); + return -ENODEV; + } + +@@ -846,7 +845,7 @@ static ssize_t et61x251_show_i2c_reg(str + + DBG(3, "Read bytes: %zd", count); + +- up(&et61x251_sysfs_lock); ++ mutex_unlock(&et61x251_sysfs_lock); + + return count; + } +@@ -859,18 +858,18 @@ et61x251_store_i2c_reg(struct class_devi + u8 index; + ssize_t count; + +- if (down_interruptible(&et61x251_sysfs_lock)) ++ if (mutex_lock_interruptible(&et61x251_sysfs_lock)) + return -ERESTARTSYS; + + cam = video_get_drvdata(to_video_device(cd)); + if (!cam) { +- up(&et61x251_sysfs_lock); ++ mutex_unlock(&et61x251_sysfs_lock); + return -ENODEV; + } + + index = et61x251_strtou8(buf, len, &count); + if (!count) { +- up(&et61x251_sysfs_lock); ++ mutex_unlock(&et61x251_sysfs_lock); + return -EINVAL; + } + +@@ -879,7 +878,7 @@ et61x251_store_i2c_reg(struct class_devi + DBG(2, "Moved sensor register index to 0x%02X", cam->sysfs.i2c_reg); + DBG(3, "Written bytes: %zd", count); + +- up(&et61x251_sysfs_lock); ++ mutex_unlock(&et61x251_sysfs_lock); + + return count; + } +@@ -891,22 +890,22 @@ static ssize_t et61x251_show_i2c_val(str + ssize_t count; + int val; + +- if (down_interruptible(&et61x251_sysfs_lock)) ++ if (mutex_lock_interruptible(&et61x251_sysfs_lock)) + return -ERESTARTSYS; + + cam = video_get_drvdata(to_video_device(cd)); + if (!cam) { +- up(&et61x251_sysfs_lock); ++ mutex_unlock(&et61x251_sysfs_lock); + return -ENODEV; + } + +- if (!(cam->sensor->sysfs_ops & ET61X251_I2C_READ)) { +- up(&et61x251_sysfs_lock); ++ if (!(cam->sensor.sysfs_ops & ET61X251_I2C_READ)) { ++ mutex_unlock(&et61x251_sysfs_lock); + return -ENOSYS; + } + + if ((val = et61x251_i2c_read(cam, cam->sysfs.i2c_reg)) < 0) { +- up(&et61x251_sysfs_lock); ++ mutex_unlock(&et61x251_sysfs_lock); + return -EIO; + } + +@@ -914,7 +913,7 @@ static ssize_t et61x251_show_i2c_val(str + + DBG(3, "Read bytes: %zd", count); + +- up(&et61x251_sysfs_lock); ++ mutex_unlock(&et61x251_sysfs_lock); + + return count; + } +@@ -928,29 +927,29 @@ et61x251_store_i2c_val(struct class_devi + ssize_t count; + int err; + +- if (down_interruptible(&et61x251_sysfs_lock)) ++ if (mutex_lock_interruptible(&et61x251_sysfs_lock)) + return -ERESTARTSYS; + + cam = video_get_drvdata(to_video_device(cd)); + if (!cam) { +- up(&et61x251_sysfs_lock); ++ mutex_unlock(&et61x251_sysfs_lock); + return -ENODEV; + } + +- if (!(cam->sensor->sysfs_ops & ET61X251_I2C_READ)) { +- up(&et61x251_sysfs_lock); ++ if (!(cam->sensor.sysfs_ops & ET61X251_I2C_READ)) { ++ mutex_unlock(&et61x251_sysfs_lock); + return -ENOSYS; + } + + value = et61x251_strtou8(buf, len, &count); + if (!count) { +- up(&et61x251_sysfs_lock); ++ mutex_unlock(&et61x251_sysfs_lock); + return -EINVAL; + } + + err = et61x251_i2c_write(cam, cam->sysfs.i2c_reg, value); + if (err) { +- up(&et61x251_sysfs_lock); ++ mutex_unlock(&et61x251_sysfs_lock); + return -EIO; + } + +@@ -958,7 +957,7 @@ et61x251_store_i2c_val(struct class_devi + cam->sysfs.i2c_reg, value); + DBG(3, "Written bytes: %zd", count); + +- up(&et61x251_sysfs_lock); ++ mutex_unlock(&et61x251_sysfs_lock); + + return count; + } +@@ -980,7 +979,7 @@ static void et61x251_create_sysfs(struct + + video_device_create_file(v4ldev, &class_device_attr_reg); + video_device_create_file(v4ldev, &class_device_attr_val); +- if (cam->sensor && cam->sensor->sysfs_ops) { ++ if (cam->sensor.sysfs_ops) { + video_device_create_file(v4ldev, &class_device_attr_i2c_reg); + video_device_create_file(v4ldev, &class_device_attr_i2c_val); + } +@@ -1048,7 +1047,7 @@ static int et61x251_set_scale(struct et6 + static int + et61x251_set_crop(struct et61x251_device* cam, struct v4l2_rect* rect) + { +- struct et61x251_sensor* s = cam->sensor; ++ struct et61x251_sensor* s = &cam->sensor; + u16 fmw_sx = (u16)(rect->left - s->cropcap.bounds.left + + s->active_pixel.left), + fmw_sy = (u16)(rect->top - s->cropcap.bounds.top + +@@ -1076,7 +1075,7 @@ et61x251_set_crop(struct et61x251_device + + static int et61x251_init(struct et61x251_device* cam) + { +- struct et61x251_sensor* s = cam->sensor; ++ struct et61x251_sensor* s = &cam->sensor; + struct v4l2_control ctrl; + struct v4l2_queryctrl *qctrl; + struct v4l2_rect* rect; +@@ -1143,7 +1142,7 @@ static int et61x251_init(struct et61x251 + } + + if (!(cam->state & DEV_INITIALIZED)) { +- init_MUTEX(&cam->fileop_sem); ++ mutex_init(&cam->fileop_mutex); + spin_lock_init(&cam->queue_lock); + init_waitqueue_head(&cam->wait_frame); + init_waitqueue_head(&cam->wait_stream); +@@ -1161,13 +1160,15 @@ static int et61x251_init(struct et61x251 + + static void et61x251_release_resources(struct et61x251_device* cam) + { +- down(&et61x251_sysfs_lock); ++ mutex_lock(&et61x251_sysfs_lock); + + DBG(2, "V4L2 device /dev/video%d deregistered", cam->v4ldev->minor); + video_set_drvdata(cam->v4ldev, NULL); + video_unregister_device(cam->v4ldev); + +- up(&et61x251_sysfs_lock); ++ usb_put_dev(cam->usbdev); ++ ++ mutex_unlock(&et61x251_sysfs_lock); + + kfree(cam->control_buffer); + } +@@ -1188,7 +1189,7 @@ static int et61x251_open(struct inode* i + + cam = video_get_drvdata(video_devdata(filp)); + +- if (down_interruptible(&cam->dev_sem)) { ++ if (mutex_lock_interruptible(&cam->dev_mutex)) { + up_read(&et61x251_disconnect); + return -ERESTARTSYS; + } +@@ -1200,7 +1201,7 @@ static int et61x251_open(struct inode* i + err = -EWOULDBLOCK; + goto out; + } +- up(&cam->dev_sem); ++ mutex_unlock(&cam->dev_mutex); + err = wait_event_interruptible_exclusive(cam->open, + cam->state & DEV_DISCONNECTED + || !cam->users); +@@ -1212,7 +1213,7 @@ static int et61x251_open(struct inode* i + up_read(&et61x251_disconnect); + return -ENODEV; + } +- down(&cam->dev_sem); ++ mutex_lock(&cam->dev_mutex); + } + + +@@ -1240,7 +1241,7 @@ static int et61x251_open(struct inode* i + DBG(3, "Video device /dev/video%d is open", cam->v4ldev->minor); + + out: +- up(&cam->dev_sem); ++ mutex_unlock(&cam->dev_mutex); + up_read(&et61x251_disconnect); + return err; + } +@@ -1250,7 +1251,7 @@ static int et61x251_release(struct inode + { + struct et61x251_device* cam = video_get_drvdata(video_devdata(filp)); + +- down(&cam->dev_sem); /* prevent disconnect() to be called */ ++ mutex_lock(&cam->dev_mutex); /* prevent disconnect() to be called */ + + et61x251_stop_transfer(cam); + +@@ -1258,7 +1259,7 @@ static int et61x251_release(struct inode + + if (cam->state & DEV_DISCONNECTED) { + et61x251_release_resources(cam); +- up(&cam->dev_sem); ++ mutex_unlock(&cam->dev_mutex); + kfree(cam); + return 0; + } +@@ -1268,7 +1269,7 @@ static int et61x251_release(struct inode + + DBG(3, "Video device /dev/video%d closed", cam->v4ldev->minor); + +- up(&cam->dev_sem); ++ mutex_unlock(&cam->dev_mutex); + + return 0; + } +@@ -1281,28 +1282,29 @@ et61x251_read(struct file* filp, char __ + struct et61x251_device* cam = video_get_drvdata(video_devdata(filp)); + struct et61x251_frame_t* f, * i; + unsigned long lock_flags; ++ long timeout; + int err = 0; + +- if (down_interruptible(&cam->fileop_sem)) ++ if (mutex_lock_interruptible(&cam->fileop_mutex)) + return -ERESTARTSYS; + + if (cam->state & DEV_DISCONNECTED) { + DBG(1, "Device not present"); +- up(&cam->fileop_sem); ++ mutex_unlock(&cam->fileop_mutex); + return -ENODEV; + } + + if (cam->state & DEV_MISCONFIGURED) { + DBG(1, "The camera is misconfigured. Close and open it " + "again."); +- up(&cam->fileop_sem); ++ mutex_unlock(&cam->fileop_mutex); + return -EIO; + } + + if (cam->io == IO_MMAP) { + DBG(3, "Close and open the device again to choose the read " + "method"); +- up(&cam->fileop_sem); ++ mutex_unlock(&cam->fileop_mutex); + return -EINVAL; + } + +@@ -1310,7 +1312,7 @@ et61x251_read(struct file* filp, char __ + if (!et61x251_request_buffers(cam, cam->nreadbuffers, + IO_READ)) { + DBG(1, "read() failed, not enough memory"); +- up(&cam->fileop_sem); ++ mutex_unlock(&cam->fileop_mutex); + return -ENOMEM; + } + cam->io = IO_READ; +@@ -1324,30 +1326,32 @@ et61x251_read(struct file* filp, char __ + } + + if (!count) { +- up(&cam->fileop_sem); ++ mutex_unlock(&cam->fileop_mutex); + return 0; + } + + if (list_empty(&cam->outqueue)) { + if (filp->f_flags & O_NONBLOCK) { +- up(&cam->fileop_sem); ++ mutex_unlock(&cam->fileop_mutex); + return -EAGAIN; + } +- err = wait_event_interruptible +- ( cam->wait_frame, +- (!list_empty(&cam->outqueue)) || +- (cam->state & DEV_DISCONNECTED) || +- (cam->state & DEV_MISCONFIGURED) ); +- if (err) { +- up(&cam->fileop_sem); +- return err; ++ timeout = wait_event_interruptible_timeout ++ ( cam->wait_frame, ++ (!list_empty(&cam->outqueue)) || ++ (cam->state & DEV_DISCONNECTED) || ++ (cam->state & DEV_MISCONFIGURED), ++ cam->module_param.frame_timeout * ++ 1000 * msecs_to_jiffies(1) ); ++ if (timeout < 0) { ++ mutex_unlock(&cam->fileop_mutex); ++ return timeout; + } + if (cam->state & DEV_DISCONNECTED) { +- up(&cam->fileop_sem); ++ mutex_unlock(&cam->fileop_mutex); + return -ENODEV; + } +- if (cam->state & DEV_MISCONFIGURED) { +- up(&cam->fileop_sem); ++ if (!timeout || (cam->state & DEV_MISCONFIGURED)) { ++ mutex_unlock(&cam->fileop_mutex); + return -EIO; + } + } +@@ -1375,7 +1379,7 @@ exit: + PDBGG("Frame #%lu, bytes read: %zu", + (unsigned long)f->buf.index, count); + +- up(&cam->fileop_sem); ++ mutex_unlock(&cam->fileop_mutex); + + return err ? err : count; + } +@@ -1388,7 +1392,7 @@ static unsigned int et61x251_poll(struct + unsigned long lock_flags; + unsigned int mask = 0; + +- if (down_interruptible(&cam->fileop_sem)) ++ if (mutex_lock_interruptible(&cam->fileop_mutex)) + return POLLERR; + + if (cam->state & DEV_DISCONNECTED) { +@@ -1426,12 +1430,12 @@ static unsigned int et61x251_poll(struct + if (!list_empty(&cam->outqueue)) + mask |= POLLIN | POLLRDNORM; + +- up(&cam->fileop_sem); ++ mutex_unlock(&cam->fileop_mutex); + + return mask; + + error: +- up(&cam->fileop_sem); ++ mutex_unlock(&cam->fileop_mutex); + return POLLERR; + } + +@@ -1465,25 +1469,25 @@ static int et61x251_mmap(struct file* fi + void *pos; + u32 i; + +- if (down_interruptible(&cam->fileop_sem)) ++ if (mutex_lock_interruptible(&cam->fileop_mutex)) + return -ERESTARTSYS; + + if (cam->state & DEV_DISCONNECTED) { + DBG(1, "Device not present"); +- up(&cam->fileop_sem); ++ mutex_unlock(&cam->fileop_mutex); + return -ENODEV; + } + + if (cam->state & DEV_MISCONFIGURED) { + DBG(1, "The camera is misconfigured. Close and open it " + "again."); +- up(&cam->fileop_sem); ++ mutex_unlock(&cam->fileop_mutex); + return -EIO; + } + + if (cam->io != IO_MMAP || !(vma->vm_flags & VM_WRITE) || + size != PAGE_ALIGN(cam->frame[0].buf.length)) { +- up(&cam->fileop_sem); ++ mutex_unlock(&cam->fileop_mutex); + return -EINVAL; + } + +@@ -1492,7 +1496,7 @@ static int et61x251_mmap(struct file* fi + break; + } + if (i == cam->nbuffers) { +- up(&cam->fileop_sem); ++ mutex_unlock(&cam->fileop_mutex); + return -EINVAL; + } + +@@ -1502,7 +1506,7 @@ static int et61x251_mmap(struct file* fi + pos = cam->frame[i].bufmem; + while (size > 0) { /* size is page-aligned */ + if (vm_insert_page(vma, start, vmalloc_to_page(pos))) { +- up(&cam->fileop_sem); ++ mutex_unlock(&cam->fileop_mutex); + return -EAGAIN; + } + start += PAGE_SIZE; +@@ -1515,7 +1519,7 @@ static int et61x251_mmap(struct file* fi + + et61x251_vm_open(vma); + +- up(&cam->fileop_sem); ++ mutex_unlock(&cam->fileop_mutex); + + return 0; + } +@@ -1557,6 +1561,7 @@ et61x251_vidioc_enuminput(struct et61x25 + + memset(&i, 0, sizeof(i)); + strcpy(i.name, "Camera"); ++ i.type = V4L2_INPUT_TYPE_CAMERA; + + if (copy_to_user(arg, &i, sizeof(i))) + return -EFAULT; +@@ -1566,7 +1571,19 @@ et61x251_vidioc_enuminput(struct et61x25 + + + static int +-et61x251_vidioc_gs_input(struct et61x251_device* cam, void __user * arg) ++et61x251_vidioc_g_input(struct et61x251_device* cam, void __user * arg) ++{ ++ int index = 0; ++ ++ if (copy_to_user(arg, &index, sizeof(index))) ++ return -EFAULT; ++ ++ return 0; ++} ++ ++ ++static int ++et61x251_vidioc_s_input(struct et61x251_device* cam, void __user * arg) + { + int index; + +@@ -1583,7 +1600,7 @@ et61x251_vidioc_gs_input(struct et61x251 + static int + et61x251_vidioc_query_ctrl(struct et61x251_device* cam, void __user * arg) + { +- struct et61x251_sensor* s = cam->sensor; ++ struct et61x251_sensor* s = &cam->sensor; + struct v4l2_queryctrl qc; + u8 i; + +@@ -1605,7 +1622,7 @@ et61x251_vidioc_query_ctrl(struct et61x2 + static int + et61x251_vidioc_g_ctrl(struct et61x251_device* cam, void __user * arg) + { +- struct et61x251_sensor* s = cam->sensor; ++ struct et61x251_sensor* s = &cam->sensor; + struct v4l2_control ctrl; + int err = 0; + u8 i; +@@ -1637,7 +1654,7 @@ exit: + static int + et61x251_vidioc_s_ctrl(struct et61x251_device* cam, void __user * arg) + { +- struct et61x251_sensor* s = cam->sensor; ++ struct et61x251_sensor* s = &cam->sensor; + struct v4l2_control ctrl; + u8 i; + int err = 0; +@@ -1650,6 +1667,8 @@ et61x251_vidioc_s_ctrl(struct et61x251_d + + for (i = 0; i < ARRAY_SIZE(s->qctrl); i++) + if (ctrl.id == s->qctrl[i].id) { ++ if (s->qctrl[i].flags & V4L2_CTRL_FLAG_DISABLED) ++ return -EINVAL; + if (ctrl.value < s->qctrl[i].minimum || + ctrl.value > s->qctrl[i].maximum) + return -ERANGE; +@@ -1669,7 +1688,7 @@ et61x251_vidioc_s_ctrl(struct et61x251_d + static int + et61x251_vidioc_cropcap(struct et61x251_device* cam, void __user * arg) + { +- struct v4l2_cropcap* cc = &(cam->sensor->cropcap); ++ struct v4l2_cropcap* cc = &(cam->sensor.cropcap); + + cc->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + cc->pixelaspect.numerator = 1; +@@ -1685,7 +1704,7 @@ et61x251_vidioc_cropcap(struct et61x251_ + static int + et61x251_vidioc_g_crop(struct et61x251_device* cam, void __user * arg) + { +- struct et61x251_sensor* s = cam->sensor; ++ struct et61x251_sensor* s = &cam->sensor; + struct v4l2_crop crop = { + .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, + }; +@@ -1702,7 +1721,7 @@ et61x251_vidioc_g_crop(struct et61x251_d + static int + et61x251_vidioc_s_crop(struct et61x251_device* cam, void __user * arg) + { +- struct et61x251_sensor* s = cam->sensor; ++ struct et61x251_sensor* s = &cam->sensor; + struct v4l2_crop crop; + struct v4l2_rect* rect; + struct v4l2_rect* bounds = &(s->cropcap.bounds); +@@ -1843,7 +1862,7 @@ static int + et61x251_vidioc_g_fmt(struct et61x251_device* cam, void __user * arg) + { + struct v4l2_format format; +- struct v4l2_pix_format* pfmt = &(cam->sensor->pix_format); ++ struct v4l2_pix_format* pfmt = &(cam->sensor.pix_format); + + if (copy_from_user(&format, arg, sizeof(format))) + return -EFAULT; +@@ -1868,7 +1887,7 @@ static int + et61x251_vidioc_try_s_fmt(struct et61x251_device* cam, unsigned int cmd, + void __user * arg) + { +- struct et61x251_sensor* s = cam->sensor; ++ struct et61x251_sensor* s = &cam->sensor; + struct v4l2_format format; + struct v4l2_pix_format* pix; + struct v4l2_pix_format* pfmt = &(s->pix_format); +@@ -2155,7 +2174,7 @@ et61x251_vidioc_dqbuf(struct et61x251_de + struct v4l2_buffer b; + struct et61x251_frame_t *f; + unsigned long lock_flags; +- int err = 0; ++ long timeout; + + if (copy_from_user(&b, arg, sizeof(b))) + return -EFAULT; +@@ -2168,16 +2187,18 @@ et61x251_vidioc_dqbuf(struct et61x251_de + return -EINVAL; + if (filp->f_flags & O_NONBLOCK) + return -EAGAIN; +- err = wait_event_interruptible +- ( cam->wait_frame, +- (!list_empty(&cam->outqueue)) || +- (cam->state & DEV_DISCONNECTED) || +- (cam->state & DEV_MISCONFIGURED) ); +- if (err) +- return err; ++ timeout = wait_event_interruptible_timeout ++ ( cam->wait_frame, ++ (!list_empty(&cam->outqueue)) || ++ (cam->state & DEV_DISCONNECTED) || ++ (cam->state & DEV_MISCONFIGURED), ++ cam->module_param.frame_timeout * ++ 1000 * msecs_to_jiffies(1) ); ++ if (timeout < 0) ++ return timeout; + if (cam->state & DEV_DISCONNECTED) + return -ENODEV; +- if (cam->state & DEV_MISCONFIGURED) ++ if (!timeout || (cam->state & DEV_MISCONFIGURED)) + return -EIO; + } + +@@ -2309,8 +2330,10 @@ static int et61x251_ioctl_v4l2(struct in + return et61x251_vidioc_enuminput(cam, arg); + + case VIDIOC_G_INPUT: ++ return et61x251_vidioc_g_input(cam, arg); ++ + case VIDIOC_S_INPUT: +- return et61x251_vidioc_gs_input(cam, arg); ++ return et61x251_vidioc_s_input(cam, arg); + + case VIDIOC_QUERYCTRL: + return et61x251_vidioc_query_ctrl(cam, arg); +@@ -2393,19 +2416,19 @@ static int et61x251_ioctl(struct inode* + struct et61x251_device* cam = video_get_drvdata(video_devdata(filp)); + int err = 0; + +- if (down_interruptible(&cam->fileop_sem)) ++ if (mutex_lock_interruptible(&cam->fileop_mutex)) + return -ERESTARTSYS; + + if (cam->state & DEV_DISCONNECTED) { + DBG(1, "Device not present"); +- up(&cam->fileop_sem); ++ mutex_unlock(&cam->fileop_mutex); + return -ENODEV; + } + + if (cam->state & DEV_MISCONFIGURED) { + DBG(1, "The camera is misconfigured. Close and open it " + "again."); +- up(&cam->fileop_sem); ++ mutex_unlock(&cam->fileop_mutex); + return -EIO; + } + +@@ -2413,7 +2436,7 @@ static int et61x251_ioctl(struct inode* + + err = et61x251_ioctl_v4l2(inode, filp, cmd, (void __user *)arg); + +- up(&cam->fileop_sem); ++ mutex_unlock(&cam->fileop_mutex); + + return err; + } +@@ -2459,7 +2482,7 @@ et61x251_usb_probe(struct usb_interface* + goto fail; + } + +- init_MUTEX(&cam->dev_sem); ++ mutex_init(&cam->dev_mutex); + + DBG(2, "ET61X[12]51 PC Camera Controller detected " + "(vid/pid 0x%04X/0x%04X)",id->idVendor, id->idProduct); +@@ -2470,8 +2493,8 @@ et61x251_usb_probe(struct usb_interface* + break; + } + +- if (!err && cam->sensor) +- DBG(2, "%s image sensor detected", cam->sensor->name); ++ if (!err) ++ DBG(2, "%s image sensor detected", cam->sensor.name); + else { + DBG(1, "No supported image sensor detected"); + err = -ENODEV; +@@ -2492,7 +2515,7 @@ et61x251_usb_probe(struct usb_interface* + cam->v4ldev->release = video_device_release; + video_set_drvdata(cam->v4ldev, cam); + +- down(&cam->dev_sem); ++ mutex_lock(&cam->dev_mutex); + + err = video_register_device(cam->v4ldev, VFL_TYPE_GRABBER, + video_nr[dev_nr]); +@@ -2502,13 +2525,14 @@ et61x251_usb_probe(struct usb_interface* + DBG(1, "Free /dev/videoX node not found"); + video_nr[dev_nr] = -1; + dev_nr = (dev_nr < ET61X251_MAX_DEVICES-1) ? dev_nr+1 : 0; +- up(&cam->dev_sem); ++ mutex_unlock(&cam->dev_mutex); + goto fail; + } + + DBG(2, "V4L2 device registered as /dev/video%d", cam->v4ldev->minor); + + cam->module_param.force_munmap = force_munmap[dev_nr]; ++ cam->module_param.frame_timeout = frame_timeout[dev_nr]; + + dev_nr = (dev_nr < ET61X251_MAX_DEVICES-1) ? dev_nr+1 : 0; + +@@ -2519,7 +2543,7 @@ et61x251_usb_probe(struct usb_interface* + + usb_set_intfdata(intf, cam); + +- up(&cam->dev_sem); ++ mutex_unlock(&cam->dev_mutex); + + return 0; + +@@ -2543,7 +2567,7 @@ static void et61x251_usb_disconnect(stru + + down_write(&et61x251_disconnect); + +- down(&cam->dev_sem); ++ mutex_lock(&cam->dev_mutex); + + DBG(2, "Disconnecting %s...", cam->v4ldev->name); + +@@ -2557,13 +2581,14 @@ static void et61x251_usb_disconnect(stru + et61x251_stop_transfer(cam); + cam->state |= DEV_DISCONNECTED; + wake_up_interruptible(&cam->wait_frame); +- wake_up_interruptible(&cam->wait_stream); ++ wake_up(&cam->wait_stream); ++ usb_get_dev(cam->usbdev); + } else { + cam->state |= DEV_DISCONNECTED; + et61x251_release_resources(cam); + } + +- up(&cam->dev_sem); ++ mutex_unlock(&cam->dev_mutex); + + if (!cam->users) + kfree(cam); +--- gregkh-2.6.orig/drivers/usb/media/et61x251.h ++++ gregkh-2.6/drivers/usb/media/et61x251.h +@@ -33,7 +33,9 @@ + #include <linux/types.h> + #include <linux/param.h> + #include <linux/rwsem.h> +-#include <asm/semaphore.h> ++#include <linux/mutex.h> ++#include <linux/stddef.h> ++#include <linux/string.h> + + #include "et61x251_sensor.h" + +@@ -51,6 +53,7 @@ + #define ET61X251_ALTERNATE_SETTING 13 + #define ET61X251_URB_TIMEOUT msecs_to_jiffies(2 * ET61X251_ISO_PACKETS) + #define ET61X251_CTRL_TIMEOUT 100 ++#define ET61X251_FRAME_TIMEOUT 2 + + /*****************************************************************************/ + +@@ -127,15 +130,16 @@ struct et61x251_sysfs_attr { + + struct et61x251_module_param { + u8 force_munmap; ++ u16 frame_timeout; + }; + +-static DECLARE_MUTEX(et61x251_sysfs_lock); ++static DEFINE_MUTEX(et61x251_sysfs_lock); + static DECLARE_RWSEM(et61x251_disconnect); + + struct et61x251_device { + struct video_device* v4ldev; + +- struct et61x251_sensor* sensor; ++ struct et61x251_sensor sensor; + + struct usb_device* usbdev; + struct urb* urb[ET61X251_URBS]; +@@ -157,19 +161,28 @@ struct et61x251_device { + enum et61x251_dev_state state; + u8 users; + +- struct semaphore dev_sem, fileop_sem; ++ struct mutex dev_mutex, fileop_mutex; + spinlock_t queue_lock; + wait_queue_head_t open, wait_frame, wait_stream; + }; + + /*****************************************************************************/ + ++struct et61x251_device* ++et61x251_match_id(struct et61x251_device* cam, const struct usb_device_id *id) ++{ ++ if (usb_match_id(usb_ifnum_to_if(cam->usbdev, 0), id)) ++ return cam; ++ ++ return NULL; ++} ++ ++ + void + et61x251_attach_sensor(struct et61x251_device* cam, + struct et61x251_sensor* sensor) + { +- cam->sensor = sensor; +- cam->sensor->usbdev = cam->usbdev; ++ memcpy(&cam->sensor, sensor, sizeof(struct et61x251_sensor)); + } + + /*****************************************************************************/ +@@ -212,7 +225,8 @@ do { + + #undef PDBG + #define PDBG(fmt, args...) \ +-dev_info(&cam->dev, "[%s:%d] " fmt "\n", __FUNCTION__, __LINE__ , ## args) ++dev_info(&cam->usbdev->dev, "[%s:%d] " fmt "\n", \ ++ __FUNCTION__, __LINE__ , ## args) + + #undef PDBGG + #define PDBGG(fmt, args...) do {;} while(0) /* placeholder */ +--- gregkh-2.6.orig/drivers/usb/media/et61x251_sensor.h ++++ gregkh-2.6/drivers/usb/media/et61x251_sensor.h +@@ -42,6 +42,9 @@ static int (*et61x251_sensor_table[])(st + NULL, \ + }; + ++extern struct et61x251_device* ++et61x251_match_id(struct et61x251_device* cam, const struct usb_device_id *id); ++ + extern void + et61x251_attach_sensor(struct et61x251_device* cam, + struct et61x251_sensor* sensor); +@@ -105,8 +108,6 @@ struct et61x251_sensor { + int (*set_pix_format)(struct et61x251_device* cam, + const struct v4l2_pix_format* pix); + +- const struct usb_device* usbdev; +- + /* Private */ + struct v4l2_queryctrl _qctrl[ET61X251_MAX_CTRLS]; + struct v4l2_rect _rect; +--- gregkh-2.6.orig/drivers/usb/media/et61x251_tas5130d1b.c ++++ gregkh-2.6/drivers/usb/media/et61x251_tas5130d1b.c +@@ -126,12 +126,16 @@ static struct et61x251_sensor tas5130d1b + + int et61x251_probe_tas5130d1b(struct et61x251_device* cam) + { +- /* This sensor has no identifiers, so let's attach it anyway */ +- et61x251_attach_sensor(cam, &tas5130d1b); ++ const struct usb_device_id tas5130d1b_id_table[] = { ++ { USB_DEVICE(0x102c, 0x6251), }, ++ { } ++ }; + + /* Sensor detection is based on USB pid/vid */ +- if (le16_to_cpu(tas5130d1b.usbdev->descriptor.idProduct) != 0x6251) ++ if (!et61x251_match_id(cam, tas5130d1b_id_table)) + return -ENODEV; + ++ et61x251_attach_sensor(cam, &tas5130d1b); ++ + return 0; + } diff --git a/usb/usb-kzalloc-conversion-for-rest-of-drivers-usb.patch b/usb/usb-kzalloc-conversion-for-rest-of-drivers-usb.patch new file mode 100644 index 0000000000000..4691e5d8f105b --- /dev/null +++ b/usb/usb-kzalloc-conversion-for-rest-of-drivers-usb.patch @@ -0,0 +1,690 @@ +From snakebyte@gmx.de Mon Feb 27 12:29:47 2006 +From: Eric Sesterhenn <snakebyte@gmx.de> +To: Greg KH <gregkh@suse.de> +Cc: kernel-janitors@lists.osdl.org +Subject: USB: kzalloc() conversion for rest of drivers/usb +Date: Mon, 27 Feb 2006 21:29:43 +0100 +Message-Id: <1141072183.32324.0.camel@alice> + + +Signed-off-by: Eric Sesterhenn <snakebyte@gmx.de> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/usb/host/ehci-mem.c | 10 +++------- + drivers/usb/host/ehci-sched.c | 3 +-- + drivers/usb/host/hc_crisv10.c | 12 ++++-------- + drivers/usb/media/ov511.c | 4 +--- + drivers/usb/media/pwc/pwc-if.c | 3 +-- + drivers/usb/media/se401.c | 4 +--- + drivers/usb/media/stv680.c | 7 ++----- + drivers/usb/misc/auerswald.c | 6 ++---- + drivers/usb/misc/usblcd.c | 3 +-- + drivers/usb/misc/usbtest.c | 9 +++------ + drivers/usb/mon/mon_main.c | 3 +-- + drivers/usb/mon/mon_text.c | 3 +-- + drivers/usb/net/zd1201.c | 9 +++------ + drivers/usb/serial/cp2101.c | 4 +--- + drivers/usb/serial/cypress_m8.c | 3 +-- + drivers/usb/serial/ftdi_sio.c | 3 +-- + drivers/usb/serial/garmin_gps.c | 3 +-- + drivers/usb/serial/io_edgeport.c | 3 +-- + drivers/usb/serial/io_ti.c | 6 ++---- + drivers/usb/serial/ir-usb.c | 3 +-- + drivers/usb/serial/keyspan.c | 6 ++---- + drivers/usb/serial/kobil_sct.c | 16 +++++----------- + drivers/usb/serial/mct_u232.c | 3 +-- + drivers/usb/serial/option.c | 3 +-- + drivers/usb/serial/pl2303.c | 6 ++---- + drivers/usb/serial/ti_usb_3410_5052.c | 3 +-- + drivers/usb/serial/usb-serial.c | 6 ++---- + drivers/usb/serial/visor.c | 3 +-- + drivers/usb/storage/isd200.c | 2 +- + 29 files changed, 48 insertions(+), 101 deletions(-) + +--- gregkh-2.6.orig/drivers/usb/host/ehci-mem.c ++++ gregkh-2.6/drivers/usb/host/ehci-mem.c +@@ -220,13 +220,9 @@ static int ehci_mem_init (struct ehci_hc + ehci->periodic [i] = EHCI_LIST_END; + + /* software shadow of hardware table */ +- ehci->pshadow = kmalloc (ehci->periodic_size * sizeof (void *), flags); +- if (ehci->pshadow == NULL) { +- goto fail; +- } +- memset (ehci->pshadow, 0, ehci->periodic_size * sizeof (void *)); +- +- return 0; ++ ehci->pshadow = kcalloc(ehci->periodic_size, sizeof(void *), flags); ++ if (ehci->pshadow != NULL) ++ return 0; + + fail: + ehci_dbg (ehci, "couldn't init memory\n"); +--- gregkh-2.6.orig/drivers/usb/host/ehci-sched.c ++++ gregkh-2.6/drivers/usb/host/ehci-sched.c +@@ -864,9 +864,8 @@ iso_sched_alloc (unsigned packets, gfp_t + int size = sizeof *iso_sched; + + size += packets * sizeof (struct ehci_iso_packet); +- iso_sched = kmalloc (size, mem_flags); ++ iso_sched = kzalloc(size, mem_flags); + if (likely (iso_sched != NULL)) { +- memset(iso_sched, 0, size); + INIT_LIST_HEAD (&iso_sched->td_list); + } + return iso_sched; +--- gregkh-2.6.orig/drivers/usb/host/hc_crisv10.c ++++ gregkh-2.6/drivers/usb/host/hc_crisv10.c +@@ -2137,10 +2137,9 @@ static int etrax_usb_submit_bulk_urb(str + urb->status = -EINPROGRESS; + + /* Setup the hcpriv data. */ +- urb_priv = kmalloc(sizeof(etrax_urb_priv_t), KMALLOC_FLAG); ++ urb_priv = kzalloc(sizeof(etrax_urb_priv_t), KMALLOC_FLAG); + assert(urb_priv != NULL); + /* This sets rx_offset to 0. */ +- memset(urb_priv, 0, sizeof(etrax_urb_priv_t)); + urb_priv->urb_state = NOT_STARTED; + urb->hcpriv = urb_priv; + +@@ -2475,10 +2474,9 @@ static int etrax_usb_submit_ctrl_urb(str + urb->status = -EINPROGRESS; + + /* Setup the hcpriv data. */ +- urb_priv = kmalloc(sizeof(etrax_urb_priv_t), KMALLOC_FLAG); ++ urb_priv = kzalloc(sizeof(etrax_urb_priv_t), KMALLOC_FLAG); + assert(urb_priv != NULL); + /* This sets rx_offset to 0. */ +- memset(urb_priv, 0, sizeof(etrax_urb_priv_t)); + urb_priv->urb_state = NOT_STARTED; + urb->hcpriv = urb_priv; + +@@ -2767,9 +2765,8 @@ static void etrax_usb_add_to_intr_sb_lis + maxlen = usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe)); + interval = urb->interval; + +- urb_priv = kmalloc(sizeof(etrax_urb_priv_t), KMALLOC_FLAG); ++ urb_priv = kzalloc(sizeof(etrax_urb_priv_t), KMALLOC_FLAG); + assert(urb_priv != NULL); +- memset(urb_priv, 0, sizeof(etrax_urb_priv_t)); + urb->hcpriv = urb_priv; + + first_ep = &TxIntrEPList[0]; +@@ -2997,9 +2994,8 @@ static void etrax_usb_add_to_isoc_sb_lis + + prev_sb_desc = next_sb_desc = temp_sb_desc = NULL; + +- urb_priv = kmalloc(sizeof(etrax_urb_priv_t), GFP_ATOMIC); ++ urb_priv = kzalloc(sizeof(etrax_urb_priv_t), GFP_ATOMIC); + assert(urb_priv != NULL); +- memset(urb_priv, 0, sizeof(etrax_urb_priv_t)); + + urb->hcpriv = urb_priv; + urb_priv->epid = epid; +--- gregkh-2.6.orig/drivers/usb/media/ov511.c ++++ gregkh-2.6/drivers/usb/media/ov511.c +@@ -5686,13 +5686,11 @@ ov51x_probe(struct usb_interface *intf, + if (idesc->bInterfaceSubClass != 0x00) + return -ENODEV; + +- if ((ov = kmalloc(sizeof(*ov), GFP_KERNEL)) == NULL) { ++ if ((ov = kzalloc(sizeof(*ov), GFP_KERNEL)) == NULL) { + err("couldn't kmalloc ov struct"); + goto error_out; + } + +- memset(ov, 0, sizeof(*ov)); +- + ov->dev = dev; + ov->iface = idesc->bInterfaceNumber; + ov->led_policy = led; +--- gregkh-2.6.orig/drivers/usb/media/pwc/pwc-if.c ++++ gregkh-2.6/drivers/usb/media/pwc/pwc-if.c +@@ -1867,12 +1867,11 @@ static int usb_pwc_probe(struct usb_inte + Info("Warning: more than 1 configuration available.\n"); + + /* Allocate structure, initialize pointers, mutexes, etc. and link it to the usb_device */ +- pdev = kmalloc(sizeof(struct pwc_device), GFP_KERNEL); ++ pdev = kzalloc(sizeof(struct pwc_device), GFP_KERNEL); + if (pdev == NULL) { + Err("Oops, could not allocate memory for pwc_device.\n"); + return -ENOMEM; + } +- memset(pdev, 0, sizeof(struct pwc_device)); + pdev->type = type_id; + pdev->vsize = default_size; + pdev->vframes = default_fps; +--- gregkh-2.6.orig/drivers/usb/media/se401.c ++++ gregkh-2.6/drivers/usb/media/se401.c +@@ -1345,13 +1345,11 @@ static int se401_probe(struct usb_interf + /* We found one */ + info("SE401 camera found: %s", camera_name); + +- if ((se401 = kmalloc(sizeof(*se401), GFP_KERNEL)) == NULL) { ++ if ((se401 = kzalloc(sizeof(*se401), GFP_KERNEL)) == NULL) { + err("couldn't kmalloc se401 struct"); + return -ENOMEM; + } + +- memset(se401, 0, sizeof(*se401)); +- + se401->dev = dev; + se401->iface = interface->bInterfaceNumber; + se401->camera_name = camera_name; +--- gregkh-2.6.orig/drivers/usb/media/stv680.c ++++ gregkh-2.6/drivers/usb/media/stv680.c +@@ -318,12 +318,11 @@ static int stv_init (struct usb_stv *stv + unsigned char *buffer; + unsigned long int bufsize; + +- buffer = kmalloc (40, GFP_KERNEL); ++ buffer = kzalloc (40, GFP_KERNEL); + if (buffer == NULL) { + PDEBUG (0, "STV(e): Out of (small buf) memory"); + return -1; + } +- memset (buffer, 0, 40); + udelay (100); + + /* set config 1, interface 0, alternate 0 */ +@@ -1388,14 +1387,12 @@ static int stv680_probe (struct usb_inte + goto error; + } + /* We found one */ +- if ((stv680 = kmalloc (sizeof (*stv680), GFP_KERNEL)) == NULL) { ++ if ((stv680 = kzalloc (sizeof (*stv680), GFP_KERNEL)) == NULL) { + PDEBUG (0, "STV(e): couldn't kmalloc stv680 struct."); + retval = -ENOMEM; + goto error; + } + +- memset (stv680, 0, sizeof (*stv680)); +- + stv680->udev = dev; + stv680->camera_name = camera_name; + +--- gregkh-2.6.orig/drivers/usb/misc/auerswald.c ++++ gregkh-2.6/drivers/usb/misc/auerswald.c +@@ -570,10 +570,9 @@ static int auerchain_setup (pauerchain_t + + /* fill the list of free elements */ + for (;numElements; numElements--) { +- acep = (pauerchainelement_t) kmalloc (sizeof (auerchainelement_t), GFP_KERNEL); ++ acep = kzalloc(sizeof(auerchainelement_t), GFP_KERNEL); + if (!acep) + goto ac_fail; +- memset (acep, 0, sizeof (auerchainelement_t)); + INIT_LIST_HEAD (&acep->list); + list_add_tail (&acep->list, &acp->free_list); + } +@@ -761,10 +760,9 @@ static int auerbuf_setup (pauerbufctl_t + + /* fill the list of free elements */ + for (;numElements; numElements--) { +- bep = (pauerbuf_t) kmalloc (sizeof (auerbuf_t), GFP_KERNEL); ++ bep = kzalloc(sizeof(auerbuf_t), GFP_KERNEL); + if (!bep) + goto bl_fail; +- memset (bep, 0, sizeof (auerbuf_t)); + bep->list = bcp; + INIT_LIST_HEAD (&bep->buff_list); + bep->bufp = kmalloc (bufsize, GFP_KERNEL); +--- gregkh-2.6.orig/drivers/usb/misc/usblcd.c ++++ gregkh-2.6/drivers/usb/misc/usblcd.c +@@ -270,12 +270,11 @@ static int lcd_probe(struct usb_interfac + int retval = -ENOMEM; + + /* allocate memory for our device state and initialize it */ +- dev = kmalloc(sizeof(*dev), GFP_KERNEL); ++ dev = kzalloc(sizeof(*dev), GFP_KERNEL); + if (dev == NULL) { + err("Out of memory"); + goto error; + } +- memset(dev, 0x00, sizeof(*dev)); + kref_init(&dev->kref); + + dev->udev = usb_get_dev(interface_to_usbdev(interface)); +--- gregkh-2.6.orig/drivers/usb/misc/usbtest.c ++++ gregkh-2.6/drivers/usb/misc/usbtest.c +@@ -382,12 +382,11 @@ alloc_sglist (int nents, int max, int va + for (i = 0; i < nents; i++) { + char *buf; + +- buf = kmalloc (size, SLAB_KERNEL); ++ buf = kzalloc (size, SLAB_KERNEL); + if (!buf) { + free_sglist (sg, i); + return NULL; + } +- memset (buf, 0, size); + + /* kmalloc pages are always physically contiguous! */ + sg_init_one(&sg[i], buf, size); +@@ -842,10 +841,9 @@ test_ctrl_queue (struct usbtest_dev *dev + * as with bulk/intr sglists, sglen is the queue depth; it also + * controls which subtests run (more tests than sglen) or rerun. + */ +- urb = kmalloc (param->sglen * sizeof (struct urb *), SLAB_KERNEL); ++ urb = kcalloc(param->sglen, sizeof(struct urb *), SLAB_KERNEL); + if (!urb) + return -ENOMEM; +- memset (urb, 0, param->sglen * sizeof (struct urb *)); + for (i = 0; i < param->sglen; i++) { + int pipe = usb_rcvctrlpipe (udev, 0); + unsigned len; +@@ -1865,10 +1863,9 @@ usbtest_probe (struct usb_interface *int + } + #endif + +- dev = kmalloc (sizeof *dev, SLAB_KERNEL); ++ dev = kzalloc(sizeof(*dev), SLAB_KERNEL); + if (!dev) + return -ENOMEM; +- memset (dev, 0, sizeof *dev); + info = (struct usbtest_info *) id->driver_info; + dev->info = info; + init_MUTEX (&dev->sem); +--- gregkh-2.6.orig/drivers/usb/mon/mon_main.c ++++ gregkh-2.6/drivers/usb/mon/mon_main.c +@@ -277,9 +277,8 @@ static void mon_bus_init(struct dentry * + char name[NAMESZ]; + int rc; + +- if ((mbus = kmalloc(sizeof(struct mon_bus), GFP_KERNEL)) == NULL) ++ if ((mbus = kzalloc(sizeof(struct mon_bus), GFP_KERNEL)) == NULL) + goto err_alloc; +- memset(mbus, 0, sizeof(struct mon_bus)); + kref_init(&mbus->ref); + spin_lock_init(&mbus->lock); + INIT_LIST_HEAD(&mbus->r_list); +--- gregkh-2.6.orig/drivers/usb/mon/mon_text.c ++++ gregkh-2.6/drivers/usb/mon/mon_text.c +@@ -213,12 +213,11 @@ static int mon_text_open(struct inode *i + mbus = inode->u.generic_ip; + ubus = mbus->u_bus; + +- rp = kmalloc(sizeof(struct mon_reader_text), GFP_KERNEL); ++ rp = kzalloc(sizeof(struct mon_reader_text), GFP_KERNEL); + if (rp == NULL) { + rc = -ENOMEM; + goto err_alloc; + } +- memset(rp, 0, sizeof(struct mon_reader_text)); + INIT_LIST_HEAD(&rp->e_list); + init_waitqueue_head(&rp->wait); + mutex_init(&rp->printf_lock); +--- gregkh-2.6.orig/drivers/usb/net/zd1201.c ++++ gregkh-2.6/drivers/usb/net/zd1201.c +@@ -621,10 +621,9 @@ static int zd1201_drvr_start(struct zd12 + __le16 zdmax; + unsigned char *buffer; + +- buffer = kmalloc(ZD1201_RXSIZE, GFP_KERNEL); ++ buffer = kzalloc(ZD1201_RXSIZE, GFP_KERNEL); + if (!buffer) + return -ENOMEM; +- memset(buffer, 0, ZD1201_RXSIZE); + + usb_fill_bulk_urb(zd->rx_urb, zd->usb, + usb_rcvbulkpipe(zd->usb, zd->endp_in), buffer, ZD1201_RXSIZE, +@@ -1750,11 +1749,9 @@ static int zd1201_probe(struct usb_inter + + usb = interface_to_usbdev(interface); + +- zd = kmalloc(sizeof(struct zd1201), GFP_KERNEL); +- if (!zd) { ++ zd = kzalloc(sizeof(struct zd1201), GFP_KERNEL); ++ if (!zd) + return -ENOMEM; +- } +- memset(zd, 0, sizeof(struct zd1201)); + zd->ap = ap; + zd->usb = usb; + zd->removed = 0; +--- gregkh-2.6.orig/drivers/usb/serial/cp2101.c ++++ gregkh-2.6/drivers/usb/serial/cp2101.c +@@ -169,9 +169,7 @@ static int cp2101_get_config(struct usb_ + /* Number of integers required to contain the array */ + length = (((size - 1) | 3) + 1)/4; + +- buf = kmalloc (length * sizeof(u32), GFP_KERNEL); +- memset(buf, 0, length * sizeof(u32)); +- ++ buf = kcalloc(length, sizeof(u32), GFP_KERNEL); + if (!buf) { + dev_err(&port->dev, "%s - out of memory.\n", __FUNCTION__); + return -ENOMEM; +--- gregkh-2.6.orig/drivers/usb/serial/cypress_m8.c ++++ gregkh-2.6/drivers/usb/serial/cypress_m8.c +@@ -435,11 +435,10 @@ static int generic_startup (struct usb_s + + dbg("%s - port %d", __FUNCTION__, serial->port[0]->number); + +- priv = kmalloc(sizeof (struct cypress_private), GFP_KERNEL); ++ priv = kzalloc(sizeof (struct cypress_private), GFP_KERNEL); + if (!priv) + return -ENOMEM; + +- memset(priv, 0x00, sizeof (struct cypress_private)); + spin_lock_init(&priv->lock); + priv->buf = cypress_buf_alloc(CYPRESS_BUF_SIZE); + if (priv->buf == NULL) { +--- gregkh-2.6.orig/drivers/usb/serial/ftdi_sio.c ++++ gregkh-2.6/drivers/usb/serial/ftdi_sio.c +@@ -1141,12 +1141,11 @@ static int ftdi_sio_attach (struct usb_s + + dbg("%s",__FUNCTION__); + +- priv = kmalloc(sizeof(struct ftdi_private), GFP_KERNEL); ++ priv = kzalloc(sizeof(struct ftdi_private), GFP_KERNEL); + if (!priv){ + err("%s- kmalloc(%Zd) failed.", __FUNCTION__, sizeof(struct ftdi_private)); + return -ENOMEM; + } +- memset(priv, 0, sizeof(*priv)); + + spin_lock_init(&priv->rx_lock); + init_waitqueue_head(&priv->delta_msr_wait); +--- gregkh-2.6.orig/drivers/usb/serial/garmin_gps.c ++++ gregkh-2.6/drivers/usb/serial/garmin_gps.c +@@ -1422,12 +1422,11 @@ static int garmin_attach (struct usb_ser + + dbg("%s", __FUNCTION__); + +- garmin_data_p = kmalloc (sizeof(struct garmin_data), GFP_KERNEL); ++ garmin_data_p = kzalloc(sizeof(struct garmin_data), GFP_KERNEL); + if (garmin_data_p == NULL) { + dev_err(&port->dev, "%s - Out of memory\n", __FUNCTION__); + return -ENOMEM; + } +- memset (garmin_data_p, 0, sizeof(struct garmin_data)); + init_timer(&garmin_data_p->timer); + spin_lock_init(&garmin_data_p->lock); + INIT_LIST_HEAD(&garmin_data_p->pktlist); +--- gregkh-2.6.orig/drivers/usb/serial/io_edgeport.c ++++ gregkh-2.6/drivers/usb/serial/io_edgeport.c +@@ -2725,12 +2725,11 @@ static int edge_startup (struct usb_seri + dev = serial->dev; + + /* create our private serial structure */ +- edge_serial = kmalloc (sizeof(struct edgeport_serial), GFP_KERNEL); ++ edge_serial = kzalloc(sizeof(struct edgeport_serial), GFP_KERNEL); + if (edge_serial == NULL) { + dev_err(&serial->dev->dev, "%s - Out of memory\n", __FUNCTION__); + return -ENOMEM; + } +- memset (edge_serial, 0, sizeof(struct edgeport_serial)); + spin_lock_init(&edge_serial->es_lock); + edge_serial->serial = serial; + usb_set_serial_data(serial, edge_serial); +--- gregkh-2.6.orig/drivers/usb/serial/io_ti.c ++++ gregkh-2.6/drivers/usb/serial/io_ti.c +@@ -2727,12 +2727,11 @@ static int edge_startup (struct usb_seri + dev = serial->dev; + + /* create our private serial structure */ +- edge_serial = kmalloc (sizeof(struct edgeport_serial), GFP_KERNEL); ++ edge_serial = kzalloc(sizeof(struct edgeport_serial), GFP_KERNEL); + if (edge_serial == NULL) { + dev_err(&serial->dev->dev, "%s - Out of memory\n", __FUNCTION__); + return -ENOMEM; + } +- memset (edge_serial, 0, sizeof(struct edgeport_serial)); + sema_init(&edge_serial->es_sem, 1); + edge_serial->serial = serial; + usb_set_serial_data(serial, edge_serial); +@@ -2745,12 +2744,11 @@ static int edge_startup (struct usb_seri + + /* set up our port private structures */ + for (i = 0; i < serial->num_ports; ++i) { +- edge_port = kmalloc (sizeof(struct edgeport_port), GFP_KERNEL); ++ edge_port = kzalloc(sizeof(struct edgeport_port), GFP_KERNEL); + if (edge_port == NULL) { + dev_err(&serial->dev->dev, "%s - Out of memory\n", __FUNCTION__); + goto cleanup; + } +- memset (edge_port, 0, sizeof(struct edgeport_port)); + spin_lock_init(&edge_port->ep_lock); + edge_port->ep_out_buf = edge_buf_alloc(EDGE_OUT_BUF_SIZE); + if (edge_port->ep_out_buf == NULL) { +--- gregkh-2.6.orig/drivers/usb/serial/ir-usb.c ++++ gregkh-2.6/drivers/usb/serial/ir-usb.c +@@ -184,10 +184,9 @@ static struct irda_class_desc *irda_usb_ + struct irda_class_desc *desc; + int ret; + +- desc = kmalloc(sizeof (struct irda_class_desc), GFP_KERNEL); ++ desc = kzalloc(sizeof (struct irda_class_desc), GFP_KERNEL); + if (desc == NULL) + return NULL; +- memset(desc, 0, sizeof(struct irda_class_desc)); + + ret = usb_control_msg(dev, usb_rcvctrlpipe(dev,0), + IU_REQ_GET_CLASS_DESC, +--- gregkh-2.6.orig/drivers/usb/serial/keyspan.c ++++ gregkh-2.6/drivers/usb/serial/keyspan.c +@@ -2250,12 +2250,11 @@ static int keyspan_startup (struct usb_s + } + + /* Setup private data for serial driver */ +- s_priv = kmalloc(sizeof(struct keyspan_serial_private), GFP_KERNEL); ++ s_priv = kzalloc(sizeof(struct keyspan_serial_private), GFP_KERNEL); + if (!s_priv) { + dbg("%s - kmalloc for keyspan_serial_private failed.", __FUNCTION__); + return -ENOMEM; + } +- memset(s_priv, 0, sizeof(struct keyspan_serial_private)); + + s_priv->device_details = d_details; + usb_set_serial_data(serial, s_priv); +@@ -2263,12 +2262,11 @@ static int keyspan_startup (struct usb_s + /* Now setup per port private data */ + for (i = 0; i < serial->num_ports; i++) { + port = serial->port[i]; +- p_priv = kmalloc(sizeof(struct keyspan_port_private), GFP_KERNEL); ++ p_priv = kzalloc(sizeof(struct keyspan_port_private), GFP_KERNEL); + if (!p_priv) { + dbg("%s - kmalloc for keyspan_port_private (%d) failed!.", __FUNCTION__, i); + return (1); + } +- memset(p_priv, 0, sizeof(struct keyspan_port_private)); + p_priv->device_details = d_details; + usb_set_serial_port_data(port, p_priv); + } +--- gregkh-2.6.orig/drivers/usb/serial/kobil_sct.c ++++ gregkh-2.6/drivers/usb/serial/kobil_sct.c +@@ -255,11 +255,9 @@ static int kobil_open (struct usb_serial + } + + // allocate memory for transfer buffer +- transfer_buffer = (unsigned char *) kmalloc(transfer_buffer_length, GFP_KERNEL); ++ transfer_buffer = kzalloc(transfer_buffer_length, GFP_KERNEL); + if (! transfer_buffer) { + return -ENOMEM; +- } else { +- memset(transfer_buffer, 0, transfer_buffer_length); + } + + // allocate write_urb +@@ -383,11 +381,10 @@ static void kobil_read_int_callback( str + + // BEGIN DEBUG + /* +- dbg_data = (unsigned char *) kmalloc((3 * purb->actual_length + 10) * sizeof(char), GFP_KERNEL); ++ dbg_data = kzalloc((3 * purb->actual_length + 10) * sizeof(char), GFP_KERNEL); + if (! dbg_data) { + return; + } +- memset(dbg_data, 0, (3 * purb->actual_length + 10)); + for (i = 0; i < purb->actual_length; i++) { + sprintf(dbg_data +3*i, "%02X ", data[i]); + } +@@ -518,11 +515,10 @@ static int kobil_tiocmget(struct usb_ser + } + + // allocate memory for transfer buffer +- transfer_buffer = (unsigned char *) kmalloc(transfer_buffer_length, GFP_KERNEL); ++ transfer_buffer = kzalloc(transfer_buffer_length, GFP_KERNEL); + if (!transfer_buffer) { + return -ENOMEM; + } +- memset(transfer_buffer, 0, transfer_buffer_length); + + result = usb_control_msg( port->serial->dev, + usb_rcvctrlpipe(port->serial->dev, 0 ), +@@ -564,11 +560,10 @@ static int kobil_tiocmset(struct usb_se + } + + // allocate memory for transfer buffer +- transfer_buffer = (unsigned char *) kmalloc(transfer_buffer_length, GFP_KERNEL); ++ transfer_buffer = kzalloc(transfer_buffer_length, GFP_KERNEL); + if (! transfer_buffer) { + return -ENOMEM; + } +- memset(transfer_buffer, 0, transfer_buffer_length); + + if (set & TIOCM_RTS) + rts = 1; +@@ -655,11 +650,10 @@ static int kobil_ioctl(struct usb_seria + (struct termios __user *)arg)) + return -EFAULT; + +- settings = (unsigned char *) kmalloc(50, GFP_KERNEL); ++ settings = kzalloc(50, GFP_KERNEL); + if (! settings) { + return -ENOBUFS; + } +- memset(settings, 0, 50); + + switch (priv->internal_termios.c_cflag & CBAUD) { + case B1200: +--- gregkh-2.6.orig/drivers/usb/serial/mct_u232.c ++++ gregkh-2.6/drivers/usb/serial/mct_u232.c +@@ -348,10 +348,9 @@ static int mct_u232_startup (struct usb_ + struct mct_u232_private *priv; + struct usb_serial_port *port, *rport; + +- priv = kmalloc(sizeof(struct mct_u232_private), GFP_KERNEL); ++ priv = kzalloc(sizeof(struct mct_u232_private), GFP_KERNEL); + if (!priv) + return -ENOMEM; +- memset(priv, 0, sizeof(struct mct_u232_private)); + spin_lock_init(&priv->lock); + usb_set_serial_port_data(serial->port[0], priv); + +--- gregkh-2.6.orig/drivers/usb/serial/option.c ++++ gregkh-2.6/drivers/usb/serial/option.c +@@ -631,13 +631,12 @@ static int option_startup(struct usb_ser + /* Now setup per port private data */ + for (i = 0; i < serial->num_ports; i++) { + port = serial->port[i]; +- portdata = kmalloc(sizeof(*portdata), GFP_KERNEL); ++ portdata = kzalloc(sizeof(*portdata), GFP_KERNEL); + if (!portdata) { + dbg("%s: kmalloc for option_port_private (%d) failed!.", + __FUNCTION__, i); + return (1); + } +- memset(portdata, 0, sizeof(struct option_port_private)); + + usb_set_serial_port_data(port, portdata); + +--- gregkh-2.6.orig/drivers/usb/serial/pl2303.c ++++ gregkh-2.6/drivers/usb/serial/pl2303.c +@@ -218,10 +218,9 @@ static int pl2303_startup (struct usb_se + dbg("device type: %d", type); + + for (i = 0; i < serial->num_ports; ++i) { +- priv = kmalloc (sizeof (struct pl2303_private), GFP_KERNEL); ++ priv = kzalloc(sizeof(struct pl2303_private), GFP_KERNEL); + if (!priv) + goto cleanup; +- memset (priv, 0x00, sizeof (struct pl2303_private)); + spin_lock_init(&priv->lock); + priv->buf = pl2303_buf_alloc(PL2303_BUF_SIZE); + if (priv->buf == NULL) { +@@ -383,12 +382,11 @@ static void pl2303_set_termios (struct u + } + } + +- buf = kmalloc (7, GFP_KERNEL); ++ buf = kzalloc (7, GFP_KERNEL); + if (!buf) { + dev_err(&port->dev, "%s - out of memory.\n", __FUNCTION__); + return; + } +- memset (buf, 0x00, 0x07); + + i = usb_control_msg (serial->dev, usb_rcvctrlpipe (serial->dev, 0), + GET_LINE_REQUEST, GET_LINE_REQUEST_TYPE, +--- gregkh-2.6.orig/drivers/usb/serial/ti_usb_3410_5052.c ++++ gregkh-2.6/drivers/usb/serial/ti_usb_3410_5052.c +@@ -416,12 +416,11 @@ static int ti_startup(struct usb_serial + dev->actconfig->desc.bConfigurationValue); + + /* create device structure */ +- tdev = kmalloc(sizeof(struct ti_device), GFP_KERNEL); ++ tdev = kzalloc(sizeof(struct ti_device), GFP_KERNEL); + if (tdev == NULL) { + dev_err(&dev->dev, "%s - out of memory\n", __FUNCTION__); + return -ENOMEM; + } +- memset(tdev, 0, sizeof(struct ti_device)); + sema_init(&tdev->td_open_close_sem, 1); + tdev->td_serial = serial; + usb_set_serial_data(serial, tdev); +--- gregkh-2.6.orig/drivers/usb/serial/usb-serial.c ++++ gregkh-2.6/drivers/usb/serial/usb-serial.c +@@ -564,12 +564,11 @@ static struct usb_serial * create_serial + { + struct usb_serial *serial; + +- serial = kmalloc (sizeof (*serial), GFP_KERNEL); ++ serial = kzalloc(sizeof(*serial), GFP_KERNEL); + if (!serial) { + dev_err(&dev->dev, "%s - out of memory\n", __FUNCTION__); + return NULL; + } +- memset (serial, 0, sizeof(*serial)); + serial->dev = usb_get_dev(dev); + serial->type = driver; + serial->interface = interface; +@@ -778,10 +777,9 @@ int usb_serial_probe(struct usb_interfac + serial->num_port_pointers = max_endpoints; + dbg("%s - setting up %d port structures for this device", __FUNCTION__, max_endpoints); + for (i = 0; i < max_endpoints; ++i) { +- port = kmalloc(sizeof(struct usb_serial_port), GFP_KERNEL); ++ port = kzalloc(sizeof(struct usb_serial_port), GFP_KERNEL); + if (!port) + goto probe_error; +- memset(port, 0x00, sizeof(struct usb_serial_port)); + port->number = i + serial->minor; + port->serial = serial; + spin_lock_init(&port->lock); +--- gregkh-2.6.orig/drivers/usb/serial/visor.c ++++ gregkh-2.6/drivers/usb/serial/visor.c +@@ -763,10 +763,9 @@ static int generic_startup(struct usb_se + int i; + + for (i = 0; i < serial->num_ports; ++i) { +- priv = kmalloc (sizeof(*priv), GFP_KERNEL); ++ priv = kzalloc (sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; +- memset (priv, 0x00, sizeof(*priv)); + spin_lock_init(&priv->lock); + usb_set_serial_port_data(serial->port[i], priv); + } +--- gregkh-2.6.orig/drivers/usb/storage/isd200.c ++++ gregkh-2.6/drivers/usb/storage/isd200.c +@@ -1382,7 +1382,7 @@ static int isd200_init_info(struct us_da + } else + US_DEBUGP("ERROR - kmalloc failure\n"); + +- return(retStatus); ++ return retStatus; + } + + /************************************************************************** diff --git a/usb/usb-kzalloc-conversion-in-drivers-usb-gadget.patch b/usb/usb-kzalloc-conversion-in-drivers-usb-gadget.patch new file mode 100644 index 0000000000000..e5d034766505f --- /dev/null +++ b/usb/usb-kzalloc-conversion-in-drivers-usb-gadget.patch @@ -0,0 +1,186 @@ +From david-b@pacbell.net Mon Feb 27 13:34:15 2006 +From: Eric Sesterhenn <snakebyte@gmx.de> +Subject: USB: kzalloc() conversion in drivers/usb/gadget +Date: Mon, 27 Feb 2006 13:34:10 -0800 +To: Greg KH <greg@kroah.com> +Cc: Eric Sesterhenn <snakebyte@gmx.de> +Content-Disposition: inline +Message-Id: <200602271334.10698.david-b@pacbell.net> + +this patch converts drivers/usb to kzalloc usage. +Compile tested with allyes config. + +I think there was a bug in drivers/usb/gadget/inode.c because +it used sizeof(*data) for the kmalloc() and sizeof(data) for +the memset(), since sizeof(data) just returns the size for a pointer. + +Signed-off-by: Eric Sesterhenn <snakebyte@gmx.de> +Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/usb/gadget/dummy_hcd.c | 3 +-- + drivers/usb/gadget/goku_udc.c | 3 +-- + drivers/usb/gadget/inode.c | 6 ++---- + drivers/usb/gadget/lh7a40x_udc.c | 3 +-- + drivers/usb/gadget/net2280.c | 3 +-- + drivers/usb/gadget/omap_udc.c | 6 ++---- + drivers/usb/gadget/pxa2xx_udc.c | 3 +-- + drivers/usb/gadget/serial.c | 3 +-- + drivers/usb/gadget/zero.c | 3 +-- + 9 files changed, 11 insertions(+), 22 deletions(-) + +--- gregkh-2.6.orig/drivers/usb/gadget/dummy_hcd.c ++++ gregkh-2.6/drivers/usb/gadget/dummy_hcd.c +@@ -478,10 +478,9 @@ dummy_alloc_request (struct usb_ep *_ep, + return NULL; + ep = usb_ep_to_dummy_ep (_ep); + +- req = kmalloc (sizeof *req, mem_flags); ++ req = kzalloc(sizeof(*req), mem_flags); + if (!req) + return NULL; +- memset (req, 0, sizeof *req); + INIT_LIST_HEAD (&req->queue); + return &req->req; + } +--- gregkh-2.6.orig/drivers/usb/gadget/goku_udc.c ++++ gregkh-2.6/drivers/usb/gadget/goku_udc.c +@@ -275,11 +275,10 @@ goku_alloc_request(struct usb_ep *_ep, g + + if (!_ep) + return NULL; +- req = kmalloc(sizeof *req, gfp_flags); ++ req = kzalloc(sizeof *req, gfp_flags); + if (!req) + return NULL; + +- memset(req, 0, sizeof *req); + req->req.dma = DMA_ADDR_INVALID; + INIT_LIST_HEAD(&req->queue); + return &req->req; +--- gregkh-2.6.orig/drivers/usb/gadget/inode.c ++++ gregkh-2.6/drivers/usb/gadget/inode.c +@@ -170,10 +170,9 @@ static struct dev_data *dev_new (void) + { + struct dev_data *dev; + +- dev = kmalloc (sizeof *dev, GFP_KERNEL); ++ dev = kzalloc(sizeof(*dev), GFP_KERNEL); + if (!dev) + return NULL; +- memset (dev, 0, sizeof *dev); + dev->state = STATE_DEV_DISABLED; + atomic_set (&dev->count, 1); + spin_lock_init (&dev->lock); +@@ -1592,10 +1591,9 @@ static int activate_ep_files (struct dev + gadget_for_each_ep (ep, dev->gadget) { + struct ep_data *data; + +- data = kmalloc (sizeof *data, GFP_KERNEL); ++ data = kzalloc(sizeof(*data), GFP_KERNEL); + if (!data) + goto enomem; +- memset (data, 0, sizeof data); + data->state = STATE_EP_DISABLED; + init_MUTEX (&data->lock); + init_waitqueue_head (&data->wait); +--- gregkh-2.6.orig/drivers/usb/gadget/lh7a40x_udc.c ++++ gregkh-2.6/drivers/usb/gadget/lh7a40x_udc.c +@@ -1114,11 +1114,10 @@ static struct usb_request *lh7a40x_alloc + + DEBUG("%s, %p\n", __FUNCTION__, ep); + +- req = kmalloc(sizeof *req, gfp_flags); ++ req = kzalloc(sizeof(*req), gfp_flags); + if (!req) + return 0; + +- memset(req, 0, sizeof *req); + INIT_LIST_HEAD(&req->queue); + + return &req->req; +--- gregkh-2.6.orig/drivers/usb/gadget/net2280.c ++++ gregkh-2.6/drivers/usb/gadget/net2280.c +@@ -386,11 +386,10 @@ net2280_alloc_request (struct usb_ep *_e + return NULL; + ep = container_of (_ep, struct net2280_ep, ep); + +- req = kmalloc (sizeof *req, gfp_flags); ++ req = kzalloc(sizeof(*req), gfp_flags); + if (!req) + return NULL; + +- memset (req, 0, sizeof *req); + req->req.dma = DMA_ADDR_INVALID; + INIT_LIST_HEAD (&req->queue); + +--- gregkh-2.6.orig/drivers/usb/gadget/omap_udc.c ++++ gregkh-2.6/drivers/usb/gadget/omap_udc.c +@@ -273,9 +273,8 @@ omap_alloc_request(struct usb_ep *ep, gf + { + struct omap_req *req; + +- req = kmalloc(sizeof *req, gfp_flags); ++ req = kzalloc(sizeof(*req), gfp_flags); + if (req) { +- memset (req, 0, sizeof *req); + req->req.dma = DMA_ADDR_INVALID; + INIT_LIST_HEAD (&req->queue); + } +@@ -2586,11 +2585,10 @@ omap_udc_setup(struct platform_device *o + /* UDC_PULLUP_EN gates the chip clock */ + // OTG_SYSCON_1_REG |= DEV_IDLE_EN; + +- udc = kmalloc (sizeof *udc, SLAB_KERNEL); ++ udc = kzalloc(sizeof(*udc), SLAB_KERNEL); + if (!udc) + return -ENOMEM; + +- memset(udc, 0, sizeof *udc); + spin_lock_init (&udc->lock); + + udc->gadget.ops = &omap_gadget_ops; +--- gregkh-2.6.orig/drivers/usb/gadget/pxa2xx_udc.c ++++ gregkh-2.6/drivers/usb/gadget/pxa2xx_udc.c +@@ -335,11 +335,10 @@ pxa2xx_ep_alloc_request (struct usb_ep * + { + struct pxa2xx_request *req; + +- req = kmalloc (sizeof *req, gfp_flags); ++ req = kzalloc(sizeof(*req), gfp_flags); + if (!req) + return NULL; + +- memset (req, 0, sizeof *req); + INIT_LIST_HEAD (&req->queue); + return &req->req; + } +--- gregkh-2.6.orig/drivers/usb/gadget/serial.c ++++ gregkh-2.6/drivers/usb/gadget/serial.c +@@ -2178,10 +2178,9 @@ static int gs_alloc_ports(struct gs_dev + return -EIO; + + for (i=0; i<GS_NUM_PORTS; i++) { +- if ((port=(struct gs_port *)kmalloc(sizeof(struct gs_port), kmalloc_flags)) == NULL) ++ if ((port=kzalloc(sizeof(struct gs_port), kmalloc_flags)) == NULL) + return -ENOMEM; + +- memset(port, 0, sizeof(struct gs_port)); + port->port_dev = dev; + port->port_num = i; + port->port_line_coding.dwDTERate = cpu_to_le32(GS_DEFAULT_DTE_RATE); +--- gregkh-2.6.orig/drivers/usb/gadget/zero.c ++++ gregkh-2.6/drivers/usb/gadget/zero.c +@@ -1188,10 +1188,9 @@ autoconf_fail: + + + /* ok, we made sense of the hardware ... */ +- dev = kmalloc (sizeof *dev, SLAB_KERNEL); ++ dev = kzalloc(sizeof(*dev), SLAB_KERNEL); + if (!dev) + return -ENOMEM; +- memset (dev, 0, sizeof *dev); + spin_lock_init (&dev->lock); + dev->gadget = gadget; + set_gadget_data (gadget, dev); diff --git a/usb/usb-pl2303-and-tiocmiwait.patch b/usb/usb-pl2303-and-tiocmiwait.patch new file mode 100644 index 0000000000000..5319796e1a8e5 --- /dev/null +++ b/usb/usb-pl2303-and-tiocmiwait.patch @@ -0,0 +1,39 @@ +From jcb@inf.ed.ac.uk Wed Mar 1 15:31:40 2006 +Message-ID: <17413.30016.470872.240977@palau.inf.ed.ac.uk> +Date: Wed, 1 Mar 2006 10:19:44 +0000 +From: Julian Bradfield <jcb+luu@inf.ed.ac.uk> +cc: Greg KH <greg@kroah.com> +Subject: USB: PL2303 and TIOCMIWAIT + +A while ago, I posted about TIOCMIWAIT not working with the PL2303 +USB-serial adapter. + + +After a brief exchange with Greg, I tracked this to a missing wake-up +in the USB interrupt procedures. I got our systems staff to install +the enclosed very simple patch to our 2.6.12 kernels, and it all works +fine as expected. I guess this should also apply to the latest version +and go into the mainstream. + +Apologies for the long delay in posting the result. + +The routine being patched is pl2303_update_line_status + +Signed-off-by: Julian Bradfield <jcb+luu@inf.ed.ac.uk> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + + +--- + drivers/usb/serial/pl2303.c | 1 + + 1 file changed, 1 insertion(+) + +--- gregkh-2.6.orig/drivers/usb/serial/pl2303.c ++++ gregkh-2.6/drivers/usb/serial/pl2303.c +@@ -826,6 +826,7 @@ static void pl2303_update_line_status(st + spin_lock_irqsave(&priv->lock, flags); + priv->line_status = data[status_idx]; + spin_unlock_irqrestore(&priv->lock, flags); ++ wake_up_interruptible (&priv->delta_msr_wait); + + exit: + return; diff --git a/usb/usb-serial-dynamic-id.patch b/usb/usb-serial-dynamic-id.patch index 7f0edeb3fcb2a..423f4924a27d8 100644 --- a/usb/usb-serial-dynamic-id.patch +++ b/usb/usb-serial-dynamic-id.patch @@ -261,7 +261,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> .name = "usbserial", .probe = usb_serial_probe, .disconnect = usb_serial_disconnect, -@@ -578,6 +578,39 @@ static struct usb_serial * create_serial +@@ -577,6 +577,39 @@ static struct usb_serial * create_serial return serial; } @@ -301,7 +301,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> static struct usb_serial_driver *search_serial_device(struct usb_interface *iface) { struct list_head *p; -@@ -587,11 +620,9 @@ static struct usb_serial_driver *search_ +@@ -586,11 +619,9 @@ static struct usb_serial_driver *search_ /* Check if the usb id matches a known device */ list_for_each(p, &usb_serial_driver_list) { t = list_entry(p, struct usb_serial_driver, driver_list); @@ -315,7 +315,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> } return NULL; -@@ -643,7 +674,7 @@ int usb_serial_probe(struct usb_interfac +@@ -642,7 +673,7 @@ int usb_serial_probe(struct usb_interfac return -EIO; } diff --git a/usb/usb-sn9c10x-driver-updates.patch b/usb/usb-sn9c10x-driver-updates.patch new file mode 100644 index 0000000000000..be6f03ab95963 --- /dev/null +++ b/usb/usb-sn9c10x-driver-updates.patch @@ -0,0 +1,1073 @@ +From luca.risolia@studio.unibo.it Fri Feb 24 21:49:15 2006 +Date: Sat, 25 Feb 2006 06:50:47 +0000 +From: Luca Risolia <luca.risolia@studio.unibo.it> +To: Greg Kroah-Hartman <gregkh@suse.de> +Subject: USB: SN9C10x driver updates +Message-ID: <20060225065047.GA31623@studio.unibo.it> +Content-Disposition: inline + +SN9C10x driver updates. + +Changes: + new, - removed, * cleanup, @ bugfix + +@ Fix stream_interrupt() +@ Fix vidioc_enum_input() and split vidioc_gs_input() +@ Need usb_get|put_dev() when disconnecting, if the device is open +* Use wait_event_interruptible_timeout() instead of wait_event_interruptible() + when waiting for video frames +* replace wake_up_interruptible(&wait_stream) with wake_up(&wait_stream) +* Cleanups and updates in the documentation ++ Use per-device sensor structures ++ Add support for PAS202BCA image sensors ++ Add frame_timeout module parameter + +Signed-off-by: Luca Risolia <luca.risolia@studio.unibo.it> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + Documentation/usb/sn9c102.txt | 11 + + drivers/usb/media/Makefile | 5 + drivers/usb/media/sn9c102.h | 23 ++- + drivers/usb/media/sn9c102_core.c | 170 +++++++++++++---------- + drivers/usb/media/sn9c102_ov7630.c | 33 ++-- + drivers/usb/media/sn9c102_pas202bca.c | 238 +++++++++++++++++++++++++++++++++ + drivers/usb/media/sn9c102_pas202bcb.c | 2 + drivers/usb/media/sn9c102_sensor.h | 15 +- + drivers/usb/media/sn9c102_tas5110c1b.c | 14 + + drivers/usb/media/sn9c102_tas5130d1b.c | 12 + + 10 files changed, 416 insertions(+), 107 deletions(-) + +--- gregkh-2.6.orig/Documentation/usb/sn9c102.txt ++++ gregkh-2.6/Documentation/usb/sn9c102.txt +@@ -196,6 +196,14 @@ Description: Force the application to + 1 = force memory unmapping (save memory) + Default: 0 + ------------------------------------------------------------------------------- ++Name: frame_timeout ++Type: uint array (min = 0, max = 64) ++Syntax: <n[,...]> ++Description: Timeout for a video frame in seconds. This parameter is ++ specific for each detected camera. This parameter can be ++ changed at runtime thanks to the /sys filesystem interface. ++Default: 2 ++------------------------------------------------------------------------------- + Name: debug + Type: ushort + Syntax: <n> +@@ -321,6 +329,7 @@ Vendor ID Product ID + --------- ---------- + 0x0c45 0x6001 + 0x0c45 0x6005 ++0x0c45 0x6007 + 0x0c45 0x6009 + 0x0c45 0x600d + 0x0c45 0x6024 +@@ -370,6 +379,7 @@ HV7131D Hynix Semiconductor, Inc. + MI-0343 Micron Technology, Inc. + OV7630 OmniVision Technologies, Inc. + PAS106B PixArt Imaging, Inc. ++PAS202BCA PixArt Imaging, Inc. + PAS202BCB PixArt Imaging, Inc. + TAS5110C1B Taiwan Advanced Sensor Corporation + TAS5130D1B Taiwan Advanced Sensor Corporation +@@ -493,6 +503,7 @@ Many thanks to following persons for the + order): + + - Luca Capello for the donation of a webcam; ++- Philippe Coval for having helped testing the PAS202BCA image sensor; + - Joao Rodrigo Fuzaro, Joao Limirio, Claudio Filho and Caio Begotti for the + donation of a webcam; + - Jon Hollstrom for the donation of a webcam; +--- gregkh-2.6.orig/drivers/usb/media/Makefile ++++ gregkh-2.6/drivers/usb/media/Makefile +@@ -2,7 +2,10 @@ + # Makefile for USB Media drivers + # + +-sn9c102-objs := sn9c102_core.o sn9c102_hv7131d.o sn9c102_mi0343.o sn9c102_ov7630.o sn9c102_pas106b.o sn9c102_pas202bcb.o sn9c102_tas5110c1b.o sn9c102_tas5130d1b.o ++sn9c102-objs := sn9c102_core.o sn9c102_hv7131d.o sn9c102_mi0343.o \ ++ sn9c102_ov7630.o sn9c102_pas106b.o sn9c102_pas202bca.o \ ++ sn9c102_pas202bcb.o sn9c102_tas5110c1b.o \ ++ sn9c102_tas5130d1b.o + et61x251-objs := et61x251_core.o et61x251_tas5130d1b.o + zc0301-objs := zc0301_core.o zc0301_pas202bcb.o + +--- gregkh-2.6.orig/drivers/usb/media/sn9c102_core.c ++++ gregkh-2.6/drivers/usb/media/sn9c102_core.c +@@ -25,11 +25,9 @@ + #include <linux/moduleparam.h> + #include <linux/errno.h> + #include <linux/slab.h> +-#include <linux/string.h> + #include <linux/device.h> + #include <linux/fs.h> + #include <linux/delay.h> +-#include <linux/stddef.h> + #include <linux/compiler.h> + #include <linux/ioctl.h> + #include <linux/poll.h> +@@ -49,8 +47,8 @@ + #define SN9C102_MODULE_AUTHOR "(C) 2004-2006 Luca Risolia" + #define SN9C102_AUTHOR_EMAIL "<luca.risolia@studio.unibo.it>" + #define SN9C102_MODULE_LICENSE "GPL" +-#define SN9C102_MODULE_VERSION "1:1.26" +-#define SN9C102_MODULE_VERSION_CODE KERNEL_VERSION(1, 0, 26) ++#define SN9C102_MODULE_VERSION "1:1.27" ++#define SN9C102_MODULE_VERSION_CODE KERNEL_VERSION(1, 0, 27) + + /*****************************************************************************/ + +@@ -89,6 +87,15 @@ MODULE_PARM_DESC(force_munmap, + "\nDefault value is "__MODULE_STRING(SN9C102_FORCE_MUNMAP)"." + "\n"); + ++static unsigned int frame_timeout[] = {[0 ... SN9C102_MAX_DEVICES-1] = ++ SN9C102_FRAME_TIMEOUT}; ++module_param_array(frame_timeout, uint, NULL, 0644); ++MODULE_PARM_DESC(frame_timeout, ++ "\n<n[,...]> Timeout for a video frame in seconds." ++ "\nThis parameter is specific for each detected camera." ++ "\nDefault value is "__MODULE_STRING(SN9C102_FRAME_TIMEOUT)"." ++ "\n"); ++ + #ifdef SN9C102_DEBUG + static unsigned short debug = SN9C102_DEBUG_LEVEL; + module_param(debug, ushort, 0644); +@@ -128,8 +135,8 @@ static u32 + sn9c102_request_buffers(struct sn9c102_device* cam, u32 count, + enum sn9c102_io_method io) + { +- struct v4l2_pix_format* p = &(cam->sensor->pix_format); +- struct v4l2_rect* r = &(cam->sensor->cropcap.bounds); ++ struct v4l2_pix_format* p = &(cam->sensor.pix_format); ++ struct v4l2_rect* r = &(cam->sensor.cropcap.bounds); + const size_t imagesize = cam->module_param.force_munmap || + io == IO_READ ? + (p->width * p->height * p->priv) / 8 : +@@ -449,19 +456,13 @@ sn9c102_i2c_try_write(struct sn9c102_dev + + int sn9c102_i2c_read(struct sn9c102_device* cam, u8 address) + { +- if (!cam->sensor) +- return -1; +- +- return sn9c102_i2c_try_read(cam, cam->sensor, address); ++ return sn9c102_i2c_try_read(cam, &cam->sensor, address); + } + + + int sn9c102_i2c_write(struct sn9c102_device* cam, u8 address, u8 value) + { +- if (!cam->sensor) +- return -1; +- +- return sn9c102_i2c_try_write(cam, cam->sensor, address, value); ++ return sn9c102_i2c_try_write(cam, &cam->sensor, address, value); + } + + /*****************************************************************************/ +@@ -505,7 +506,7 @@ sn9c102_find_eof_header(struct sn9c102_d + size_t eoflen = sizeof(sn9c102_eof_header_t), i; + unsigned j, n = sizeof(sn9c102_eof_header) / eoflen; + +- if (cam->sensor->pix_format.pixelformat == V4L2_PIX_FMT_SN9C10X) ++ if (cam->sensor.pix_format.pixelformat == V4L2_PIX_FMT_SN9C10X) + return NULL; /* EOF header does not exist in compressed data */ + + for (i = 0; (len >= eoflen) && (i <= len - eoflen); i++) +@@ -535,7 +536,7 @@ static void sn9c102_urb_complete(struct + if ((*f)) + (*f)->state = F_QUEUED; + DBG(3, "Stream interrupted"); +- wake_up_interruptible(&cam->wait_stream); ++ wake_up(&cam->wait_stream); + } + + if (cam->state & DEV_DISCONNECTED) +@@ -553,9 +554,9 @@ static void sn9c102_urb_complete(struct + (*f) = list_entry(cam->inqueue.next, struct sn9c102_frame_t, + frame); + +- imagesize = (cam->sensor->pix_format.width * +- cam->sensor->pix_format.height * +- cam->sensor->pix_format.priv) / 8; ++ imagesize = (cam->sensor.pix_format.width * ++ cam->sensor.pix_format.height * ++ cam->sensor.pix_format.priv) / 8; + + soflen = (cam->bridge) == BRIDGE_SN9C103 ? + sizeof(sn9c103_sof_header_t) : +@@ -579,7 +580,7 @@ static void sn9c102_urb_complete(struct + + redo: + sof = sn9c102_find_sof_header(cam, pos, len); +- if (!sof) { ++ if (likely(!sof)) { + eof = sn9c102_find_eof_header(cam, pos, len); + if ((*f)->state == F_GRABBING) { + end_of_frame: +@@ -589,8 +590,9 @@ end_of_frame: + img = (eof > pos) ? eof - pos - 1 : 0; + + if ((*f)->buf.bytesused+img > imagesize) { +- u32 b = (*f)->buf.bytesused + img - +- imagesize; ++ u32 b; ++ b = (*f)->buf.bytesused + img - ++ imagesize; + img = imagesize - (*f)->buf.bytesused; + DBG(3, "Expected EOF not found: " + "video frame cut"); +@@ -608,9 +610,10 @@ end_of_frame: + (*f)->buf.bytesused += img; + + if ((*f)->buf.bytesused == imagesize || +- (cam->sensor->pix_format.pixelformat == ++ (cam->sensor.pix_format.pixelformat == + V4L2_PIX_FMT_SN9C10X && eof)) { +- u32 b = (*f)->buf.bytesused; ++ u32 b; ++ b = (*f)->buf.bytesused; + (*f)->state = F_DONE; + (*f)->buf.sequence= ++cam->frame_count; + spin_lock(&cam->queue_lock); +@@ -667,7 +670,7 @@ start_of_frame: + if (eof && eof < sof) + goto end_of_frame; /* (1) */ + else { +- if (cam->sensor->pix_format.pixelformat == ++ if (cam->sensor.pix_format.pixelformat == + V4L2_PIX_FMT_SN9C10X) { + eof = sof - soflen; + goto end_of_frame; +@@ -808,20 +811,21 @@ static int sn9c102_stop_transfer(struct + + static int sn9c102_stream_interrupt(struct sn9c102_device* cam) + { +- int err = 0; ++ long timeout; + + cam->stream = STREAM_INTERRUPT; +- err = wait_event_timeout(cam->wait_stream, +- (cam->stream == STREAM_OFF) || +- (cam->state & DEV_DISCONNECTED), +- SN9C102_URB_TIMEOUT); ++ timeout = wait_event_timeout(cam->wait_stream, ++ (cam->stream == STREAM_OFF) || ++ (cam->state & DEV_DISCONNECTED), ++ SN9C102_URB_TIMEOUT); + if (cam->state & DEV_DISCONNECTED) + return -ENODEV; +- else if (err) { ++ else if (cam->stream != STREAM_OFF) { + cam->state |= DEV_MISCONFIGURED; +- DBG(1, "The camera is misconfigured. To use it, close and " +- "open /dev/video%d again.", cam->v4ldev->minor); +- return err; ++ DBG(1, "URB timeout reached. The camera is misconfigured. " ++ "To use it, close and open /dev/video%d again.", ++ cam->v4ldev->minor); ++ return -EIO; + } + + return 0; +@@ -1057,7 +1061,7 @@ static ssize_t sn9c102_show_i2c_val(stru + return -ENODEV; + } + +- if (!(cam->sensor->sysfs_ops & SN9C102_I2C_READ)) { ++ if (!(cam->sensor.sysfs_ops & SN9C102_I2C_READ)) { + mutex_unlock(&sn9c102_sysfs_lock); + return -ENOSYS; + } +@@ -1094,7 +1098,7 @@ sn9c102_store_i2c_val(struct class_devic + return -ENODEV; + } + +- if (!(cam->sensor->sysfs_ops & SN9C102_I2C_WRITE)) { ++ if (!(cam->sensor.sysfs_ops & SN9C102_I2C_WRITE)) { + mutex_unlock(&sn9c102_sysfs_lock); + return -ENOSYS; + } +@@ -1249,7 +1253,7 @@ static void sn9c102_create_sysfs(struct + video_device_create_file(v4ldev, &class_device_attr_blue); + video_device_create_file(v4ldev, &class_device_attr_red); + } +- if (cam->sensor && cam->sensor->sysfs_ops) { ++ if (cam->sensor.sysfs_ops) { + video_device_create_file(v4ldev, &class_device_attr_i2c_reg); + video_device_create_file(v4ldev, &class_device_attr_i2c_val); + } +@@ -1312,7 +1316,7 @@ static int sn9c102_set_scale(struct sn9c + + static int sn9c102_set_crop(struct sn9c102_device* cam, struct v4l2_rect* rect) + { +- struct sn9c102_sensor* s = cam->sensor; ++ struct sn9c102_sensor* s = &cam->sensor; + u8 h_start = (u8)(rect->left - s->cropcap.bounds.left), + v_start = (u8)(rect->top - s->cropcap.bounds.top), + h_size = (u8)(rect->width / 16), +@@ -1335,7 +1339,7 @@ static int sn9c102_set_crop(struct sn9c1 + + static int sn9c102_init(struct sn9c102_device* cam) + { +- struct sn9c102_sensor* s = cam->sensor; ++ struct sn9c102_sensor* s = &cam->sensor; + struct v4l2_control ctrl; + struct v4l2_queryctrl *qctrl; + struct v4l2_rect* rect; +@@ -1428,6 +1432,8 @@ static void sn9c102_release_resources(st + video_set_drvdata(cam->v4ldev, NULL); + video_unregister_device(cam->v4ldev); + ++ usb_put_dev(cam->usbdev); ++ + mutex_unlock(&sn9c102_sysfs_lock); + + kfree(cam->control_buffer); +@@ -1541,6 +1547,7 @@ sn9c102_read(struct file* filp, char __u + struct sn9c102_device* cam = video_get_drvdata(video_devdata(filp)); + struct sn9c102_frame_t* f, * i; + unsigned long lock_flags; ++ long timeout; + int err = 0; + + if (mutex_lock_interruptible(&cam->fileop_mutex)) +@@ -1592,20 +1599,22 @@ sn9c102_read(struct file* filp, char __u + mutex_unlock(&cam->fileop_mutex); + return -EAGAIN; + } +- err = wait_event_interruptible +- ( cam->wait_frame, +- (!list_empty(&cam->outqueue)) || +- (cam->state & DEV_DISCONNECTED) || +- (cam->state & DEV_MISCONFIGURED) ); +- if (err) { ++ timeout = wait_event_interruptible_timeout ++ ( cam->wait_frame, ++ (!list_empty(&cam->outqueue)) || ++ (cam->state & DEV_DISCONNECTED) || ++ (cam->state & DEV_MISCONFIGURED), ++ cam->module_param.frame_timeout * ++ 1000 * msecs_to_jiffies(1) ); ++ if (timeout < 0) { + mutex_unlock(&cam->fileop_mutex); +- return err; ++ return timeout; + } + if (cam->state & DEV_DISCONNECTED) { + mutex_unlock(&cam->fileop_mutex); + return -ENODEV; + } +- if (cam->state & DEV_MISCONFIGURED) { ++ if (!timeout || (cam->state & DEV_MISCONFIGURED)) { + mutex_unlock(&cam->fileop_mutex); + return -EIO; + } +@@ -1816,6 +1825,7 @@ sn9c102_vidioc_enuminput(struct sn9c102_ + + memset(&i, 0, sizeof(i)); + strcpy(i.name, "Camera"); ++ i.type = V4L2_INPUT_TYPE_CAMERA; + + if (copy_to_user(arg, &i, sizeof(i))) + return -EFAULT; +@@ -1825,7 +1835,19 @@ sn9c102_vidioc_enuminput(struct sn9c102_ + + + static int +-sn9c102_vidioc_gs_input(struct sn9c102_device* cam, void __user * arg) ++sn9c102_vidioc_g_input(struct sn9c102_device* cam, void __user * arg) ++{ ++ int index = 0; ++ ++ if (copy_to_user(arg, &index, sizeof(index))) ++ return -EFAULT; ++ ++ return 0; ++} ++ ++ ++static int ++sn9c102_vidioc_s_input(struct sn9c102_device* cam, void __user * arg) + { + int index; + +@@ -1842,7 +1864,7 @@ sn9c102_vidioc_gs_input(struct sn9c102_d + static int + sn9c102_vidioc_query_ctrl(struct sn9c102_device* cam, void __user * arg) + { +- struct sn9c102_sensor* s = cam->sensor; ++ struct sn9c102_sensor* s = &cam->sensor; + struct v4l2_queryctrl qc; + u8 i; + +@@ -1864,7 +1886,7 @@ sn9c102_vidioc_query_ctrl(struct sn9c102 + static int + sn9c102_vidioc_g_ctrl(struct sn9c102_device* cam, void __user * arg) + { +- struct sn9c102_sensor* s = cam->sensor; ++ struct sn9c102_sensor* s = &cam->sensor; + struct v4l2_control ctrl; + int err = 0; + u8 i; +@@ -1896,7 +1918,7 @@ exit: + static int + sn9c102_vidioc_s_ctrl(struct sn9c102_device* cam, void __user * arg) + { +- struct sn9c102_sensor* s = cam->sensor; ++ struct sn9c102_sensor* s = &cam->sensor; + struct v4l2_control ctrl; + u8 i; + int err = 0; +@@ -1909,6 +1931,8 @@ sn9c102_vidioc_s_ctrl(struct sn9c102_dev + + for (i = 0; i < ARRAY_SIZE(s->qctrl); i++) + if (ctrl.id == s->qctrl[i].id) { ++ if (s->qctrl[i].flags & V4L2_CTRL_FLAG_DISABLED) ++ return -EINVAL; + if (ctrl.value < s->qctrl[i].minimum || + ctrl.value > s->qctrl[i].maximum) + return -ERANGE; +@@ -1931,7 +1955,7 @@ sn9c102_vidioc_s_ctrl(struct sn9c102_dev + static int + sn9c102_vidioc_cropcap(struct sn9c102_device* cam, void __user * arg) + { +- struct v4l2_cropcap* cc = &(cam->sensor->cropcap); ++ struct v4l2_cropcap* cc = &(cam->sensor.cropcap); + + cc->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + cc->pixelaspect.numerator = 1; +@@ -1947,7 +1971,7 @@ sn9c102_vidioc_cropcap(struct sn9c102_de + static int + sn9c102_vidioc_g_crop(struct sn9c102_device* cam, void __user * arg) + { +- struct sn9c102_sensor* s = cam->sensor; ++ struct sn9c102_sensor* s = &cam->sensor; + struct v4l2_crop crop = { + .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, + }; +@@ -1964,7 +1988,7 @@ sn9c102_vidioc_g_crop(struct sn9c102_dev + static int + sn9c102_vidioc_s_crop(struct sn9c102_device* cam, void __user * arg) + { +- struct sn9c102_sensor* s = cam->sensor; ++ struct sn9c102_sensor* s = &cam->sensor; + struct v4l2_crop crop; + struct v4l2_rect* rect; + struct v4l2_rect* bounds = &(s->cropcap.bounds); +@@ -2105,7 +2129,7 @@ static int + sn9c102_vidioc_g_fmt(struct sn9c102_device* cam, void __user * arg) + { + struct v4l2_format format; +- struct v4l2_pix_format* pfmt = &(cam->sensor->pix_format); ++ struct v4l2_pix_format* pfmt = &(cam->sensor.pix_format); + + if (copy_from_user(&format, arg, sizeof(format))) + return -EFAULT; +@@ -2130,7 +2154,7 @@ static int + sn9c102_vidioc_try_s_fmt(struct sn9c102_device* cam, unsigned int cmd, + void __user * arg) + { +- struct sn9c102_sensor* s = cam->sensor; ++ struct sn9c102_sensor* s = &cam->sensor; + struct v4l2_format format; + struct v4l2_pix_format* pix; + struct v4l2_pix_format* pfmt = &(s->pix_format); +@@ -2417,7 +2441,7 @@ sn9c102_vidioc_dqbuf(struct sn9c102_devi + struct v4l2_buffer b; + struct sn9c102_frame_t *f; + unsigned long lock_flags; +- int err = 0; ++ long timeout; + + if (copy_from_user(&b, arg, sizeof(b))) + return -EFAULT; +@@ -2430,16 +2454,18 @@ sn9c102_vidioc_dqbuf(struct sn9c102_devi + return -EINVAL; + if (filp->f_flags & O_NONBLOCK) + return -EAGAIN; +- err = wait_event_interruptible +- ( cam->wait_frame, +- (!list_empty(&cam->outqueue)) || +- (cam->state & DEV_DISCONNECTED) || +- (cam->state & DEV_MISCONFIGURED) ); +- if (err) +- return err; ++ timeout = wait_event_interruptible_timeout ++ ( cam->wait_frame, ++ (!list_empty(&cam->outqueue)) || ++ (cam->state & DEV_DISCONNECTED) || ++ (cam->state & DEV_MISCONFIGURED), ++ cam->module_param.frame_timeout * ++ 1000 * msecs_to_jiffies(1) ); ++ if (timeout < 0) ++ return timeout; + if (cam->state & DEV_DISCONNECTED) + return -ENODEV; +- if (cam->state & DEV_MISCONFIGURED) ++ if (!timeout || (cam->state & DEV_MISCONFIGURED)) + return -EIO; + } + +@@ -2571,8 +2597,10 @@ static int sn9c102_ioctl_v4l2(struct ino + return sn9c102_vidioc_enuminput(cam, arg); + + case VIDIOC_G_INPUT: ++ return sn9c102_vidioc_g_input(cam, arg); ++ + case VIDIOC_S_INPUT: +- return sn9c102_vidioc_gs_input(cam, arg); ++ return sn9c102_vidioc_s_input(cam, arg); + + case VIDIOC_QUERYCTRL: + return sn9c102_vidioc_query_ctrl(cam, arg); +@@ -2752,10 +2780,10 @@ sn9c102_usb_probe(struct usb_interface* + break; + } + +- if (!err && cam->sensor) { +- DBG(2, "%s image sensor detected", cam->sensor->name); ++ if (!err) { ++ DBG(2, "%s image sensor detected", cam->sensor.name); + DBG(3, "Support for %s maintained by %s", +- cam->sensor->name, cam->sensor->maintainer); ++ cam->sensor.name, cam->sensor.maintainer); + } else { + DBG(1, "No supported image sensor detected"); + err = -ENODEV; +@@ -2793,6 +2821,7 @@ sn9c102_usb_probe(struct usb_interface* + DBG(2, "V4L2 device registered as /dev/video%d", cam->v4ldev->minor); + + cam->module_param.force_munmap = force_munmap[dev_nr]; ++ cam->module_param.frame_timeout = frame_timeout[dev_nr]; + + dev_nr = (dev_nr < SN9C102_MAX_DEVICES-1) ? dev_nr+1 : 0; + +@@ -2841,7 +2870,8 @@ static void sn9c102_usb_disconnect(struc + sn9c102_stop_transfer(cam); + cam->state |= DEV_DISCONNECTED; + wake_up_interruptible(&cam->wait_frame); +- wake_up_interruptible(&cam->wait_stream); ++ wake_up(&cam->wait_stream); ++ usb_get_dev(cam->usbdev); + } else { + cam->state |= DEV_DISCONNECTED; + sn9c102_release_resources(cam); +--- gregkh-2.6.orig/drivers/usb/media/sn9c102.h ++++ gregkh-2.6/drivers/usb/media/sn9c102.h +@@ -34,7 +34,8 @@ + #include <linux/param.h> + #include <linux/rwsem.h> + #include <linux/mutex.h> +-#include <asm/semaphore.h> ++#include <linux/string.h> ++#include <linux/stddef.h> + + #include "sn9c102_sensor.h" + +@@ -51,6 +52,7 @@ + #define SN9C102_ALTERNATE_SETTING 8 + #define SN9C102_URB_TIMEOUT msecs_to_jiffies(2 * SN9C102_ISO_PACKETS) + #define SN9C102_CTRL_TIMEOUT 300 ++#define SN9C102_FRAME_TIMEOUT 2 + + /*****************************************************************************/ + +@@ -108,6 +110,7 @@ struct sn9c102_sysfs_attr { + + struct sn9c102_module_param { + u8 force_munmap; ++ u16 frame_timeout; + }; + + static DEFINE_MUTEX(sn9c102_sysfs_lock); +@@ -117,7 +120,7 @@ struct sn9c102_device { + struct video_device* v4ldev; + + enum sn9c102_bridge bridge; +- struct sn9c102_sensor* sensor; ++ struct sn9c102_sensor sensor; + + struct usb_device* usbdev; + struct urb* urb[SN9C102_URBS]; +@@ -149,12 +152,21 @@ struct sn9c102_device { + + /*****************************************************************************/ + ++struct sn9c102_device* ++sn9c102_match_id(struct sn9c102_device* cam, const struct usb_device_id *id) ++{ ++ if (usb_match_id(usb_ifnum_to_if(cam->usbdev, 0), id)) ++ return cam; ++ ++ return NULL; ++} ++ ++ + void + sn9c102_attach_sensor(struct sn9c102_device* cam, + struct sn9c102_sensor* sensor) + { +- cam->sensor = sensor; +- cam->sensor->usbdev = cam->usbdev; ++ memcpy(&cam->sensor, sensor, sizeof(struct sn9c102_sensor)); + } + + /*****************************************************************************/ +@@ -197,7 +209,8 @@ do { + + #undef PDBG + #define PDBG(fmt, args...) \ +-dev_info(&cam->dev, "[%s:%d] " fmt "\n", __FUNCTION__, __LINE__ , ## args) ++dev_info(&cam->usbdev->dev, "[%s:%d] " fmt "\n", \ ++ __FUNCTION__, __LINE__ , ## args) + + #undef PDBGG + #define PDBGG(fmt, args...) do {;} while(0) /* placeholder */ +--- gregkh-2.6.orig/drivers/usb/media/sn9c102_ov7630.c ++++ gregkh-2.6/drivers/usb/media/sn9c102_ov7630.c +@@ -34,8 +34,8 @@ static int ov7630_init(struct sn9c102_de + err += sn9c102_write_reg(cam, 0x0f, 0x18); + err += sn9c102_write_reg(cam, 0x50, 0x19); + +- err += sn9c102_i2c_write(cam, 0x12, 0x8d); +- err += sn9c102_i2c_write(cam, 0x11, 0x00); ++ err += sn9c102_i2c_write(cam, 0x12, 0x80); ++ err += sn9c102_i2c_write(cam, 0x11, 0x01); + err += sn9c102_i2c_write(cam, 0x15, 0x34); + err += sn9c102_i2c_write(cam, 0x16, 0x03); + err += sn9c102_i2c_write(cam, 0x17, 0x1c); +@@ -43,12 +43,14 @@ static int ov7630_init(struct sn9c102_de + err += sn9c102_i2c_write(cam, 0x19, 0x06); + err += sn9c102_i2c_write(cam, 0x1a, 0xf6); + err += sn9c102_i2c_write(cam, 0x1b, 0x04); +- err += sn9c102_i2c_write(cam, 0x20, 0x44); ++ err += sn9c102_i2c_write(cam, 0x20, 0xf6); + err += sn9c102_i2c_write(cam, 0x23, 0xee); + err += sn9c102_i2c_write(cam, 0x26, 0xa0); + err += sn9c102_i2c_write(cam, 0x27, 0x9a); +- err += sn9c102_i2c_write(cam, 0x28, 0x20); ++ err += sn9c102_i2c_write(cam, 0x28, 0xa0); + err += sn9c102_i2c_write(cam, 0x29, 0x30); ++ err += sn9c102_i2c_write(cam, 0x2a, 0xa0); ++ err += sn9c102_i2c_write(cam, 0x2b, 0x1f); + err += sn9c102_i2c_write(cam, 0x2f, 0x3d); + err += sn9c102_i2c_write(cam, 0x30, 0x24); + err += sn9c102_i2c_write(cam, 0x32, 0x86); +@@ -80,7 +82,7 @@ static int ov7630_set_ctrl(struct sn9c10 + err += sn9c102_i2c_write(cam, 0x02, ctrl->value); + break; + case V4L2_CID_BLUE_BALANCE: +- err += sn9c102_i2c_write(cam, 0x03, ctrl->value); ++ err += sn9c102_i2c_write(cam, 0x01, ctrl->value); + break; + case V4L2_CID_GAIN: + err += sn9c102_i2c_write(cam, 0x00, ctrl->value); +@@ -108,7 +110,7 @@ static int ov7630_set_ctrl(struct sn9c10 + err += sn9c102_i2c_write(cam, 0x0d, ctrl->value); + break; + case V4L2_CID_AUTO_WHITE_BALANCE: +- err += sn9c102_i2c_write(cam, 0x12, (ctrl->value << 2) | 0x09); ++ err += sn9c102_i2c_write(cam, 0x12, (ctrl->value << 2) | 0x78); + break; + case V4L2_CID_AUTOGAIN: + err += sn9c102_i2c_write(cam, 0x13, ctrl->value); +@@ -371,26 +373,29 @@ static struct sn9c102_sensor ov7630 = { + + int sn9c102_probe_ov7630(struct sn9c102_device* cam) + { ++ const struct usb_device_id ov7630_id_table[] = { ++ { USB_DEVICE(0x0c45, 0x602c), }, ++ { USB_DEVICE(0x0c45, 0x602d), }, ++ { USB_DEVICE(0x0c45, 0x608f), }, ++ { USB_DEVICE(0x0c45, 0x60b0), }, ++ { } ++ }; + int err = 0; + +- sn9c102_attach_sensor(cam, &ov7630); +- +- if (le16_to_cpu(ov7630.usbdev->descriptor.idProduct) != 0x602c && +- le16_to_cpu(ov7630.usbdev->descriptor.idProduct) != 0x602d && +- le16_to_cpu(ov7630.usbdev->descriptor.idProduct) != 0x608f && +- le16_to_cpu(ov7630.usbdev->descriptor.idProduct) != 0x60b0) ++ if (!sn9c102_match_id(cam, ov7630_id_table)) + return -ENODEV; + + err += sn9c102_write_reg(cam, 0x01, 0x01); + err += sn9c102_write_reg(cam, 0x00, 0x01); + err += sn9c102_write_reg(cam, 0x28, 0x17); +- + if (err) + return -EIO; + +- err += sn9c102_i2c_write(cam, 0x0b, 0); ++ err += sn9c102_i2c_try_write(cam, &ov7630, 0x0b, 0); + if (err) + return -ENODEV; + ++ sn9c102_attach_sensor(cam, &ov7630); ++ + return 0; + } +--- /dev/null ++++ gregkh-2.6/drivers/usb/media/sn9c102_pas202bca.c +@@ -0,0 +1,238 @@ ++/*************************************************************************** ++ * Plug-in for PAS202BCA image sensor connected to the SN9C10x PC Camera * ++ * Controllers * ++ * * ++ * Copyright (C) 2006 by Luca Risolia <luca.risolia@studio.unibo.it> * ++ * * ++ * This program is free software; you can redistribute it and/or modify * ++ * it under the terms of the GNU General Public License as published by * ++ * the Free Software Foundation; either version 2 of the License, or * ++ * (at your option) any later version. * ++ * * ++ * This program is distributed in the hope that it will be useful, * ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of * ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * ++ * GNU General Public License for more details. * ++ * * ++ * You should have received a copy of the GNU General Public License * ++ * along with this program; if not, write to the Free Software * ++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * ++ ***************************************************************************/ ++ ++#include <linux/delay.h> ++#include "sn9c102_sensor.h" ++ ++ ++static struct sn9c102_sensor pas202bca; ++ ++ ++static int pas202bca_init(struct sn9c102_device* cam) ++{ ++ int err = 0; ++ ++ err += sn9c102_write_reg(cam, 0x00, 0x10); ++ err += sn9c102_write_reg(cam, 0x00, 0x11); ++ err += sn9c102_write_reg(cam, 0x00, 0x14); ++ err += sn9c102_write_reg(cam, 0x20, 0x17); ++ err += sn9c102_write_reg(cam, 0x30, 0x19); ++ err += sn9c102_write_reg(cam, 0x09, 0x18); ++ ++ err += sn9c102_i2c_write(cam, 0x02, 0x14); ++ err += sn9c102_i2c_write(cam, 0x03, 0x40); ++ err += sn9c102_i2c_write(cam, 0x0d, 0x2c); ++ err += sn9c102_i2c_write(cam, 0x0e, 0x01); ++ err += sn9c102_i2c_write(cam, 0x0f, 0xa9); ++ err += sn9c102_i2c_write(cam, 0x10, 0x08); ++ err += sn9c102_i2c_write(cam, 0x13, 0x63); ++ err += sn9c102_i2c_write(cam, 0x15, 0x70); ++ err += sn9c102_i2c_write(cam, 0x11, 0x01); ++ ++ msleep(400); ++ ++ return err; ++} ++ ++ ++static int pas202bca_set_pix_format(struct sn9c102_device* cam, ++ const struct v4l2_pix_format* pix) ++{ ++ int err = 0; ++ ++ if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X) ++ err += sn9c102_write_reg(cam, 0x24, 0x17); ++ else ++ err += sn9c102_write_reg(cam, 0x20, 0x17); ++ ++ return err; ++} ++ ++ ++static int pas202bca_set_ctrl(struct sn9c102_device* cam, ++ const struct v4l2_control* ctrl) ++{ ++ int err = 0; ++ ++ switch (ctrl->id) { ++ case V4L2_CID_EXPOSURE: ++ err += sn9c102_i2c_write(cam, 0x04, ctrl->value >> 6); ++ err += sn9c102_i2c_write(cam, 0x05, ctrl->value & 0x3f); ++ break; ++ case V4L2_CID_RED_BALANCE: ++ err += sn9c102_i2c_write(cam, 0x09, ctrl->value); ++ break; ++ case V4L2_CID_BLUE_BALANCE: ++ err += sn9c102_i2c_write(cam, 0x07, ctrl->value); ++ break; ++ case V4L2_CID_GAIN: ++ err += sn9c102_i2c_write(cam, 0x10, ctrl->value); ++ break; ++ case SN9C102_V4L2_CID_GREEN_BALANCE: ++ err += sn9c102_i2c_write(cam, 0x08, ctrl->value); ++ break; ++ case SN9C102_V4L2_CID_DAC_MAGNITUDE: ++ err += sn9c102_i2c_write(cam, 0x0c, ctrl->value); ++ break; ++ default: ++ return -EINVAL; ++ } ++ err += sn9c102_i2c_write(cam, 0x11, 0x01); ++ ++ return err ? -EIO : 0; ++} ++ ++ ++static int pas202bca_set_crop(struct sn9c102_device* cam, ++ const struct v4l2_rect* rect) ++{ ++ struct sn9c102_sensor* s = &pas202bca; ++ int err = 0; ++ u8 h_start = (u8)(rect->left - s->cropcap.bounds.left) + 3, ++ v_start = (u8)(rect->top - s->cropcap.bounds.top) + 3; ++ ++ err += sn9c102_write_reg(cam, h_start, 0x12); ++ err += sn9c102_write_reg(cam, v_start, 0x13); ++ ++ return err; ++} ++ ++ ++static struct sn9c102_sensor pas202bca = { ++ .name = "PAS202BCA", ++ .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>", ++ .sysfs_ops = SN9C102_I2C_READ | SN9C102_I2C_WRITE, ++ .frequency = SN9C102_I2C_400KHZ | SN9C102_I2C_100KHZ, ++ .interface = SN9C102_I2C_2WIRES, ++ .i2c_slave_id = 0x40, ++ .init = &pas202bca_init, ++ .qctrl = { ++ { ++ .id = V4L2_CID_EXPOSURE, ++ .type = V4L2_CTRL_TYPE_INTEGER, ++ .name = "exposure", ++ .minimum = 0x01e5, ++ .maximum = 0x3fff, ++ .step = 0x0001, ++ .default_value = 0x01e5, ++ .flags = 0, ++ }, ++ { ++ .id = V4L2_CID_GAIN, ++ .type = V4L2_CTRL_TYPE_INTEGER, ++ .name = "global gain", ++ .minimum = 0x00, ++ .maximum = 0x1f, ++ .step = 0x01, ++ .default_value = 0x0c, ++ .flags = 0, ++ }, ++ { ++ .id = V4L2_CID_RED_BALANCE, ++ .type = V4L2_CTRL_TYPE_INTEGER, ++ .name = "red balance", ++ .minimum = 0x00, ++ .maximum = 0x0f, ++ .step = 0x01, ++ .default_value = 0x01, ++ .flags = 0, ++ }, ++ { ++ .id = V4L2_CID_BLUE_BALANCE, ++ .type = V4L2_CTRL_TYPE_INTEGER, ++ .name = "blue balance", ++ .minimum = 0x00, ++ .maximum = 0x0f, ++ .step = 0x01, ++ .default_value = 0x05, ++ .flags = 0, ++ }, ++ { ++ .id = SN9C102_V4L2_CID_GREEN_BALANCE, ++ .type = V4L2_CTRL_TYPE_INTEGER, ++ .name = "green balance", ++ .minimum = 0x00, ++ .maximum = 0x0f, ++ .step = 0x01, ++ .default_value = 0x00, ++ .flags = 0, ++ }, ++ { ++ .id = SN9C102_V4L2_CID_DAC_MAGNITUDE, ++ .type = V4L2_CTRL_TYPE_INTEGER, ++ .name = "DAC magnitude", ++ .minimum = 0x00, ++ .maximum = 0xff, ++ .step = 0x01, ++ .default_value = 0x04, ++ .flags = 0, ++ }, ++ }, ++ .set_ctrl = &pas202bca_set_ctrl, ++ .cropcap = { ++ .bounds = { ++ .left = 0, ++ .top = 0, ++ .width = 640, ++ .height = 480, ++ }, ++ .defrect = { ++ .left = 0, ++ .top = 0, ++ .width = 640, ++ .height = 480, ++ }, ++ }, ++ .set_crop = &pas202bca_set_crop, ++ .pix_format = { ++ .width = 640, ++ .height = 480, ++ .pixelformat = V4L2_PIX_FMT_SBGGR8, ++ .priv = 8, ++ }, ++ .set_pix_format = &pas202bca_set_pix_format ++}; ++ ++ ++int sn9c102_probe_pas202bca(struct sn9c102_device* cam) ++{ ++ const struct usb_device_id pas202bca_id_table[] = { ++ { USB_DEVICE(0x0c45, 0x60af), }, ++ { } ++ }; ++ int err = 0; ++ ++ if (!sn9c102_match_id(cam,pas202bca_id_table)) ++ return -ENODEV; ++ ++ err += sn9c102_write_reg(cam, 0x01, 0x01); ++ err += sn9c102_write_reg(cam, 0x40, 0x01); ++ err += sn9c102_write_reg(cam, 0x28, 0x17); ++ if (err) ++ return -EIO; ++ ++ if (sn9c102_i2c_try_write(cam, &pas202bca, 0x10, 0)) /* try to write */ ++ return -ENODEV; ++ ++ sn9c102_attach_sensor(cam, &pas202bca); ++ ++ return 0; ++} +--- gregkh-2.6.orig/drivers/usb/media/sn9c102_pas202bcb.c ++++ gregkh-2.6/drivers/usb/media/sn9c102_pas202bcb.c +@@ -263,7 +263,7 @@ static struct sn9c102_sensor pas202bcb = + + + int sn9c102_probe_pas202bcb(struct sn9c102_device* cam) +-{ ++{ + int r0 = 0, r1 = 0, err = 0; + unsigned int pid = 0; + +--- gregkh-2.6.orig/drivers/usb/media/sn9c102_sensor.h ++++ gregkh-2.6/drivers/usb/media/sn9c102_sensor.h +@@ -66,6 +66,7 @@ extern int sn9c102_probe_hv7131d(struct + extern int sn9c102_probe_mi0343(struct sn9c102_device* cam); + extern int sn9c102_probe_ov7630(struct sn9c102_device* cam); + extern int sn9c102_probe_pas106b(struct sn9c102_device* cam); ++extern int sn9c102_probe_pas202bca(struct sn9c102_device* cam); + extern int sn9c102_probe_pas202bcb(struct sn9c102_device* cam); + extern int sn9c102_probe_tas5110c1b(struct sn9c102_device* cam); + extern int sn9c102_probe_tas5130d1b(struct sn9c102_device* cam); +@@ -81,12 +82,17 @@ static int (*sn9c102_sensor_table[])(str + &sn9c102_probe_pas106b, /* strong detection based on SENSOR ids */ \ + &sn9c102_probe_pas202bcb, /* strong detection based on SENSOR ids */ \ + &sn9c102_probe_hv7131d, /* strong detection based on SENSOR ids */ \ ++ &sn9c102_probe_pas202bca, /* detection mostly based on USB pid/vid */ \ + &sn9c102_probe_ov7630, /* detection mostly based on USB pid/vid */ \ + &sn9c102_probe_tas5110c1b, /* detection based on USB pid/vid */ \ + &sn9c102_probe_tas5130d1b, /* detection based on USB pid/vid */ \ + NULL, \ + }; + ++/* Device identification */ ++extern struct sn9c102_device* ++sn9c102_match_id(struct sn9c102_device* cam, const struct usb_device_id *id); ++ + /* Attach a probed sensor to the camera. */ + extern void + sn9c102_attach_sensor(struct sn9c102_device* cam, +@@ -108,6 +114,7 @@ sn9c102_attach_sensor(struct sn9c102_dev + static const struct usb_device_id sn9c102_id_table[] = { \ + { USB_DEVICE(0x0c45, 0x6001), }, /* TAS5110C1B */ \ + { USB_DEVICE(0x0c45, 0x6005), }, /* TAS5110C1B */ \ ++ { USB_DEVICE(0x0c45, 0x6007), }, \ + { USB_DEVICE(0x0c45, 0x6009), }, /* PAS106B */ \ + { USB_DEVICE(0x0c45, 0x600d), }, /* PAS106B */ \ + { USB_DEVICE(0x0c45, 0x6024), }, \ +@@ -126,7 +133,7 @@ static const struct usb_device_id sn9c10 + { SN9C102_USB_DEVICE(0x0c45, 0x6088, 0xff), }, \ + { SN9C102_USB_DEVICE(0x0c45, 0x608a, 0xff), }, \ + { SN9C102_USB_DEVICE(0x0c45, 0x608b, 0xff), }, \ +- { SN9C102_USB_DEVICE(0x0c45, 0x608c, 0xff), }, /* HV7131x */ \ ++ { SN9C102_USB_DEVICE(0x0c45, 0x608c, 0xff), }, /* HV7131/R */ \ + { SN9C102_USB_DEVICE(0x0c45, 0x608e, 0xff), }, /* CIS-VF10 */ \ + { SN9C102_USB_DEVICE(0x0c45, 0x608f, 0xff), }, /* OV7630 */ \ + { SN9C102_USB_DEVICE(0x0c45, 0x60a0, 0xff), }, \ +@@ -359,12 +366,6 @@ struct sn9c102_sensor { + error code without rolling back. + */ + +- const struct usb_device* usbdev; +- /* +- Points to the usb_device struct after the sensor is attached. +- Do not touch unless you know what you are doing. +- */ +- + /* + Do NOT write to the data below, it's READ ONLY. It is used by the + core module to store successfully updated values of the above +--- gregkh-2.6.orig/drivers/usb/media/sn9c102_tas5110c1b.c ++++ gregkh-2.6/drivers/usb/media/sn9c102_tas5110c1b.c +@@ -142,14 +142,18 @@ static struct sn9c102_sensor tas5110c1b + + int sn9c102_probe_tas5110c1b(struct sn9c102_device* cam) + { +- /* This sensor has no identifiers, so let's attach it anyway */ +- sn9c102_attach_sensor(cam, &tas5110c1b); ++ const struct usb_device_id tas5110c1b_id_table[] = { ++ { USB_DEVICE(0x0c45, 0x6001), }, ++ { USB_DEVICE(0x0c45, 0x6005), }, ++ { USB_DEVICE(0x0c45, 0x60ab), }, ++ { } ++ }; + + /* Sensor detection is based on USB pid/vid */ +- if (le16_to_cpu(tas5110c1b.usbdev->descriptor.idProduct) != 0x6001 && +- le16_to_cpu(tas5110c1b.usbdev->descriptor.idProduct) != 0x6005 && +- le16_to_cpu(tas5110c1b.usbdev->descriptor.idProduct) != 0x60ab) ++ if (!sn9c102_match_id(cam, tas5110c1b_id_table)) + return -ENODEV; + ++ sn9c102_attach_sensor(cam, &tas5110c1b); ++ + return 0; + } +--- gregkh-2.6.orig/drivers/usb/media/sn9c102_tas5130d1b.c ++++ gregkh-2.6/drivers/usb/media/sn9c102_tas5130d1b.c +@@ -153,13 +153,17 @@ static struct sn9c102_sensor tas5130d1b + + int sn9c102_probe_tas5130d1b(struct sn9c102_device* cam) + { +- /* This sensor has no identifiers, so let's attach it anyway */ +- sn9c102_attach_sensor(cam, &tas5130d1b); ++ const struct usb_device_id tas5130d1b_id_table[] = { ++ { USB_DEVICE(0x0c45, 0x6025), }, ++ { USB_DEVICE(0x0c45, 0x60aa), }, ++ { } ++ }; + + /* Sensor detection is based on USB pid/vid */ +- if (le16_to_cpu(tas5130d1b.usbdev->descriptor.idProduct) != 0x6025 && +- le16_to_cpu(tas5130d1b.usbdev->descriptor.idProduct) != 0x60aa) ++ if (!sn9c102_match_id(cam, tas5130d1b_id_table)) + return -ENODEV; + ++ sn9c102_attach_sensor(cam, &tas5130d1b); ++ + return 0; + } diff --git a/usb/usb-support-for-usb-to-serial-cable-from-speed-dragon-multimedia.patch b/usb/usb-support-for-usb-to-serial-cable-from-speed-dragon-multimedia.patch new file mode 100644 index 0000000000000..043b322d58df9 --- /dev/null +++ b/usb/usb-support-for-usb-to-serial-cable-from-speed-dragon-multimedia.patch @@ -0,0 +1,42 @@ +From akpm@osdl.org Wed Mar 1 15:57:52 2006 +Message-Id: <200603010854.k218sepU024122@shell0.pdx.osdl.net> +Subject: USB: support for USB-to-serial cable from Speed Dragon Multimedia +To: dick@streefland.net, greg@kroah.com, mm-commits@vger.kernel.org +From: akpm@osdl.org +Date: Wed, 01 Mar 2006 00:53:33 -0800 + +From: Dick Streefland <dick@streefland.net> + +The USB data cable for my Samsung GSM phone contains the USB-to-serial +converter chip MS3303H from Speed Dragon Multimedia, Inc. that appears to +be compatible with the PL2303 chip. The following patch adds support for +this chip to the pl2303 driver. + +Signed-off-by: Dick Streefland <dick@streefland.net> +Signed-off-by: Andrew Morton <akpm@osdl.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> +--- + drivers/usb/serial/pl2303.c | 1 + + drivers/usb/serial/pl2303.h | 4 ++++ + 2 files changed, 5 insertions(+) + +--- gregkh-2.6.orig/drivers/usb/serial/pl2303.c ++++ gregkh-2.6/drivers/usb/serial/pl2303.c +@@ -77,6 +77,7 @@ static struct usb_device_id id_table [] + { USB_DEVICE(CA_42_CA42_VENDOR_ID, CA_42_CA42_PRODUCT_ID) }, + { USB_DEVICE(SAGEM_VENDOR_ID, SAGEM_PRODUCT_ID) }, + { USB_DEVICE(LEADTEK_VENDOR_ID, LEADTEK_9531_PRODUCT_ID) }, ++ { USB_DEVICE(SPEEDDRAGON_VENDOR_ID, SPEEDDRAGON_PRODUCT_ID) }, + { } /* Terminating entry */ + }; + +--- gregkh-2.6.orig/drivers/usb/serial/pl2303.h ++++ gregkh-2.6/drivers/usb/serial/pl2303.h +@@ -75,3 +75,7 @@ + /* Leadtek GPS 9531 (ID 0413:2101) */ + #define LEADTEK_VENDOR_ID 0x0413 + #define LEADTEK_9531_PRODUCT_ID 0x2101 ++ ++/* USB GSM cable from Speed Dragon Multimedia, Ltd */ ++#define SPEEDDRAGON_VENDOR_ID 0x0e55 ++#define SPEEDDRAGON_PRODUCT_ID 0x110b diff --git a/usb/usb-uhci-increase-port-reset-completion-delay-for-hp-controllers.patch b/usb/usb-uhci-increase-port-reset-completion-delay-for-hp-controllers.patch new file mode 100644 index 0000000000000..5058539a7913f --- /dev/null +++ b/usb/usb-uhci-increase-port-reset-completion-delay-for-hp-controllers.patch @@ -0,0 +1,59 @@ +From stern@rowland.harvard.edu Wed Mar 1 15:58:26 2006 +Date: Tue, 28 Feb 2006 10:16:12 -0500 (EST) +From: Alan Stern <stern@rowland.harvard.edu> +To: Greg KH <greg@kroah.com> +cc: "Frantz, Chris" <Chris.Frantz@hp.com>, Brian Baker <brian.b@hp.com>, Pete Zaitcev <zaitcev@redhat.com> +Subject: USB: UHCI: Increase port-reset completion delay for HP controllers +Message-ID: <Pine.LNX.4.44L0.0602281011040.4987-100000@iolanthe.rowland.org> + +This patch (as657) increases the port-reset completion delay in uhci-hcd +for HP's embedded controllers. Unlike other UHCI controllers, the HP +chips can take as long as 250 us to carry out the processing associated +with finishing a port reset. + +This fixes Novell bug #148761. + +Signed-off-by: Alan Stern <stern@rowland.harvard.edu> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/usb/host/uhci-hub.c | 21 +++++++++++++++++++++ + 1 file changed, 21 insertions(+) + +--- gregkh-2.6.orig/drivers/usb/host/uhci-hub.c ++++ gregkh-2.6/drivers/usb/host/uhci-hub.c +@@ -99,6 +99,21 @@ static void uhci_finish_suspend(struct u + } + } + ++/* Wait for the UHCI controller in HP's iLO2 server management chip. ++ * It can take up to 250 us to finish a reset and set the CSC bit. ++ */ ++static void wait_for_HP(unsigned long port_addr) ++{ ++ int i; ++ ++ for (i = 10; i < 250; i += 10) { ++ if (inw(port_addr) & USBPORTSC_CSC) ++ return; ++ udelay(10); ++ } ++ /* Log a warning? */ ++} ++ + static void uhci_check_ports(struct uhci_hcd *uhci) + { + unsigned int port; +@@ -113,6 +128,12 @@ static void uhci_check_ports(struct uhci + CLR_RH_PORTSTAT(USBPORTSC_PR); + udelay(10); + ++ /* HP's server management chip requires ++ * a longer delay. */ ++ if (to_pci_dev(uhci_dev(uhci))->vendor == ++ PCI_VENDOR_ID_HP) ++ wait_for_HP(port_addr); ++ + /* If the port was enabled before, turning + * reset on caused a port enable change. + * Turning reset off causes a port connect diff --git a/usb/usb-zc0301-driver-updates-2.patch b/usb/usb-zc0301-driver-updates-2.patch new file mode 100644 index 0000000000000..8ae04c03d3cd0 --- /dev/null +++ b/usb/usb-zc0301-driver-updates-2.patch @@ -0,0 +1,496 @@ +From luca.risolia@studio.unibo.it Fri Feb 24 21:56:12 2006 +Date: Sat, 25 Feb 2006 06:57:49 +0000 +From: Luca Risolia <luca.risolia@studio.unibo.it> +To: Greg Kroah-Hartman <gregkh@suse.de> +Subject: USB: ZC0301 driver updates +Message-ID: <20060225065749.GC31623@studio.unibo.it> +Content-Disposition: inline + +ZC0301 driver updates. + +Changes: + new, - removed, * cleanup, @ bugfix + +@ Need usb_get|put_dev() when disconnecting, if the device is open +* Cleanups and updates in the documentation ++ Use per-device sensor structures ++ Add frame_timeout module parameter + +Signed-off-by: Luca Risolia <luca.risolia@studio.unibo.it> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + Documentation/usb/zc0301.txt | 29 +++++++++++------ + drivers/usb/media/zc0301.h | 20 +++++++++--- + drivers/usb/media/zc0301_core.c | 58 +++++++++++++++++++++-------------- + drivers/usb/media/zc0301_pas202bcb.c | 38 +++++++++++++--------- + drivers/usb/media/zc0301_sensor.h | 25 +++++++++------ + 5 files changed, 108 insertions(+), 62 deletions(-) + +--- gregkh-2.6.orig/Documentation/usb/zc0301.txt ++++ gregkh-2.6/Documentation/usb/zc0301.txt +@@ -68,11 +68,6 @@ Some of the features of the driver are: + data transfers; + - automatic detection of image sensor; + - video format is standard JPEG; +-- full support for the capabilities of every possible image sensors that can +- be connected to the ZC0301 bridges, including, for istance, red, green, +- blue and global gain adjustments and exposure control (see "Supported +- devices" paragraph for details); +-- use of default color settings for sunlight conditions; + - dynamic driver control thanks to various module parameters (see "Module + parameters" paragraph); + - up to 64 cameras can be handled at the same time; they can be connected and +@@ -171,6 +166,14 @@ Description: Force the application to + 1 = force memory unmapping (save memory) + Default: 0 + ------------------------------------------------------------------------------- ++Name: frame_timeout ++Type: uint array (min = 0, max = 64) ++Syntax: <n[,...]> ++Description: Timeout for a video frame in seconds. This parameter is ++ specific for each detected camera. This parameter can be ++ changed at runtime thanks to the /sys filesystem interface. ++Default: 2 ++------------------------------------------------------------------------------- + Name: debug + Type: ushort + Syntax: <n> +@@ -198,17 +201,23 @@ devices mounting the ZC0301 Image Proces + + Vendor ID Product ID + --------- ---------- ++0x10fd 0x8050 ++0x041e 0x0417 ++0x041e 0x041e ++0x041e 0x081c ++0x041e 0x0834 ++0x041e 0x0835 + 0x046d 0x08ae ++0x0ac8 0x0301 + +-The following image sensors are supported: ++The list above does not imply that all those devices work with this driver: up ++until now only the ones that mount the following image sensors are supported; ++kernel messages will always tell you whether this is the case: + + Model Manufacturer + ----- ------------ + PAS202BCB PixArt Imaging, Inc. + +-All the available control settings of each image sensor are supported through +-the V4L2 interface. +- + + 9. Notes for V4L2 application developers + ======================================== +@@ -240,6 +249,6 @@ the fingerprint is: '88E8 F32F 7244 68BA + - Informations about the chip internals needed to enable the I2C protocol have + been taken from the documentation of the ZC030x Video4Linux1 driver written + by Andrew Birkett <andy@nobugs.org>; +-- Initialization values of the ZC0301 controller connected to the PAS202BCB ++- The initialization values of the ZC0301 controller connected to the PAS202BCB + image sensor have been taken from the SPCA5XX driver maintained by + Michel Xhaard <mxhaard@magic.fr>. +--- gregkh-2.6.orig/drivers/usb/media/zc0301_core.c ++++ gregkh-2.6/drivers/usb/media/zc0301_core.c +@@ -29,11 +29,9 @@ + #include <linux/moduleparam.h> + #include <linux/errno.h> + #include <linux/slab.h> +-#include <linux/string.h> + #include <linux/device.h> + #include <linux/fs.h> + #include <linux/delay.h> +-#include <linux/stddef.h> + #include <linux/compiler.h> + #include <linux/ioctl.h> + #include <linux/poll.h> +@@ -54,8 +52,8 @@ + #define ZC0301_MODULE_AUTHOR "(C) 2006 Luca Risolia" + #define ZC0301_AUTHOR_EMAIL "<luca.risolia@studio.unibo.it>" + #define ZC0301_MODULE_LICENSE "GPL" +-#define ZC0301_MODULE_VERSION "1:1.01" +-#define ZC0301_MODULE_VERSION_CODE KERNEL_VERSION(1, 0, 1) ++#define ZC0301_MODULE_VERSION "1:1.02" ++#define ZC0301_MODULE_VERSION_CODE KERNEL_VERSION(1, 0, 2) + + /*****************************************************************************/ + +@@ -94,6 +92,15 @@ MODULE_PARM_DESC(force_munmap, + "\nDefault value is "__MODULE_STRING(SN9C102_FORCE_MUNMAP)"." + "\n"); + ++static unsigned int frame_timeout[] = {[0 ... ZC0301_MAX_DEVICES-1] = ++ ZC0301_FRAME_TIMEOUT}; ++module_param_array(frame_timeout, uint, NULL, 0644); ++MODULE_PARM_DESC(frame_timeout, ++ "\n<n[,...]> Timeout for a video frame in seconds." ++ "\nThis parameter is specific for each detected camera." ++ "\nDefault value is "__MODULE_STRING(ZC0301_FRAME_TIMEOUT)"." ++ "\n"); ++ + #ifdef ZC0301_DEBUG + static unsigned short debug = ZC0301_DEBUG_LEVEL; + module_param(debug, ushort, 0644); +@@ -115,8 +122,8 @@ static u32 + zc0301_request_buffers(struct zc0301_device* cam, u32 count, + enum zc0301_io_method io) + { +- struct v4l2_pix_format* p = &(cam->sensor->pix_format); +- struct v4l2_rect* r = &(cam->sensor->cropcap.bounds); ++ struct v4l2_pix_format* p = &(cam->sensor.pix_format); ++ struct v4l2_rect* r = &(cam->sensor.cropcap.bounds); + const size_t imagesize = cam->module_param.force_munmap || + io == IO_READ ? + (p->width * p->height * p->priv) / 8 : +@@ -332,9 +339,9 @@ static void zc0301_urb_complete(struct u + (*f) = list_entry(cam->inqueue.next, struct zc0301_frame_t, + frame); + +- imagesize = (cam->sensor->pix_format.width * +- cam->sensor->pix_format.height * +- cam->sensor->pix_format.priv) / 8; ++ imagesize = (cam->sensor.pix_format.width * ++ cam->sensor.pix_format.height * ++ cam->sensor.pix_format.priv) / 8; + + for (i = 0; i < urb->number_of_packets; i++) { + unsigned int len, status; +@@ -555,7 +562,7 @@ zc0301_set_compression(struct zc0301_dev + + static int zc0301_init(struct zc0301_device* cam) + { +- struct zc0301_sensor* s = cam->sensor; ++ struct zc0301_sensor* s = &cam->sensor; + struct v4l2_control ctrl; + struct v4l2_queryctrl *qctrl; + struct v4l2_rect* rect; +@@ -630,6 +637,7 @@ static void zc0301_release_resources(str + DBG(2, "V4L2 device /dev/video%d deregistered", cam->v4ldev->minor); + video_set_drvdata(cam->v4ldev, NULL); + video_unregister_device(cam->v4ldev); ++ usb_put_dev(cam->usbdev); + kfree(cam->control_buffer); + } + +@@ -798,7 +806,8 @@ zc0301_read(struct file* filp, char __us + (!list_empty(&cam->outqueue)) || + (cam->state & DEV_DISCONNECTED) || + (cam->state & DEV_MISCONFIGURED), +- ZC0301_FRAME_TIMEOUT ); ++ cam->module_param.frame_timeout * ++ 1000 * msecs_to_jiffies(1) ); + if (timeout < 0) { + mutex_unlock(&cam->fileop_mutex); + return timeout; +@@ -1056,7 +1065,7 @@ zc0301_vidioc_s_input(struct zc0301_devi + static int + zc0301_vidioc_query_ctrl(struct zc0301_device* cam, void __user * arg) + { +- struct zc0301_sensor* s = cam->sensor; ++ struct zc0301_sensor* s = &cam->sensor; + struct v4l2_queryctrl qc; + u8 i; + +@@ -1078,7 +1087,7 @@ zc0301_vidioc_query_ctrl(struct zc0301_d + static int + zc0301_vidioc_g_ctrl(struct zc0301_device* cam, void __user * arg) + { +- struct zc0301_sensor* s = cam->sensor; ++ struct zc0301_sensor* s = &cam->sensor; + struct v4l2_control ctrl; + int err = 0; + u8 i; +@@ -1110,7 +1119,7 @@ exit: + static int + zc0301_vidioc_s_ctrl(struct zc0301_device* cam, void __user * arg) + { +- struct zc0301_sensor* s = cam->sensor; ++ struct zc0301_sensor* s = &cam->sensor; + struct v4l2_control ctrl; + u8 i; + int err = 0; +@@ -1123,6 +1132,8 @@ zc0301_vidioc_s_ctrl(struct zc0301_devic + + for (i = 0; i < ARRAY_SIZE(s->qctrl); i++) + if (ctrl.id == s->qctrl[i].id) { ++ if (s->qctrl[i].flags & V4L2_CTRL_FLAG_DISABLED) ++ return -EINVAL; + if (ctrl.value < s->qctrl[i].minimum || + ctrl.value > s->qctrl[i].maximum) + return -ERANGE; +@@ -1142,7 +1153,7 @@ zc0301_vidioc_s_ctrl(struct zc0301_devic + static int + zc0301_vidioc_cropcap(struct zc0301_device* cam, void __user * arg) + { +- struct v4l2_cropcap* cc = &(cam->sensor->cropcap); ++ struct v4l2_cropcap* cc = &(cam->sensor.cropcap); + + cc->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + cc->pixelaspect.numerator = 1; +@@ -1158,7 +1169,7 @@ zc0301_vidioc_cropcap(struct zc0301_devi + static int + zc0301_vidioc_g_crop(struct zc0301_device* cam, void __user * arg) + { +- struct zc0301_sensor* s = cam->sensor; ++ struct zc0301_sensor* s = &cam->sensor; + struct v4l2_crop crop = { + .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, + }; +@@ -1175,7 +1186,7 @@ zc0301_vidioc_g_crop(struct zc0301_devic + static int + zc0301_vidioc_s_crop(struct zc0301_device* cam, void __user * arg) + { +- struct zc0301_sensor* s = cam->sensor; ++ struct zc0301_sensor* s = &cam->sensor; + struct v4l2_crop crop; + struct v4l2_rect* rect; + struct v4l2_rect* bounds = &(s->cropcap.bounds); +@@ -1304,7 +1315,7 @@ static int + zc0301_vidioc_g_fmt(struct zc0301_device* cam, void __user * arg) + { + struct v4l2_format format; +- struct v4l2_pix_format* pfmt = &(cam->sensor->pix_format); ++ struct v4l2_pix_format* pfmt = &(cam->sensor.pix_format); + + if (copy_from_user(&format, arg, sizeof(format))) + return -EFAULT; +@@ -1328,7 +1339,7 @@ static int + zc0301_vidioc_try_s_fmt(struct zc0301_device* cam, unsigned int cmd, + void __user * arg) + { +- struct zc0301_sensor* s = cam->sensor; ++ struct zc0301_sensor* s = &cam->sensor; + struct v4l2_format format; + struct v4l2_pix_format* pix; + struct v4l2_pix_format* pfmt = &(s->pix_format); +@@ -1612,7 +1623,8 @@ zc0301_vidioc_dqbuf(struct zc0301_device + (!list_empty(&cam->outqueue)) || + (cam->state & DEV_DISCONNECTED) || + (cam->state & DEV_MISCONFIGURED), +- ZC0301_FRAME_TIMEOUT ); ++ cam->module_param.frame_timeout * ++ 1000 * msecs_to_jiffies(1) ); + if (timeout < 0) + return timeout; + if (cam->state & DEV_DISCONNECTED) +@@ -1911,8 +1923,8 @@ zc0301_usb_probe(struct usb_interface* i + break; + } + +- if (!err && cam->sensor) +- DBG(2, "%s image sensor detected", cam->sensor->name); ++ if (!err) ++ DBG(2, "%s image sensor detected", cam->sensor.name); + else { + DBG(1, "No supported image sensor detected"); + err = -ENODEV; +@@ -1950,6 +1962,7 @@ zc0301_usb_probe(struct usb_interface* i + DBG(2, "V4L2 device registered as /dev/video%d", cam->v4ldev->minor); + + cam->module_param.force_munmap = force_munmap[dev_nr]; ++ cam->module_param.frame_timeout = frame_timeout[dev_nr]; + + dev_nr = (dev_nr < ZC0301_MAX_DEVICES-1) ? dev_nr+1 : 0; + +@@ -1994,6 +2007,7 @@ static void zc0301_usb_disconnect(struct + cam->state |= DEV_DISCONNECTED; + wake_up_interruptible(&cam->wait_frame); + wake_up(&cam->wait_stream); ++ usb_get_dev(cam->usbdev); + } else { + cam->state |= DEV_DISCONNECTED; + zc0301_release_resources(cam); +--- gregkh-2.6.orig/drivers/usb/media/zc0301.h ++++ gregkh-2.6/drivers/usb/media/zc0301.h +@@ -34,7 +34,8 @@ + #include <linux/param.h> + #include <linux/mutex.h> + #include <linux/rwsem.h> +-#include <asm/semaphore.h> ++#include <linux/stddef.h> ++#include <linux/string.h> + + #include "zc0301_sensor.h" + +@@ -51,7 +52,7 @@ + #define ZC0301_ALTERNATE_SETTING 7 + #define ZC0301_URB_TIMEOUT msecs_to_jiffies(2 * ZC0301_ISO_PACKETS) + #define ZC0301_CTRL_TIMEOUT 100 +-#define ZC0301_FRAME_TIMEOUT 2 * 1000 * msecs_to_jiffies(1) ++#define ZC0301_FRAME_TIMEOUT 2 + + /*****************************************************************************/ + +@@ -94,6 +95,7 @@ enum zc0301_stream_state { + + struct zc0301_module_param { + u8 force_munmap; ++ u16 frame_timeout; + }; + + static DECLARE_RWSEM(zc0301_disconnect); +@@ -101,7 +103,7 @@ static DECLARE_RWSEM(zc0301_disconnect); + struct zc0301_device { + struct video_device* v4ldev; + +- struct zc0301_sensor* sensor; ++ struct zc0301_sensor sensor; + + struct usb_device* usbdev; + struct urb* urb[ZC0301_URBS]; +@@ -129,11 +131,19 @@ struct zc0301_device { + + /*****************************************************************************/ + ++struct zc0301_device* ++zc0301_match_id(struct zc0301_device* cam, const struct usb_device_id *id) ++{ ++ if (usb_match_id(usb_ifnum_to_if(cam->usbdev, 0), id)) ++ return cam; ++ ++ return NULL; ++} ++ + void + zc0301_attach_sensor(struct zc0301_device* cam, struct zc0301_sensor* sensor) + { +- cam->sensor = sensor; +- cam->sensor->usbdev = cam->usbdev; ++ memcpy(&cam->sensor, sensor, sizeof(struct zc0301_sensor)); + } + + /*****************************************************************************/ +--- gregkh-2.6.orig/drivers/usb/media/zc0301_pas202bcb.c ++++ gregkh-2.6/drivers/usb/media/zc0301_pas202bcb.c +@@ -22,6 +22,14 @@ + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * + ***************************************************************************/ + ++/* ++ NOTE: Sensor controls are disabled for now, becouse changing them while ++ streaming sometimes results in out-of-sync video frames. We'll use ++ the default initialization, until we know how to stop and start video ++ in the chip. However, the image quality still looks good under various ++ light conditions. ++*/ ++ + #include <linux/delay.h> + #include "zc0301_sensor.h" + +@@ -245,7 +253,7 @@ static struct zc0301_sensor pas202bcb = + .maximum = 0x3fff, + .step = 0x0001, + .default_value = 0x01e5, +- .flags = 0, ++ .flags = V4L2_CTRL_FLAG_DISABLED, + }, + { + .id = V4L2_CID_GAIN, +@@ -255,7 +263,17 @@ static struct zc0301_sensor pas202bcb = + .maximum = 0x1f, + .step = 0x01, + .default_value = 0x0c, +- .flags = 0, ++ .flags = V4L2_CTRL_FLAG_DISABLED, ++ }, ++ { ++ .id = ZC0301_V4L2_CID_DAC_MAGNITUDE, ++ .type = V4L2_CTRL_TYPE_INTEGER, ++ .name = "DAC magnitude", ++ .minimum = 0x00, ++ .maximum = 0xff, ++ .step = 0x01, ++ .default_value = 0x00, ++ .flags = V4L2_CTRL_FLAG_DISABLED, + }, + { + .id = V4L2_CID_RED_BALANCE, +@@ -265,7 +283,7 @@ static struct zc0301_sensor pas202bcb = + .maximum = 0x0f, + .step = 0x01, + .default_value = 0x01, +- .flags = 0, ++ .flags = V4L2_CTRL_FLAG_DISABLED, + }, + { + .id = V4L2_CID_BLUE_BALANCE, +@@ -275,7 +293,7 @@ static struct zc0301_sensor pas202bcb = + .maximum = 0x0f, + .step = 0x01, + .default_value = 0x05, +- .flags = 0, ++ .flags = V4L2_CTRL_FLAG_DISABLED, + }, + { + .id = ZC0301_V4L2_CID_GREEN_BALANCE, +@@ -285,17 +303,7 @@ static struct zc0301_sensor pas202bcb = + .maximum = 0x0f, + .step = 0x01, + .default_value = 0x00, +- .flags = 0, +- }, +- { +- .id = ZC0301_V4L2_CID_DAC_MAGNITUDE, +- .type = V4L2_CTRL_TYPE_INTEGER, +- .name = "DAC magnitude", +- .minimum = 0x00, +- .maximum = 0xff, +- .step = 0x01, +- .default_value = 0x04, +- .flags = 0, ++ .flags = V4L2_CTRL_FLAG_DISABLED, + }, + }, + .get_ctrl = &pas202bcb_get_ctrl, +--- gregkh-2.6.orig/drivers/usb/media/zc0301_sensor.h ++++ gregkh-2.6/drivers/usb/media/zc0301_sensor.h +@@ -43,9 +43,11 @@ static int (*zc0301_sensor_table[])(stru + NULL, \ + }; + ++extern struct zc0301_device* ++zc0301_match_id(struct zc0301_device* cam, const struct usb_device_id *id); ++ + extern void +-zc0301_attach_sensor(struct zc0301_device* cam, +- struct zc0301_sensor* sensor); ++zc0301_attach_sensor(struct zc0301_device* cam, struct zc0301_sensor* sensor); + + #define ZC0301_USB_DEVICE(vend, prod, intclass) \ + .match_flags = USB_DEVICE_ID_MATCH_DEVICE | \ +@@ -56,7 +58,14 @@ zc0301_attach_sensor(struct zc0301_devic + + #define ZC0301_ID_TABLE \ + static const struct usb_device_id zc0301_id_table[] = { \ ++ { ZC0301_USB_DEVICE(0x10fd, 0x8050, 0xff), }, /* TAS5130D */ \ ++ { ZC0301_USB_DEVICE(0x041e, 0x0417, 0xff), }, \ ++ { ZC0301_USB_DEVICE(0x041e, 0x041e, 0xff), }, /* HV7131B */ \ ++ { ZC0301_USB_DEVICE(0x041e, 0x081c, 0xff), }, /* PAS106 */ \ ++ { ZC0301_USB_DEVICE(0x041e, 0x0834, 0xff), }, /* PAS106 */ \ ++ { ZC0301_USB_DEVICE(0x041e, 0x0835, 0xff), }, /* PAS106 */ \ + { ZC0301_USB_DEVICE(0x046d, 0x08ae, 0xff), }, /* PAS202BCB */ \ ++ { ZC0301_USB_DEVICE(0x0ac8, 0x0301, 0xff), }, \ + { } \ + }; + +@@ -80,15 +89,11 @@ struct zc0301_sensor { + struct v4l2_cropcap cropcap; + struct v4l2_pix_format pix_format; + +- int (*init)(struct zc0301_device* cam); +- int (*get_ctrl)(struct zc0301_device* cam, +- struct v4l2_control* ctrl); +- int (*set_ctrl)(struct zc0301_device* cam, ++ int (*init)(struct zc0301_device*); ++ int (*get_ctrl)(struct zc0301_device*, struct v4l2_control* ctrl); ++ int (*set_ctrl)(struct zc0301_device*, + const struct v4l2_control* ctrl); +- int (*set_crop)(struct zc0301_device* cam, +- const struct v4l2_rect* rect); +- +- const struct usb_device* usbdev; ++ int (*set_crop)(struct zc0301_device*, const struct v4l2_rect* rect); + + /* Private */ + struct v4l2_queryctrl _qctrl[ZC0301_MAX_CTRLS]; |