aboutsummaryrefslogtreecommitdiffstats
path: root/usb
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@suse.de>2006-03-22 15:36:23 -0800
committerGreg Kroah-Hartman <gregkh@suse.de>2006-03-22 15:36:23 -0800
commitb171e4fc69b3d2ef67d2f02597c818315ecc4b88 (patch)
treedf9ea6631c8dd70d8af25c8421dcbae3d6f7df67 /usb
parente82bcd05071353092ac327e3e9b4014cd393b26f (diff)
downloadpatches-b171e4fc69b3d2ef67d2f02597c818315ecc4b88.tar.gz
remove usb patches that went into mainline (2.6.16-git3)
Diffstat (limited to 'usb')
-rw-r--r--usb/cypress_m8-add-support-for-the-nokia-ca42-version-2-cable.patch182
-rw-r--r--usb/navman-usb-serial.patch202
-rw-r--r--usb/omninet_debug.patch55
-rw-r--r--usb/recognize-three-more-usb-peripheral-controllers.patch106
-rw-r--r--usb/ub-use-kzalloc.patch63
-rw-r--r--usb/uhci-don-t-log-short-transfers.patch37
-rw-r--r--usb/uhci-hcd-fix-mistaken-usage-of-list_prepare_entry.patch29
-rw-r--r--usb/uhci-improve-debugging-code.patch285
-rw-r--r--usb/uhci-remove-main-list-of-urbs.patch927
-rw-r--r--usb/uhci-use-dummy-tds.patch320
-rw-r--r--usb/uhci-use-one-qh-per-endpoint-not-per-urb.patch2397
-rw-r--r--usb/usb-add-support-for-at91-gadget.patch2022
-rw-r--r--usb/usb-add-support-for-creativelabs-silvercrest-usb-keyboard.patch34
-rw-r--r--usb/usb-add-support-for-ochi-on-at91rm9200.patch378
-rw-r--r--usb/usb-add-zc0301-video4linux2-driver.patch3023
-rw-r--r--usb/usb-convert-a-bunch-of-usb-semaphores-to-mutexes.patch3199
-rw-r--r--usb/usb-core-and-hcds-don-t-put_device-while-atomic.patch160
-rw-r--r--usb/usb-cp2101-add-new-device-ids.patch37
-rw-r--r--usb/usb-credits-add-credits-about-the-zc0301-and-et61x51-usb-drivers.patch29
-rw-r--r--usb/usb-drivers-usb-core-message.c-make-usb_get_string-static.patch52
-rw-r--r--usb/usb-ehci-and-freescale-83xx-quirk.patch94
-rw-r--r--usb/usb-ehci-and-nf2-quirk.patch120
-rw-r--r--usb/usb-ehci-for-au1200.patch425
-rw-r--r--usb/usb-ehci-for-freescale-83xx.patch503
-rw-r--r--usb/usb-ehci-full-speed-iso-bugfixes.patch68
-rw-r--r--usb/usb-ehci-unlink-tweaks.patch44
-rw-r--r--usb/usb-et61x51-driver-updates.patch1211
-rw-r--r--usb/usb-ethernet-gadget-driver-section-fixups.patch145
-rw-r--r--usb/usb-fix-check_ctrlrecip-to-allow-control-transfers-in-state-address.patch41
-rw-r--r--usb/usb-fix-irda-usb-use-after-use.patch47
-rw-r--r--usb/usb-fix-masking-bug-initialization-of-freescale-ehci-controller.patch32
-rw-r--r--usb/usb-fix-warning-in-drivers-usb-media-ov511.c.patch33
-rw-r--r--usb/usb-ftdi_sio-add-icom-id1-usb-product-and-vendor-ids.patch50
-rw-r--r--usb/usb-gadget-driver-section-fixups.patch147
-rw-r--r--usb/usb-initdata-fixes.patch24
-rw-r--r--usb/usb-kzalloc-conversion-for-rest-of-drivers-usb.patch690
-rw-r--r--usb/usb-kzalloc-conversion-in-drivers-usb-gadget.patch186
-rw-r--r--usb/usb-kzalloc-for-hid.patch150
-rw-r--r--usb/usb-kzalloc-for-storage.patch112
-rw-r--r--usb/usb-kzalloc-in-cytherm.patch34
-rw-r--r--usb/usb-kzalloc-in-dabusb.patch34
-rw-r--r--usb/usb-kzalloc-in-idmouse.patch32
-rw-r--r--usb/usb-kzalloc-in-ldusb.patch34
-rw-r--r--usb/usb-kzalloc-in-phidgetinterfacekit.patch68
-rw-r--r--usb/usb-kzalloc-in-phidgetservo.patch33
-rw-r--r--usb/usb-kzalloc-in-sisusbvga.patch44
-rw-r--r--usb/usb-kzalloc-in-usbled.patch33
-rw-r--r--usb/usb-kzalloc-in-usbvideo.patch35
-rw-r--r--usb/usb-kzalloc-in-w9968cf.patch73
-rw-r--r--usb/usb-mdc800.c-to-kzalloc.patch35
-rw-r--r--usb/usb-minor-gadget-rndis-tweak.patch30
-rw-r--r--usb/usb-ohci-for-au1200.patch241
-rw-r--r--usb/usb-ohci-uses-driver-model-wakeup-flags.patch228
-rw-r--r--usb/usb-optimise-devio.c-usbdev_read-fix.patch43
-rw-r--r--usb/usb-optimise-devio.c-usbdev_read.patch56
-rw-r--r--usb/usb-pegasus-linksys-usbvpn1-support-cleanup.patch104
-rw-r--r--usb/usb-pl2303-and-tiocmiwait.patch39
-rw-r--r--usb/usb-remove-linux_version_code-macro-usage.patch82
-rw-r--r--usb/usb-remove-obsolete_oss_usb_driver-drivers.patch6407
-rw-r--r--usb/usb-remove-usbcore-specific-wakeup-flags.patch181
-rw-r--r--usb/usb-rtl8150-small-fix.patch37
-rw-r--r--usb/usb-sn9c10x-driver-updates.patch1073
-rw-r--r--usb/usb-storage-another-unusual_devs.h-entry.patch35
-rw-r--r--usb/usb-storage-new-unusual_devs.h-entry-mitsumi-7in1-card-reader.patch37
-rw-r--r--usb/usb-storage-sandisk-unusual_devices-entry.patch45
-rw-r--r--usb/usb-storage-unusual_devs.h-entry-0420-0001.patch34
-rw-r--r--usb/usb-support-for-usb-to-serial-cable-from-speed-dragon-multimedia.patch42
-rw-r--r--usb/usb-ub-01-remove-first_open.patch71
-rw-r--r--usb/usb-ub-02-remove-diag.patch395
-rw-r--r--usb/usb-ub-03-drop-stall-clearing.patch45
-rw-r--r--usb/usb-uhci-increase-port-reset-completion-delay-for-hp-controllers.patch59
-rw-r--r--usb/usb-usbcore-don-t-assume-a-usb-configuration-includes-any-interfaces.patch66
-rw-r--r--usb/usb-usbcore-sets-up-root-hubs-earlier.patch198
-rw-r--r--usb/usb-usbcore-usb_set_configuration-oops.patch43
-rw-r--r--usb/usb-vicam.c-fix-a-null-pointer-dereference.patch29
-rw-r--r--usb/usb-zc0301-driver-bugfix.patch111
-rw-r--r--usb/usb-zc0301-driver-updates-2.patch496
-rw-r--r--usb/usb-zc0301-driver-updates.patch214
-rw-r--r--usb/usb-zero-driver-removed-duplicated-code.patch30
-rw-r--r--usb/usbcore-fix-compile-error-with-config_usb_suspend-n.patch29
-rw-r--r--usb/usbhid-add-error-handling.patch298
81 files changed, 0 insertions, 28912 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
deleted file mode 100644
index a7910af76c86f..0000000000000
--- a/usb/cypress_m8-add-support-for-the-nokia-ca42-version-2-cable.patch
+++ /dev/null
@@ -1,182 +0,0 @@
-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/navman-usb-serial.patch b/usb/navman-usb-serial.patch
deleted file mode 100644
index 95cdafd762909..0000000000000
--- a/usb/navman-usb-serial.patch
+++ /dev/null
@@ -1,202 +0,0 @@
-From foo@baz Tue Apr 9 12:12:43 2002
-Date: Fri, 17 Mar 2006 17:40:08 -0800 (PST)
-From: Greg Kroah-Hartman <gregkh@suse.de>
-Subject: USB serial: add navman driver
-
-Thanks to Warren Lewis <wlewis@scn.org> for the information needed to
-write the driver and for testing it out.
-
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-
----
- drivers/usb/serial/Kconfig | 7 +
- drivers/usb/serial/Makefile | 1
- drivers/usb/serial/navman.c | 157 ++++++++++++++++++++++++++++++++++++++++++++
- 3 files changed, 165 insertions(+)
-
---- usb-2.6.orig/drivers/usb/serial/Kconfig
-+++ usb-2.6/drivers/usb/serial/Kconfig
-@@ -403,6 +403,13 @@ config USB_SERIAL_MCT_U232
- To compile this driver as a module, choose M here: the
- module will be called mct_u232.
-
-+config USB_SERIAL_NAVMAN
-+ tristate "USB Navman GPS device"
-+ depends on USB_SERIAL
-+ help
-+ To compile this driver as a module, choose M here: the
-+ module will be called navman.
-+
- config USB_SERIAL_PL2303
- tristate "USB Prolific 2303 Single Port Serial Driver"
- depends on USB_SERIAL
---- usb-2.6.orig/drivers/usb/serial/Makefile
-+++ usb-2.6/drivers/usb/serial/Makefile
-@@ -32,6 +32,7 @@ obj-$(CONFIG_USB_SERIAL_KEYSPAN_PDA) +=
- obj-$(CONFIG_USB_SERIAL_KLSI) += kl5kusb105.o
- obj-$(CONFIG_USB_SERIAL_KOBIL_SCT) += kobil_sct.o
- obj-$(CONFIG_USB_SERIAL_MCT_U232) += mct_u232.o
-+obj-$(CONFIG_USB_SERIAL_NAVMAN) += navman.o
- obj-$(CONFIG_USB_SERIAL_OMNINET) += omninet.o
- obj-$(CONFIG_USB_SERIAL_OPTION) += option.o
- obj-$(CONFIG_USB_SERIAL_PL2303) += pl2303.o
---- /dev/null
-+++ usb-2.6/drivers/usb/serial/navman.c
-@@ -0,0 +1,157 @@
-+/*
-+ * Navman Serial USB driver
-+ *
-+ * Copyright (C) 2006 Greg Kroah-Hartman <gregkh@suse.de>
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License
-+ * version 2 as published by the Free Software Foundation.
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/tty.h>
-+#include <linux/tty_flip.h>
-+#include <linux/module.h>
-+#include <linux/usb.h>
-+#include "usb-serial.h"
-+
-+static int debug;
-+
-+static struct usb_device_id id_table [] = {
-+ { USB_DEVICE(0x0a99, 0x0001) }, /* Talon Technology device */
-+ { },
-+};
-+MODULE_DEVICE_TABLE(usb, id_table);
-+
-+static struct usb_driver navman_driver = {
-+ .name = "navman",
-+ .probe = usb_serial_probe,
-+ .disconnect = usb_serial_disconnect,
-+ .id_table = id_table,
-+ .no_dynamic_id = 1,
-+};
-+
-+static void navman_read_int_callback(struct urb *urb, struct pt_regs *regs)
-+{
-+ struct usb_serial_port *port = urb->context;
-+ unsigned char *data = urb->transfer_buffer;
-+ struct tty_struct *tty;
-+ int result;
-+
-+ switch (urb->status) {
-+ case 0:
-+ /* success */
-+ break;
-+ case -ECONNRESET:
-+ case -ENOENT:
-+ case -ESHUTDOWN:
-+ /* this urb is terminated, clean up */
-+ dbg("%s - urb shutting down with status: %d",
-+ __FUNCTION__, urb->status);
-+ return;
-+ default:
-+ dbg("%s - nonzero urb status received: %d",
-+ __FUNCTION__, urb->status);
-+ goto exit;
-+ }
-+
-+ usb_serial_debug_data(debug, &port->dev, __FUNCTION__,
-+ urb->actual_length, data);
-+
-+ tty = port->tty;
-+ if (tty && urb->actual_length) {
-+ tty_buffer_request_room(tty, urb->actual_length);
-+ tty_insert_flip_string(tty, data, urb->actual_length);
-+ tty_flip_buffer_push(tty);
-+ }
-+
-+exit:
-+ result = usb_submit_urb(urb, GFP_ATOMIC);
-+ if (result)
-+ dev_err(&urb->dev->dev,
-+ "%s - Error %d submitting interrupt urb\n",
-+ __FUNCTION__, result);
-+}
-+
-+static int navman_open(struct usb_serial_port *port, struct file *filp)
-+{
-+ int result = 0;
-+
-+ dbg("%s - port %d", __FUNCTION__, port->number);
-+
-+ if (port->interrupt_in_urb) {
-+ dbg("%s - adding interrupt input for treo", __FUNCTION__);
-+ result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
-+ if (result)
-+ dev_err(&port->dev,
-+ "%s - failed submitting interrupt urb, error %d\n",
-+ __FUNCTION__, result);
-+ }
-+ return result;
-+}
-+
-+static void navman_close(struct usb_serial_port *port, struct file *filp)
-+{
-+ dbg("%s - port %d", __FUNCTION__, port->number);
-+
-+ if (port->interrupt_in_urb)
-+ usb_kill_urb(port->interrupt_in_urb);
-+}
-+
-+static int navman_write(struct usb_serial_port *port,
-+ const unsigned char *buf, int count)
-+{
-+ dbg("%s - port %d", __FUNCTION__, port->number);
-+
-+ /*
-+ * This device can't write any data, only read from the device
-+ * so we just silently eat all data sent to us and say it was
-+ * successfully sent.
-+ * Evil, I know, but do you have a better idea?
-+ */
-+
-+ return count;
-+}
-+
-+static struct usb_serial_driver navman_device = {
-+ .driver = {
-+ .owner = THIS_MODULE,
-+ .name = "navman",
-+ },
-+ .id_table = id_table,
-+ .num_interrupt_in = NUM_DONT_CARE,
-+ .num_bulk_in = NUM_DONT_CARE,
-+ .num_bulk_out = NUM_DONT_CARE,
-+ .num_ports = 1,
-+ .open = navman_open,
-+ .close = navman_close,
-+ .write = navman_write,
-+ .read_int_callback = navman_read_int_callback,
-+};
-+
-+static int __init navman_init(void)
-+{
-+ int retval;
-+
-+ retval = usb_serial_register(&navman_device);
-+ if (retval)
-+ return retval;
-+ retval = usb_register(&navman_driver);
-+ if (retval)
-+ usb_serial_deregister(&navman_device);
-+ return retval;
-+}
-+
-+static void __exit navman_exit(void)
-+{
-+ usb_deregister(&navman_driver);
-+ usb_serial_deregister(&navman_device);
-+}
-+
-+module_init(navman_init);
-+module_exit(navman_exit);
-+MODULE_LICENSE("GPL");
-+
-+module_param(debug, bool, S_IRUGO | S_IWUSR);
-+MODULE_PARM_DESC(debug, "Debug enabled or not");
diff --git a/usb/omninet_debug.patch b/usb/omninet_debug.patch
deleted file mode 100644
index 6264231528f44..0000000000000
--- a/usb/omninet_debug.patch
+++ /dev/null
@@ -1,55 +0,0 @@
-From foo@baz Tue Apr 9 12:12:43 2002
-Date: Mon, 20 Mar 2006 17:28:39 -0500
-From: Greg Kroah-Hartman <gregkh@suse.de>
-Subject: USB: omninet: fix up debugging comments
-
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-
----
---- gregkh-2.6.orig/drivers/usb/serial/omninet.c
-+++ gregkh-2.6/drivers/usb/serial/omninet.c
-@@ -204,7 +204,7 @@ static void omninet_read_bulk_callback (
- int i;
- int result;
-
--// dbg("omninet_read_bulk_callback");
-+ dbg("%s - port %d", __FUNCTION__, port->number);
-
- if (urb->status) {
- dbg("%s - nonzero read bulk status received: %d", __FUNCTION__, urb->status);
-@@ -250,7 +250,7 @@ static int omninet_write (struct usb_ser
-
- int result;
-
--// dbg("omninet_write port %d", port->number);
-+ dbg("%s - port %d", __FUNCTION__, port->number);
-
- if (count == 0) {
- dbg("%s - write request of 0 bytes", __FUNCTION__);
-@@ -302,7 +302,7 @@ static int omninet_write_room (struct us
- if (wport->write_urb_busy)
- room = wport->bulk_out_size - OMNINET_HEADERLEN;
-
--// dbg("omninet_write_room returns %d", room);
-+ dbg("%s - returns %d", __FUNCTION__, room);
-
- return (room);
- }
-@@ -312,7 +312,7 @@ static void omninet_write_bulk_callback
- /* struct omninet_header *header = (struct omninet_header *) urb->transfer_buffer; */
- struct usb_serial_port *port = (struct usb_serial_port *) urb->context;
-
--// dbg("omninet_write_bulk_callback, port %0x\n", port);
-+ dbg("%s - port %0x\n", __FUNCTION__, port->number);
-
- port->write_urb_busy = 0;
- if (urb->status) {
-@@ -321,8 +321,6 @@ static void omninet_write_bulk_callback
- }
-
- schedule_work(&port->work);
--
--// dbg("omninet_write_bulk_callback, tty %0x\n", tty);
- }
-
-
diff --git a/usb/recognize-three-more-usb-peripheral-controllers.patch b/usb/recognize-three-more-usb-peripheral-controllers.patch
deleted file mode 100644
index 9878029d095e6..0000000000000
--- a/usb/recognize-three-more-usb-peripheral-controllers.patch
+++ /dev/null
@@ -1,106 +0,0 @@
-From david-b@pacbell.net Wed Jan 25 08:57:17 2006
-From: David Brownell <david-b@pacbell.net>
-To: Greg KH <greg@kroah.com>
-Subject: [patch 2.6.16-rc1] recognize three more usb peripheral controllers
-Date: Wed, 25 Jan 2006 08:45:59 -0800
-Cc: "Kamat, Nishant" <nskamat@ti.com>, Kevin Hilman <khilman@mvista.com>, Tony Lindgren <tony@atomide.com>
-Message-Id: <200601250845.59331.david-b@pacbell.net>
-
-This adds declarations for three USB peripheral controllers:
-
- - Two high speed USB cores that can be licensed from Mentor Graphics
- to be integrated into silicon:
-
- * "musbhsfc" is for peripherals only, as found in for example the
- IBM/AMCC 44EP processors.
-
- * "musbhdrc" is OTG-capable (dual role), and is found in various
- products including OMAP 2430 and the new DaVinci SOCs.
-
- The "musbh" standing for "Mentor USB Highspeed", the rest standing
- for "Function Controller" or "Dual Role Controller" (OTG-capable).
-
- - The full speed controller on the FreeScale MPC8272.
-
-Adding these definitions just allows gadget driver code to handle any
-controller-specific logic; controller drivers are quite separate.
-
-
-Signed-off-by: David Brownell <david-b@pacbell.net>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-
----
- drivers/usb/gadget/ether.c | 8 ++++++++
- drivers/usb/gadget/gadget_chips.h | 30 ++++++++++++++++++++++++++++--
- 2 files changed, 36 insertions(+), 2 deletions(-)
-
---- gregkh-2.6.orig/drivers/usb/gadget/ether.c
-+++ gregkh-2.6/drivers/usb/gadget/ether.c
-@@ -253,6 +253,14 @@ MODULE_PARM_DESC(host_addr, "Host Ethern
- #define DEV_CONFIG_CDC
- #endif
-
-+#ifdef CONFIG_USB_GADGET_MUSBHSFC
-+#define DEV_CONFIG_CDC
-+#endif
-+
-+#ifdef CONFIG_USB_GADGET_MUSBHDRC
-+#define DEV_CONFIG_CDC
-+#endif
-+
-
- /* For CDC-incapable hardware, choose the simple cdc subset.
- * Anything that talks bulk (without notable bugs) can do this.
---- gregkh-2.6.orig/drivers/usb/gadget/gadget_chips.h
-+++ gregkh-2.6/drivers/usb/gadget/gadget_chips.h
-@@ -3,9 +3,9 @@
- * gadget drivers or other code that needs to deal with them, and which
- * autoconfigures instead of using early binding to the hardware.
- *
-- * This could eventually work like the ARM mach_is_*() stuff, driven by
-+ * This SHOULD eventually work like the ARM mach_is_*() stuff, driven by
- * some config file that gets updated as new hardware is supported.
-- * (And avoiding the runtime comparisons in typical one-choice cases.)
-+ * (And avoiding all runtime comparisons in typical one-choice configs!)
- *
- * NOTE: some of these controller drivers may not be available yet.
- */
-@@ -93,6 +93,26 @@
- #define gadget_is_imx(g) 0
- #endif
-
-+/* Mentor high speed function controller */
-+#ifdef CONFIG_USB_GADGET_MUSBHSFC
-+#define gadget_is_musbhsfc(g) !strcmp("musbhsfc_udc", (g)->name)
-+#else
-+#define gadget_is_musbhsfc(g) 0
-+#endif
-+
-+/* Mentor high speed "dual role" controller, peripheral mode */
-+#ifdef CONFIG_USB_GADGET_MUSBHDRC
-+#define gadget_is_musbhdrc(g) !strcmp("musbhdrc_udc", (g)->name)
-+#else
-+#define gadget_is_musbhdrc(g) 0
-+#endif
-+
-+#ifdef CONFIG_USB_GADGET_MPC8272
-+#define gadget_is_mpc8272(g) !strcmp("mpc8272_udc", (g)->name)
-+#else
-+#define gadget_is_mpc8272(g) 0
-+#endif
-+
- // CONFIG_USB_GADGET_SX2
- // CONFIG_USB_GADGET_AU1X00
- // ...
-@@ -143,5 +163,11 @@ static inline int usb_gadget_controller_
- return 0x13;
- else if (gadget_is_imx(gadget))
- return 0x14;
-+ else if (gadget_is_musbhsfc(gadget))
-+ return 0x15;
-+ else if (gadget_is_musbhdrc(gadget))
-+ return 0x16;
-+ else if (gadget_is_mpc8272(gadget))
-+ return 0x17;
- return -ENOENT;
- }
diff --git a/usb/ub-use-kzalloc.patch b/usb/ub-use-kzalloc.patch
deleted file mode 100644
index 52091cbb74b54..0000000000000
--- a/usb/ub-use-kzalloc.patch
+++ /dev/null
@@ -1,63 +0,0 @@
-From zaitcev@redhat.com Mon Feb 13 20:36:09 2006
-Date: Mon, 13 Feb 2006 20:35:57 -0800
-From: Pete Zaitcev <zaitcev@redhat.com>
-To: Greg KH <greg@kroah.com>
-Cc: zaitcev@redhat.com
-Subject: ub: use kzalloc
-Message-Id: <20060213203557.4892cf5a.zaitcev@redhat.com>
-
-Switch from kmalloc+memset to kzalloc.
-
-Signed-off-by: Pete Zaitcev <zaitcev@redhat.com>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-
----
- drivers/block/ub.c | 12 ++++--------
- 1 file changed, 4 insertions(+), 8 deletions(-)
-
---- gregkh-2.6.orig/drivers/block/ub.c
-+++ gregkh-2.6/drivers/block/ub.c
-@@ -2007,9 +2007,8 @@ static int ub_sync_tur(struct ub_dev *sc
- init_completion(&compl);
-
- rc = -ENOMEM;
-- if ((cmd = kmalloc(ALLOC_SIZE, GFP_KERNEL)) == NULL)
-+ if ((cmd = kzalloc(ALLOC_SIZE, GFP_KERNEL)) == NULL)
- goto err_alloc;
-- memset(cmd, 0, ALLOC_SIZE);
-
- cmd->cdb[0] = TEST_UNIT_READY;
- cmd->cdb_len = 6;
-@@ -2062,9 +2061,8 @@ static int ub_sync_read_cap(struct ub_de
- init_completion(&compl);
-
- rc = -ENOMEM;
-- if ((cmd = kmalloc(ALLOC_SIZE, GFP_KERNEL)) == NULL)
-+ if ((cmd = kzalloc(ALLOC_SIZE, GFP_KERNEL)) == NULL)
- goto err_alloc;
-- memset(cmd, 0, ALLOC_SIZE);
- p = (char *)cmd + sizeof(struct ub_scsi_cmd);
-
- cmd->cdb[0] = 0x25;
-@@ -2405,9 +2403,8 @@ static int ub_probe(struct usb_interface
- return -ENXIO;
-
- rc = -ENOMEM;
-- if ((sc = kmalloc(sizeof(struct ub_dev), GFP_KERNEL)) == NULL)
-+ if ((sc = kzalloc(sizeof(struct ub_dev), GFP_KERNEL)) == NULL)
- goto err_core;
-- memset(sc, 0, sizeof(struct ub_dev));
- sc->lock = ub_next_lock();
- INIT_LIST_HEAD(&sc->luns);
- usb_init_urb(&sc->work_urb);
-@@ -2524,9 +2521,8 @@ static int ub_probe_lun(struct ub_dev *s
- int rc;
-
- rc = -ENOMEM;
-- if ((lun = kmalloc(sizeof(struct ub_lun), GFP_KERNEL)) == NULL)
-+ if ((lun = kzalloc(sizeof(struct ub_lun), GFP_KERNEL)) == NULL)
- goto err_alloc;
-- memset(lun, 0, sizeof(struct ub_lun));
- lun->num = lnum;
-
- rc = -ENOSR;
diff --git a/usb/uhci-don-t-log-short-transfers.patch b/usb/uhci-don-t-log-short-transfers.patch
deleted file mode 100644
index 1b0ed73980c59..0000000000000
--- a/usb/uhci-don-t-log-short-transfers.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From stern@rowland.harvard.edu Tue Dec 20 07:01:47 2005
-Date: Tue, 20 Dec 2005 09:58:08 -0500 (EST)
-From: Alan Stern <stern@rowland.harvard.edu>
-To: Greg KH <greg@kroah.com>
-Subject: [PATCH] UHCI: Don't log short transfers
-Message-ID: <Pine.LNX.4.44L0.0512200953140.5250-100000@iolanthe.rowland.org>
-
-Even when the URB_SHORT_NOT_OK flag is set, a short transfer shouldn't
-generate a debugging log message. Especially not one with the confusing
-claim that the transfer "failed with status 0". This patch (as627)
-fixes that behavior in uhci-hcd.
-
-Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-
----
- drivers/usb/host/uhci-q.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- gregkh-2.6.orig/drivers/usb/host/uhci-q.c
-+++ gregkh-2.6/drivers/usb/host/uhci-q.c
-@@ -922,7 +922,6 @@ static int uhci_result_common(struct uhc
- td_error:
- ret = uhci_map_status(status, uhci_packetout(td_token(td)));
-
--err:
- if ((debug == 1 && ret != -EPIPE) || debug > 1) {
- /* Some debugging code */
- dev_dbg(uhci_dev(uhci), "%s: failed with status %x\n",
-@@ -934,6 +933,7 @@ err:
- lprintk(errbuf);
- }
- }
-+err:
-
- /* Note that the queue has stopped and save the next toggle value */
- urbp->qh->element = UHCI_PTR_TERM;
diff --git a/usb/uhci-hcd-fix-mistaken-usage-of-list_prepare_entry.patch b/usb/uhci-hcd-fix-mistaken-usage-of-list_prepare_entry.patch
deleted file mode 100644
index e387d350f101e..0000000000000
--- a/usb/uhci-hcd-fix-mistaken-usage-of-list_prepare_entry.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From stern@rowland.harvard.edu Tue Jan 31 07:03:01 2006
-Date: Tue, 31 Jan 2006 10:02:55 -0500 (EST)
-From: Alan Stern <stern@rowland.harvard.edu>
-To: Greg KH <greg@kroah.com>, Andrew Morton <akpm@osdl.org>
-cc: Arnaud Patard <arnaud.patard@rtp-net.org>
-Subject: [PATCH] uhci-hcd: fix mistaken usage of list_prepare_entry
-Message-ID: <Pine.LNX.4.44L0.0601310958570.5380-100000@iolanthe.rowland.org>
-
-A recent update to the uhci-hcd driver invoked the list_prepare_entry
-macro incorrectly. This patch (as646) corrects it.
-
-Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-
----
- drivers/usb/host/uhci-q.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- gregkh-2.6.orig/drivers/usb/host/uhci-q.c
-+++ gregkh-2.6/drivers/usb/host/uhci-q.c
-@@ -259,7 +259,7 @@ static void uhci_fixup_toggles(struct uh
- /* Fix up the toggle for the URBs in the queue. Normally this
- * loop won't run more than once: When an error or short transfer
- * occurs, the queue usually gets emptied. */
-- list_prepare_entry(urbp, &qh->queue, node);
-+ urbp = list_prepare_entry(urbp, &qh->queue, node);
- list_for_each_entry_continue(urbp, &qh->queue, node) {
-
- /* If the first TD has the right toggle value, we don't
diff --git a/usb/uhci-improve-debugging-code.patch b/usb/uhci-improve-debugging-code.patch
deleted file mode 100644
index 77ede9e35bcb8..0000000000000
--- a/usb/uhci-improve-debugging-code.patch
+++ /dev/null
@@ -1,285 +0,0 @@
-From stern@rowland.harvard.edu Sat Dec 17 15:14:04 2005
-Date: Sat, 17 Dec 2005 18:03:37 -0500 (EST)
-From: Alan Stern <stern@rowland.harvard.edu>
-To: Greg KH <greg@kroah.com>
-Subject: [PATCH 4/4] UHCI: improve debugging code
-Message-ID: <Pine.LNX.4.44L0.0512171732300.14730-100000@netrider.rowland.org>
-
-This patch (as626) makes some improvements to the debugging code in
-uhci-hcd. The main change is that now the code won't get compiled if
-CONFIG_USB_DEBUG isn't set. But there are other changes too, like
-adding a missing .owner field and printing a debugging dump if the
-controller dies.
-
-Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-
----
- drivers/usb/host/uhci-debug.c | 36 ++++++++++++++++++++-----
- drivers/usb/host/uhci-hcd.c | 60 +++++++++++++++++++++++++++---------------
- drivers/usb/host/uhci-hcd.h | 1
- drivers/usb/host/uhci-q.c | 12 --------
- 4 files changed, 70 insertions(+), 39 deletions(-)
-
---- gregkh-2.6.orig/drivers/usb/host/uhci-debug.c
-+++ gregkh-2.6/drivers/usb/host/uhci-debug.c
-@@ -17,10 +17,13 @@
-
- #include "uhci-hcd.h"
-
--static struct dentry *uhci_debugfs_root = NULL;
-+#define uhci_debug_operations (* (struct file_operations *) NULL)
-+static struct dentry *uhci_debugfs_root;
-+
-+#ifdef DEBUG
-
- /* Handle REALLY large printks so we don't overflow buffers */
--static inline void lprintk(char *buf)
-+static void lprintk(char *buf)
- {
- char *p;
-
-@@ -196,7 +199,6 @@ static int uhci_show_qh(struct uhci_qh *
- return out - buf;
- }
-
--#ifdef CONFIG_PROC_FS
- static const char * const qh_names[] = {
- "skel_unlink_qh", "skel_iso_qh",
- "skel_int128_qh", "skel_int64_qh",
-@@ -393,12 +395,13 @@ static int uhci_sprint_schedule(struct u
- return out - buf;
- }
-
-+#ifdef CONFIG_DEBUG_FS
-+
- #define MAX_OUTPUT (64 * 1024)
-
- struct uhci_debug {
- int size;
- char *data;
-- struct uhci_hcd *uhci;
- };
-
- static int uhci_debug_open(struct inode *inode, struct file *file)
-@@ -419,8 +422,10 @@ static int uhci_debug_open(struct inode
- goto out;
- }
-
-+ up->size = 0;
- spin_lock_irqsave(&uhci->lock, flags);
-- up->size = uhci_sprint_schedule(uhci, up->data, MAX_OUTPUT);
-+ if (uhci->is_initialized)
-+ up->size = uhci_sprint_schedule(uhci, up->data, MAX_OUTPUT);
- spin_unlock_irqrestore(&uhci->lock, flags);
-
- file->private_data = up;
-@@ -472,15 +477,32 @@ static int uhci_debug_release(struct ino
- return 0;
- }
-
-+#undef uhci_debug_operations
- static struct file_operations uhci_debug_operations = {
-+ .owner = THIS_MODULE,
- .open = uhci_debug_open,
- .llseek = uhci_debug_lseek,
- .read = uhci_debug_read,
- .release = uhci_debug_release,
- };
-
--#else /* CONFIG_DEBUG_FS */
-+#endif /* CONFIG_DEBUG_FS */
-
--#define uhci_debug_operations (* (struct file_operations *) NULL)
-+#else /* DEBUG */
-+
-+static inline void lprintk(char *buf)
-+{}
-+
-+static inline int uhci_show_qh(struct uhci_qh *qh, char *buf,
-+ int len, int space)
-+{
-+ return 0;
-+}
-+
-+static inline int uhci_sprint_schedule(struct uhci_hcd *uhci,
-+ char *buf, int len)
-+{
-+ return 0;
-+}
-
- #endif
---- gregkh-2.6.orig/drivers/usb/host/uhci-hcd.c
-+++ gregkh-2.6/drivers/usb/host/uhci-hcd.c
-@@ -68,12 +68,16 @@ Alan Stern"
- * debug = 3, show all TDs in URBs when dumping
- */
- #ifdef DEBUG
-+#define DEBUG_CONFIGURED 1
- static int debug = 1;
--#else
--static int debug = 0;
--#endif
- module_param(debug, int, S_IRUGO | S_IWUSR);
- MODULE_PARM_DESC(debug, "Debug level");
-+
-+#else
-+#define DEBUG_CONFIGURED 0
-+#define debug 0
-+#endif
-+
- static char *errbuf;
- #define ERRBUF_LEN (32 * 1024)
-
-@@ -338,6 +342,12 @@ static irqreturn_t uhci_irq(struct usb_h
- dev_err(uhci_dev(uhci),
- "host controller halted, "
- "very bad!\n");
-+ if (debug > 1 && errbuf) {
-+ /* Print the schedule for debugging */
-+ uhci_sprint_schedule(uhci,
-+ errbuf, ERRBUF_LEN);
-+ lprintk(errbuf);
-+ }
- hc_died(uhci);
-
- /* Force a callback in case there are
-@@ -376,6 +386,14 @@ static void release_uhci(struct uhci_hcd
- {
- int i;
-
-+ if (DEBUG_CONFIGURED) {
-+ spin_lock_irq(&uhci->lock);
-+ uhci->is_initialized = 0;
-+ spin_unlock_irq(&uhci->lock);
-+
-+ debugfs_remove(uhci->dentry);
-+ }
-+
- for (i = 0; i < UHCI_NUM_SKELQH; i++)
- uhci_free_qh(uhci, uhci->skelqh[i]);
-
-@@ -390,8 +408,6 @@ static void release_uhci(struct uhci_hcd
- dma_free_coherent(uhci_dev(uhci),
- UHCI_NUMFRAMES * sizeof(*uhci->frame),
- uhci->frame, uhci->frame_dma_handle);
--
-- debugfs_remove(uhci->dentry);
- }
-
- static int uhci_reset(struct usb_hcd *hcd)
-@@ -474,17 +490,6 @@ static int uhci_start(struct usb_hcd *hc
-
- hcd->uses_new_polling = 1;
-
-- dentry = debugfs_create_file(hcd->self.bus_name,
-- S_IFREG|S_IRUGO|S_IWUSR, uhci_debugfs_root, uhci,
-- &uhci_debug_operations);
-- if (!dentry) {
-- dev_err(uhci_dev(uhci),
-- "couldn't create uhci debugfs entry\n");
-- retval = -ENOMEM;
-- goto err_create_debug_entry;
-- }
-- uhci->dentry = dentry;
--
- uhci->fsbr = 0;
- uhci->fsbrtimeout = 0;
-
-@@ -495,6 +500,19 @@ static int uhci_start(struct usb_hcd *hc
-
- init_waitqueue_head(&uhci->waitqh);
-
-+ if (DEBUG_CONFIGURED) {
-+ dentry = debugfs_create_file(hcd->self.bus_name,
-+ S_IFREG|S_IRUGO|S_IWUSR, uhci_debugfs_root,
-+ uhci, &uhci_debug_operations);
-+ if (!dentry) {
-+ dev_err(uhci_dev(uhci), "couldn't create uhci "
-+ "debugfs entry\n");
-+ retval = -ENOMEM;
-+ goto err_create_debug_entry;
-+ }
-+ uhci->dentry = dentry;
-+ }
-+
- uhci->frame = dma_alloc_coherent(uhci_dev(uhci),
- UHCI_NUMFRAMES * sizeof(*uhci->frame),
- &uhci->frame_dma_handle, 0);
-@@ -609,6 +627,7 @@ static int uhci_start(struct usb_hcd *hc
- mb();
-
- configure_hc(uhci);
-+ uhci->is_initialized = 1;
- start_rh(uhci);
- return 0;
-
-@@ -872,16 +891,15 @@ static int __init uhci_hcd_init(void)
- if (usb_disabled())
- return -ENODEV;
-
-- if (debug) {
-+ if (DEBUG_CONFIGURED) {
- errbuf = kmalloc(ERRBUF_LEN, GFP_KERNEL);
- if (!errbuf)
- goto errbuf_failed;
-+ uhci_debugfs_root = debugfs_create_dir("uhci", NULL);
-+ if (!uhci_debugfs_root)
-+ goto debug_failed;
- }
-
-- uhci_debugfs_root = debugfs_create_dir("uhci", NULL);
-- if (!uhci_debugfs_root)
-- goto debug_failed;
--
- uhci_up_cachep = kmem_cache_create("uhci_urb_priv",
- sizeof(struct urb_priv), 0, 0, NULL, NULL);
- if (!uhci_up_cachep)
---- gregkh-2.6.orig/drivers/usb/host/uhci-hcd.h
-+++ gregkh-2.6/drivers/usb/host/uhci-hcd.h
-@@ -411,6 +411,7 @@ struct uhci_hcd {
- unsigned int hc_inaccessible:1; /* HC is suspended or dead */
- unsigned int working_RD:1; /* Suspended root hub doesn't
- need to be polled */
-+ unsigned int is_initialized:1; /* Data structure is usable */
-
- /* Support for port suspend/resume/reset */
- unsigned long port_c_suspend; /* Bit-arrays of ports */
---- gregkh-2.6.orig/drivers/usb/host/uhci-q.c
-+++ gregkh-2.6/drivers/usb/host/uhci-q.c
-@@ -736,7 +736,6 @@ err:
- if (errbuf) {
- /* Print the chain for debugging purposes */
- uhci_show_qh(urbp->qh, errbuf, ERRBUF_LEN, 0);
--
- lprintk(errbuf);
- }
- }
-@@ -924,26 +923,17 @@ td_error:
- ret = uhci_map_status(status, uhci_packetout(td_token(td)));
-
- err:
-- /*
-- * Enable this chunk of code if you want to see some more debugging.
-- * But be careful, it has the tendancy to starve out khubd and prevent
-- * disconnects from happening successfully if you have a slow debug
-- * log interface (like a serial console.
-- */
--#if 0
- if ((debug == 1 && ret != -EPIPE) || debug > 1) {
- /* Some debugging code */
- dev_dbg(uhci_dev(uhci), "%s: failed with status %x\n",
- __FUNCTION__, status);
-
-- if (errbuf) {
-+ if (debug > 1 && errbuf) {
- /* Print the chain for debugging purposes */
- uhci_show_qh(urbp->qh, errbuf, ERRBUF_LEN, 0);
--
- lprintk(errbuf);
- }
- }
--#endif
-
- /* Note that the queue has stopped and save the next toggle value */
- urbp->qh->element = UHCI_PTR_TERM;
diff --git a/usb/uhci-remove-main-list-of-urbs.patch b/usb/uhci-remove-main-list-of-urbs.patch
deleted file mode 100644
index 576b0b0cd447e..0000000000000
--- a/usb/uhci-remove-main-list-of-urbs.patch
+++ /dev/null
@@ -1,927 +0,0 @@
-From stern@rowland.harvard.edu Sat Dec 17 15:13:57 2005
-Date: Sat, 17 Dec 2005 18:02:38 -0500 (EST)
-From: Alan Stern <stern@rowland.harvard.edu>
-To: Greg KH <greg@kroah.com>
-Subject: [PATCH 3/4] UHCI: remove main list of URBs
-Message-ID: <Pine.LNX.4.44L0.0512171728000.14730-100000@netrider.rowland.org>
-
-As part of reorienting uhci-hcd away from URBs and toward endpoint
-queues, this patch (as625) eliminates the driver's main list of URBs.
-The list wsa used mainly in checking for URB completions; now the driver
-goes through the list of active endpoints and checks the members of the
-queues.
-
-As a side effect, I had to remove the code that looks for FSBR timeouts.
-For now, FSBR will remain on so long as any URBs on a full-speed control
-or bulk queue request it, even if the queue isn't advancing. A later
-patch can add more intelligent handling. This isn't a huge drawback;
-it's pretty rare for an URB to get stuck for more than a fraction of a
-second. (And it will help the people trying to use those insane HP USB
-devices.)
-
-
-Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-
----
- drivers/usb/host/uhci-debug.c | 1
- drivers/usb/host/uhci-hcd.c | 2
- drivers/usb/host/uhci-hcd.h | 15
- drivers/usb/host/uhci-q.c | 633 ++++++++++++++++++------------------------
- 4 files changed, 280 insertions(+), 371 deletions(-)
-
---- gregkh-2.6.orig/drivers/usb/host/uhci-debug.c
-+++ gregkh-2.6/drivers/usb/host/uhci-debug.c
-@@ -114,7 +114,6 @@ static int uhci_show_urbp(struct urb_pri
- }
-
- out += sprintf(out, "%s", (urbp->fsbr ? " FSBR" : ""));
-- out += sprintf(out, "%s", (urbp->fsbr_timeout ? " FSBR_TO" : ""));
-
- if (urbp->urb->status != -EINPROGRESS)
- out += sprintf(out, " Status=%d", urbp->urb->status);
---- gregkh-2.6.orig/drivers/usb/host/uhci-hcd.c
-+++ gregkh-2.6/drivers/usb/host/uhci-hcd.c
-@@ -491,8 +491,6 @@ static int uhci_start(struct usb_hcd *hc
- spin_lock_init(&uhci->lock);
-
- INIT_LIST_HEAD(&uhci->td_remove_list);
-- INIT_LIST_HEAD(&uhci->urb_list);
-- INIT_LIST_HEAD(&uhci->complete_list);
- INIT_LIST_HEAD(&uhci->idle_qh_list);
-
- init_waitqueue_head(&uhci->waitqh);
---- gregkh-2.6.orig/drivers/usb/host/uhci-hcd.h
-+++ gregkh-2.6/drivers/usb/host/uhci-hcd.h
-@@ -132,6 +132,10 @@ struct uhci_qh {
-
- unsigned int unlink_frame; /* When the QH was unlinked */
- int state; /* QH_STATE_xxx; see above */
-+
-+ unsigned int initial_toggle:1; /* Endpoint's current toggle value */
-+ unsigned int needs_fixup:1; /* Must fix the TD toggle values */
-+ unsigned int is_stopped:1; /* Queue was stopped by an error */
- } __attribute__((aligned(16)));
-
- /*
-@@ -384,6 +388,7 @@ struct uhci_hcd {
-
- struct uhci_td *term_td; /* Terminating TD, see UHCI bug */
- struct uhci_qh *skelqh[UHCI_NUM_SKELQH]; /* Skeleton QHs */
-+ struct uhci_qh *next_qh; /* Next QH to scan */
-
- spinlock_t lock;
-
-@@ -413,16 +418,10 @@ struct uhci_hcd {
- unsigned long resuming_ports;
- unsigned long ports_timeout; /* Time to stop signalling */
-
-- /* Main list of URBs currently controlled by this HC */
-- struct list_head urb_list;
--
- /* List of TDs that are done, but waiting to be freed (race) */
- struct list_head td_remove_list;
- unsigned int td_remove_age; /* Age in frames */
-
-- /* List of URBs awaiting completion callback */
-- struct list_head complete_list;
--
- struct list_head idle_qh_list; /* Where the idle QHs live */
-
- int rh_numports; /* Number of root-hub ports */
-@@ -448,7 +447,6 @@ static inline struct usb_hcd *uhci_to_hc
- * Private per-URB data
- */
- struct urb_priv {
-- struct list_head urb_list;
- struct list_head node; /* Node in the QH's urbp list */
-
- struct urb *urb;
-@@ -456,10 +454,7 @@ struct urb_priv {
- struct uhci_qh *qh; /* QH for this URB */
- struct list_head td_list;
-
-- unsigned long fsbrtime; /* In jiffies */
--
- unsigned fsbr : 1; /* URB turned on FSBR */
-- unsigned fsbr_timeout : 1; /* URB timed out on FSBR */
- unsigned short_transfer : 1; /* URB got a short transfer, no
- * need to rescan */
- };
---- gregkh-2.6.orig/drivers/usb/host/uhci-q.c
-+++ gregkh-2.6/drivers/usb/host/uhci-q.c
-@@ -151,53 +151,6 @@ static void uhci_unlink_isochronous_tds(
- wmb();
- }
-
--/*
-- * Remove an URB's TDs from the hardware schedule
-- */
--static void uhci_remove_tds_from_schedule(struct uhci_hcd *uhci,
-- struct urb *urb, int status)
--{
-- struct urb_priv *urbp = (struct urb_priv *) urb->hcpriv;
--
-- /* Isochronous TDs get unlinked directly from the frame list */
-- if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
-- uhci_unlink_isochronous_tds(uhci, urb);
-- return;
-- }
--
-- /* If the URB isn't first on its queue, adjust the link pointer
-- * of the last TD in the previous URB. */
-- if (urbp->node.prev != &urbp->qh->queue) {
-- struct urb_priv *purbp;
-- struct uhci_td *ptd, *ltd;
--
-- if (status == -EINPROGRESS)
-- status = 0;
-- purbp = list_entry(urbp->node.prev, struct urb_priv, node);
-- ptd = list_entry(purbp->td_list.prev, struct uhci_td,
-- list);
-- ltd = list_entry(urbp->td_list.prev, struct uhci_td,
-- list);
-- ptd->link = ltd->link;
-- }
--
-- /* If the URB completed with an error, then the QH element certainly
-- * points to one of the URB's TDs. If it completed normally then
-- * the QH element has certainly moved on to the next URB. And if
-- * the URB is still in progress then it must have been dequeued.
-- * The QH element either hasn't reached it yet or is somewhere in
-- * the middle. If the URB wasn't first we can assume that it
-- * hasn't started yet (see above): Otherwise all the preceding URBs
-- * would have completed and been removed from the queue, so this one
-- * _would_ be first.
-- *
-- * If the QH element is inside this URB, clear it. It will be
-- * set properly when the QH is activated.
-- */
-- if (status < 0)
-- urbp->qh->element = UHCI_PTR_TERM;
--}
--
- static struct uhci_qh *uhci_alloc_qh(struct uhci_hcd *uhci,
- struct usb_device *udev, struct usb_host_endpoint *hep)
- {
-@@ -251,6 +204,90 @@ static void uhci_free_qh(struct uhci_hcd
- }
-
- /*
-+ * When the currently executing URB is dequeued, save its current toggle value
-+ */
-+static void uhci_save_toggle(struct uhci_qh *qh, struct urb *urb)
-+{
-+ struct urb_priv *urbp = (struct urb_priv *) urb->hcpriv;
-+ struct uhci_td *td;
-+
-+ /* If the QH element pointer is UHCI_PTR_TERM then then currently
-+ * executing URB has already been unlinked, so this one isn't it. */
-+ if (qh_element(qh) == UHCI_PTR_TERM ||
-+ qh->queue.next != &urbp->node)
-+ return;
-+ qh->element = UHCI_PTR_TERM;
-+
-+ /* Only bulk and interrupt pipes have to worry about toggles */
-+ if (!(usb_pipetype(urb->pipe) == PIPE_BULK ||
-+ usb_pipetype(urb->pipe) == PIPE_INTERRUPT))
-+ return;
-+
-+ /* Find the first active TD; that's the device's toggle state */
-+ list_for_each_entry(td, &urbp->td_list, list) {
-+ if (td_status(td) & TD_CTRL_ACTIVE) {
-+ qh->needs_fixup = 1;
-+ qh->initial_toggle = uhci_toggle(td_token(td));
-+ return;
-+ }
-+ }
-+
-+ WARN_ON(1);
-+}
-+
-+/*
-+ * Fix up the data toggles for URBs in a queue, when one of them
-+ * terminates early (short transfer, error, or dequeued).
-+ */
-+static void uhci_fixup_toggles(struct uhci_qh *qh, int skip_first)
-+{
-+ struct urb_priv *urbp = NULL;
-+ struct uhci_td *td;
-+ unsigned int toggle = qh->initial_toggle;
-+ unsigned int pipe;
-+
-+ /* Fixups for a short transfer start with the second URB in the
-+ * queue (the short URB is the first). */
-+ if (skip_first)
-+ urbp = list_entry(qh->queue.next, struct urb_priv, node);
-+
-+ /* When starting with the first URB, if the QH element pointer is
-+ * still valid then we know the URB's toggles are okay. */
-+ else if (qh_element(qh) != UHCI_PTR_TERM)
-+ toggle = 2;
-+
-+ /* Fix up the toggle for the URBs in the queue. Normally this
-+ * loop won't run more than once: When an error or short transfer
-+ * occurs, the queue usually gets emptied. */
-+ list_prepare_entry(urbp, &qh->queue, node);
-+ list_for_each_entry_continue(urbp, &qh->queue, node) {
-+
-+ /* If the first TD has the right toggle value, we don't
-+ * need to change any toggles in this URB */
-+ td = list_entry(urbp->td_list.next, struct uhci_td, list);
-+ if (toggle > 1 || uhci_toggle(td_token(td)) == toggle) {
-+ td = list_entry(urbp->td_list.next, struct uhci_td,
-+ list);
-+ toggle = uhci_toggle(td_token(td)) ^ 1;
-+
-+ /* Otherwise all the toggles in the URB have to be switched */
-+ } else {
-+ list_for_each_entry(td, &urbp->td_list, list) {
-+ td->token ^= __constant_cpu_to_le32(
-+ TD_TOKEN_TOGGLE);
-+ toggle ^= 1;
-+ }
-+ }
-+ }
-+
-+ wmb();
-+ pipe = list_entry(qh->queue.next, struct urb_priv, node)->urb->pipe;
-+ usb_settoggle(qh->udev, usb_pipeendpoint(pipe),
-+ usb_pipeout(pipe), toggle);
-+ qh->needs_fixup = 0;
-+}
-+
-+/*
- * Put a QH on the schedule in both hardware and software
- */
- static void uhci_activate_qh(struct uhci_hcd *uhci, struct uhci_qh *qh)
-@@ -276,6 +313,9 @@ static void uhci_activate_qh(struct uhci
-
- /* Move the QH from its old list to the end of the appropriate
- * skeleton's list */
-+ if (qh == uhci->next_qh)
-+ uhci->next_qh = list_entry(qh->node.next, struct uhci_qh,
-+ node);
- list_move_tail(&qh->node, &qh->skel->node);
-
- /* Link it into the schedule */
-@@ -310,6 +350,9 @@ static void uhci_unlink_qh(struct uhci_h
- uhci_set_next_interrupt(uhci);
-
- /* Move the QH from its old list to the end of the unlinking list */
-+ if (qh == uhci->next_qh)
-+ uhci->next_qh = list_entry(qh->node.next, struct uhci_qh,
-+ node);
- list_move_tail(&qh->node, &uhci->skel_unlink_qh->node);
- }
-
-@@ -323,6 +366,9 @@ static void uhci_make_qh_idle(struct uhc
- {
- WARN_ON(qh->state == QH_STATE_ACTIVE);
-
-+ if (qh == uhci->next_qh)
-+ uhci->next_qh = list_entry(qh->node.next, struct uhci_qh,
-+ node);
- list_move(&qh->node, &uhci->idle_qh_list);
- qh->state = QH_STATE_IDLE;
-
-@@ -344,11 +390,9 @@ static inline struct urb_priv *uhci_allo
-
- urbp->urb = urb;
- urb->hcpriv = urbp;
-- urbp->fsbrtime = jiffies;
-
- INIT_LIST_HEAD(&urbp->node);
- INIT_LIST_HEAD(&urbp->td_list);
-- INIT_LIST_HEAD(&urbp->urb_list);
-
- return urbp;
- }
-@@ -373,9 +417,6 @@ static void uhci_free_urb_priv(struct uh
- {
- struct uhci_td *td, *tmp;
-
-- if (!list_empty(&urbp->urb_list))
-- dev_warn(uhci_dev(uhci), "urb %p still on uhci->urb_list!\n",
-- urbp->urb);
- if (!list_empty(&urbp->node))
- dev_warn(uhci_dev(uhci), "urb %p still on QH's list!\n",
- urbp->urb);
-@@ -453,71 +494,6 @@ static int uhci_map_status(int status, i
- }
-
- /*
-- * Fix up the data toggles for URBs in a queue, when one of them
-- * terminates early (short transfer, error, or dequeued).
-- */
--static void uhci_fixup_toggles(struct urb *urb)
--{
-- struct list_head *head;
-- struct uhci_td *td;
-- struct urb_priv *urbp = (struct urb_priv *) urb->hcpriv;
-- int prevactive = 0;
-- unsigned int toggle = 0;
-- struct urb_priv *turbp, *list_end;
--
-- /*
-- * We need to find out what the last successful toggle was so
-- * we can update the data toggles for the following transfers.
-- *
-- * There are 2 ways the last successful completed TD is found:
-- *
-- * 1) The TD is NOT active and the actual length < expected length
-- * 2) The TD is NOT active and it's the last TD in the chain
-- *
-- * and a third way the first uncompleted TD is found:
-- *
-- * 3) The TD is active and the previous TD is NOT active
-- */
-- head = &urbp->td_list;
-- list_for_each_entry(td, head, list) {
-- unsigned int ctrlstat = td_status(td);
--
-- if (!(ctrlstat & TD_CTRL_ACTIVE) &&
-- (uhci_actual_length(ctrlstat) <
-- uhci_expected_length(td_token(td)) ||
-- td->list.next == head))
-- toggle = uhci_toggle(td_token(td)) ^ 1;
-- else if ((ctrlstat & TD_CTRL_ACTIVE) && !prevactive)
-- toggle = uhci_toggle(td_token(td));
--
-- prevactive = ctrlstat & TD_CTRL_ACTIVE;
-- }
--
-- /*
-- * Fix up the toggle for the following URBs in the queue.
-- *
-- * We can stop as soon as we find an URB with toggles set correctly,
-- * because then all the following URBs will be correct also.
-- */
-- list_end = list_entry(&urbp->qh->queue, struct urb_priv, node);
-- turbp = urbp;
-- while ((turbp = list_entry(turbp->node.next, struct urb_priv, node))
-- != list_end) {
-- td = list_entry(turbp->td_list.next, struct uhci_td, list);
-- if (uhci_toggle(td_token(td)) == toggle)
-- return;
--
-- list_for_each_entry(td, &turbp->td_list, list) {
-- td->token ^= __constant_cpu_to_le32(TD_TOKEN_TOGGLE);
-- toggle ^= 1;
-- }
-- }
--
-- usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe),
-- usb_pipeout(urb->pipe), toggle);
--}
--
--/*
- * Control transfers
- */
- static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb,
-@@ -765,6 +741,9 @@ err:
- }
- }
-
-+ /* Note that the queue has stopped */
-+ urbp->qh->element = UHCI_PTR_TERM;
-+ urbp->qh->is_stopped = 1;
- return ret;
- }
-
-@@ -927,7 +906,10 @@ static int uhci_result_common(struct uhc
- */
- if (!urbp->short_transfer) {
- urbp->short_transfer = 1;
-- uhci_fixup_toggles(urb);
-+ urbp->qh->initial_toggle =
-+ uhci_toggle(td_token(td)) ^ 1;
-+ uhci_fixup_toggles(urbp->qh, 1);
-+
- td = list_entry(urbp->td_list.prev,
- struct uhci_td, list);
- urbp->qh->element = td->link;
-@@ -962,6 +944,13 @@ err:
- }
- }
- #endif
-+
-+ /* Note that the queue has stopped and save the next toggle value */
-+ urbp->qh->element = UHCI_PTR_TERM;
-+ urbp->qh->is_stopped = 1;
-+ urbp->qh->needs_fixup = 1;
-+ urbp->qh->initial_toggle = uhci_toggle(td_token(td)) ^
-+ (ret == -EREMOTEIO);
- return ret;
- }
-
-@@ -995,76 +984,39 @@ static inline int uhci_submit_interrupt(
- /*
- * Isochronous transfers
- */
--static int isochronous_find_limits(struct uhci_hcd *uhci, struct urb *urb, unsigned int *start, unsigned int *end)
--{
-- struct urb *last_urb = NULL;
-- struct urb_priv *up;
-- int ret = 0;
--
-- list_for_each_entry(up, &uhci->urb_list, urb_list) {
-- struct urb *u = up->urb;
--
-- /* look for pending URBs with identical pipe handle */
-- if ((urb->pipe == u->pipe) && (urb->dev == u->dev) &&
-- (u->status == -EINPROGRESS) && (u != urb)) {
-- if (!last_urb)
-- *start = u->start_frame;
-- last_urb = u;
-- }
-- }
--
-- if (last_urb) {
-- *end = (last_urb->start_frame + last_urb->number_of_packets *
-- last_urb->interval) & (UHCI_NUMFRAMES-1);
-- ret = 0;
-- } else
-- ret = -1; /* no previous urb found */
--
-- return ret;
--}
--
--static int isochronous_find_start(struct uhci_hcd *uhci, struct urb *urb)
-+static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb,
-+ struct uhci_qh *qh)
- {
-- int limits;
-- unsigned int start = 0, end = 0;
-+ struct uhci_td *td = NULL; /* Since urb->number_of_packets > 0 */
-+ int i, frame;
-+ unsigned long destination, status;
-+ struct urb_priv *urbp = (struct urb_priv *) urb->hcpriv;
-
- if (urb->number_of_packets > 900) /* 900? Why? */
- return -EFBIG;
-
-- limits = isochronous_find_limits(uhci, urb, &start, &end);
-+ status = TD_CTRL_ACTIVE | TD_CTRL_IOS;
-+ destination = (urb->pipe & PIPE_DEVEP_MASK) | usb_packetid(urb->pipe);
-
-+ /* Figure out the starting frame number */
- if (urb->transfer_flags & URB_ISO_ASAP) {
-- if (limits) {
-+ if (list_empty(&qh->queue)) {
- uhci_get_current_frame_number(uhci);
-- urb->start_frame = (uhci->frame_number + 10)
-- & (UHCI_NUMFRAMES - 1);
-- } else
-- urb->start_frame = end;
-+ urb->start_frame = (uhci->frame_number + 10);
-+
-+ } else { /* Go right after the last one */
-+ struct urb *last_urb;
-+
-+ last_urb = list_entry(qh->queue.prev,
-+ struct urb_priv, node)->urb;
-+ urb->start_frame = (last_urb->start_frame +
-+ last_urb->number_of_packets *
-+ last_urb->interval);
-+ }
- } else {
-- urb->start_frame &= (UHCI_NUMFRAMES - 1);
- /* FIXME: Sanity check */
- }
--
-- return 0;
--}
--
--/*
-- * Isochronous transfers
-- */
--static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb,
-- struct uhci_qh *qh)
--{
-- struct uhci_td *td = NULL; /* Since urb->number_of_packets > 0 */
-- int i, ret, frame;
-- unsigned long destination, status;
-- struct urb_priv *urbp = (struct urb_priv *) urb->hcpriv;
--
-- status = TD_CTRL_ACTIVE | TD_CTRL_IOS;
-- destination = (urb->pipe & PIPE_DEVEP_MASK) | usb_packetid(urb->pipe);
--
-- ret = isochronous_find_start(uhci, urb);
-- if (ret)
-- return ret;
-+ urb->start_frame &= (UHCI_NUMFRAMES - 1);
-
- for (i = 0; i < urb->number_of_packets; i++) {
- td = uhci_alloc_td(uhci);
-@@ -1203,7 +1155,6 @@ static int uhci_urb_enqueue(struct usb_h
- /* Add this URB to the QH */
- urbp->qh = qh;
- list_add_tail(&urbp->node, &qh->queue);
-- list_add_tail(&urbp->urb_list, &uhci->urb_list);
-
- /* If the new URB is the first and only one on this QH then either
- * the QH is new and idle or else it's unlinked and waiting to
-@@ -1224,49 +1175,66 @@ done:
- return ret;
- }
-
-+static int uhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb)
-+{
-+ struct uhci_hcd *uhci = hcd_to_uhci(hcd);
-+ unsigned long flags;
-+ struct urb_priv *urbp;
-+
-+ spin_lock_irqsave(&uhci->lock, flags);
-+ urbp = urb->hcpriv;
-+ if (!urbp) /* URB was never linked! */
-+ goto done;
-+
-+ /* Remove Isochronous TDs from the frame list ASAP */
-+ if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS)
-+ uhci_unlink_isochronous_tds(uhci, urb);
-+ uhci_unlink_qh(uhci, urbp->qh);
-+
-+done:
-+ spin_unlock_irqrestore(&uhci->lock, flags);
-+ return 0;
-+}
-+
- /*
-- * Return the result of a transfer
-+ * Finish unlinking an URB and give it back
- */
--static void uhci_transfer_result(struct uhci_hcd *uhci, struct urb *urb)
-+static void uhci_giveback_urb(struct uhci_hcd *uhci, struct uhci_qh *qh,
-+ struct urb *urb, struct pt_regs *regs)
-+__releases(uhci->lock)
-+__acquires(uhci->lock)
- {
-- int status;
-- int okay_to_giveback = 0;
- struct urb_priv *urbp = (struct urb_priv *) urb->hcpriv;
-
-- switch (usb_pipetype(urb->pipe)) {
-- case PIPE_CONTROL:
-- status = uhci_result_control(uhci, urb);
-- break;
-- case PIPE_ISOCHRONOUS:
-- status = uhci_result_isochronous(uhci, urb);
-- break;
-- default: /* PIPE_BULK or PIPE_INTERRUPT */
-- status = uhci_result_common(uhci, urb);
-- break;
-- }
-+ /* Isochronous TDs get unlinked directly from the frame list */
-+ if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS)
-+ uhci_unlink_isochronous_tds(uhci, urb);
-
-- spin_lock(&urb->lock);
-- if (urb->status == -EINPROGRESS) { /* Not yet dequeued */
-- if (status != -EINPROGRESS) { /* URB has completed */
-- urb->status = status;
-+ /* If the URB isn't first on its queue, adjust the link pointer
-+ * of the last TD in the previous URB. */
-+ else if (qh->queue.next != &urbp->node) {
-+ struct urb_priv *purbp;
-+ struct uhci_td *ptd, *ltd;
-
-- /* If the URB got a real error (as opposed to
-- * simply being dequeued), we don't have to
-- * unlink the QH. Fix this later... */
-- if (status < 0)
-- uhci_unlink_qh(uhci, urbp->qh);
-- else
-- okay_to_giveback = 1;
-- }
-- } else { /* Already dequeued */
-- if (urbp->qh->state == QH_STATE_UNLINKING &&
-- uhci->frame_number + uhci->is_stopped !=
-- urbp->qh->unlink_frame)
-- okay_to_giveback = 1;
-+ purbp = list_entry(urbp->node.prev, struct urb_priv, node);
-+ ptd = list_entry(purbp->td_list.prev, struct uhci_td,
-+ list);
-+ ltd = list_entry(urbp->td_list.prev, struct uhci_td,
-+ list);
-+ ptd->link = ltd->link;
- }
-- spin_unlock(&urb->lock);
-- if (!okay_to_giveback)
-- return;
-+
-+ /* Take the URB off the QH's queue. If the queue is now empty,
-+ * this is a perfect time for a toggle fixup. */
-+ list_del_init(&urbp->node);
-+ if (list_empty(&qh->queue) && qh->needs_fixup) {
-+ usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe),
-+ usb_pipeout(urb->pipe), qh->initial_toggle);
-+ qh->needs_fixup = 0;
-+ }
-+
-+ uhci_dec_fsbr(uhci, urb); /* Safe since it checks */
-+ uhci_free_urb_priv(uhci, urbp);
-
- switch (usb_pipetype(urb->pipe)) {
- case PIPE_ISOCHRONOUS:
-@@ -1277,122 +1245,107 @@ static void uhci_transfer_result(struct
- case PIPE_INTERRUPT:
- /* Release bandwidth for Interrupt or Isoc. transfers */
- /* Make sure we don't release if we have a queued URB */
-- if (list_empty(&urbp->qh->queue) && urb->bandwidth)
-+ if (list_empty(&qh->queue) && urb->bandwidth)
- usb_release_bandwidth(urb->dev, urb, 0);
- else
- /* bandwidth was passed on to queued URB, */
- /* so don't let usb_unlink_urb() release it */
- urb->bandwidth = 0;
-- /* Falls through */
-- case PIPE_BULK:
-- if (status < 0)
-- uhci_fixup_toggles(urb);
-- break;
-- default: /* PIPE_CONTROL */
- break;
- }
-
-- /* Take the URB's TDs off the hardware schedule */
-- uhci_remove_tds_from_schedule(uhci, urb, status);
--
-- /* Take the URB off the QH's queue and see if the QH is now unused */
-- list_del_init(&urbp->node);
-- if (list_empty(&urbp->qh->queue))
-- uhci_unlink_qh(uhci, urbp->qh);
-+ spin_unlock(&uhci->lock);
-+ usb_hcd_giveback_urb(uhci_to_hcd(uhci), urb, regs);
-+ spin_lock(&uhci->lock);
-
-- uhci_dec_fsbr(uhci, urb); /* Safe since it checks */
-+ /* If the queue is now empty, we can unlink the QH and give up its
-+ * reserved bandwidth. */
-+ if (list_empty(&qh->queue)) {
-+ uhci_unlink_qh(uhci, qh);
-
-- /* Queue it for giving back */
-- list_move_tail(&urbp->urb_list, &uhci->complete_list);
-+ /* Bandwidth stuff not yet implemented */
-+ }
- }
-
- /*
-- * Check out the QHs waiting to be fully unlinked
-+ * Scan the URBs in a QH's queue
- */
--static void uhci_scan_unlinking_qhs(struct uhci_hcd *uhci)
--{
-- struct uhci_qh *qh, *tmp;
-+#define QH_FINISHED_UNLINKING(qh) \
-+ (qh->state == QH_STATE_UNLINKING && \
-+ uhci->frame_number + uhci->is_stopped != qh->unlink_frame)
-
-- list_for_each_entry_safe(qh, tmp, &uhci->skel_unlink_qh->node, node) {
--
-- /* If the queue is empty and the QH is fully unlinked then
-- * it can become IDLE. */
-- if (list_empty(&qh->queue)) {
-- if (uhci->frame_number + uhci->is_stopped !=
-- qh->unlink_frame)
-- uhci_make_qh_idle(uhci, qh);
--
-- /* If none of the QH's URBs have been dequeued then the QH
-- * should be re-activated. */
-- } else {
-- struct urb_priv *urbp;
-- int any_dequeued = 0;
--
-- list_for_each_entry(urbp, &qh->queue, node) {
-- if (urbp->urb->status != -EINPROGRESS) {
-- any_dequeued = 1;
-- break;
-- }
-- }
-- if (!any_dequeued)
-- uhci_activate_qh(uhci, qh);
-- }
-- }
--}
--
--static int uhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb)
-+static void uhci_scan_qh(struct uhci_hcd *uhci, struct uhci_qh *qh,
-+ struct pt_regs *regs)
- {
-- struct uhci_hcd *uhci = hcd_to_uhci(hcd);
-- unsigned long flags;
- struct urb_priv *urbp;
-+ struct urb *urb;
-+ int status;
-
-- spin_lock_irqsave(&uhci->lock, flags);
-- urbp = urb->hcpriv;
-- if (!urbp) /* URB was never linked! */
-- goto done;
--
-- /* Remove Isochronous TDs from the frame list ASAP */
-- if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS)
-- uhci_unlink_isochronous_tds(uhci, urb);
-- uhci_unlink_qh(uhci, urbp->qh);
--
--done:
-- spin_unlock_irqrestore(&uhci->lock, flags);
-- return 0;
--}
-+ while (!list_empty(&qh->queue)) {
-+ urbp = list_entry(qh->queue.next, struct urb_priv, node);
-+ urb = urbp->urb;
-+
-+ switch (usb_pipetype(urb->pipe)) {
-+ case PIPE_CONTROL:
-+ status = uhci_result_control(uhci, urb);
-+ break;
-+ case PIPE_ISOCHRONOUS:
-+ status = uhci_result_isochronous(uhci, urb);
-+ break;
-+ default: /* PIPE_BULK or PIPE_INTERRUPT */
-+ status = uhci_result_common(uhci, urb);
-+ break;
-+ }
-+ if (status == -EINPROGRESS)
-+ break;
-
--static int uhci_fsbr_timeout(struct uhci_hcd *uhci, struct urb *urb)
--{
-- struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv;
-- struct list_head *head;
-- struct uhci_td *td;
-- int count = 0;
-+ spin_lock(&urb->lock);
-+ if (urb->status == -EINPROGRESS) /* Not dequeued */
-+ urb->status = status;
-+ else
-+ status = -ECONNRESET;
-+ spin_unlock(&urb->lock);
-
-- uhci_dec_fsbr(uhci, urb);
-+ /* Dequeued but completed URBs can't be given back unless
-+ * the QH is stopped or has finished unlinking. */
-+ if (status == -ECONNRESET &&
-+ !(qh->is_stopped || QH_FINISHED_UNLINKING(qh)))
-+ return;
-
-- urbp->fsbr_timeout = 1;
-+ uhci_giveback_urb(uhci, qh, urb, regs);
-+ if (qh->is_stopped)
-+ break;
-+ }
-
-- /*
-- * Ideally we would want to fix qh->element as well, but it's
-- * read/write by the HC, so that can introduce a race. It's not
-- * really worth the hassle
-- */
-+ /* If the QH is neither stopped nor finished unlinking (normal case),
-+ * our work here is done. */
-+ restart:
-+ if (!(qh->is_stopped || QH_FINISHED_UNLINKING(qh)))
-+ return;
-
-- head = &urbp->td_list;
-- list_for_each_entry(td, head, list) {
-- /*
-- * Make sure we don't do the last one (since it'll have the
-- * TERM bit set) as well as we skip every so many TDs to
-- * make sure it doesn't hog the bandwidth
-- */
-- if (td->list.next != head && (count % DEPTH_INTERVAL) ==
-- (DEPTH_INTERVAL - 1))
-- td->link |= UHCI_PTR_DEPTH;
-+ /* Otherwise give back each of the dequeued URBs */
-+ list_for_each_entry(urbp, &qh->queue, node) {
-+ urb = urbp->urb;
-+ if (urb->status != -EINPROGRESS) {
-+ uhci_save_toggle(qh, urb);
-+ uhci_giveback_urb(uhci, qh, urb, regs);
-+ goto restart;
-+ }
-+ }
-+ qh->is_stopped = 0;
-
-- count++;
-+ /* There are no more dequeued URBs. If there are still URBs on the
-+ * queue, the QH can now be re-activated. */
-+ if (!list_empty(&qh->queue)) {
-+ if (qh->needs_fixup)
-+ uhci_fixup_toggles(qh, 0);
-+ uhci_activate_qh(uhci, qh);
- }
-
-- return 0;
-+ /* The queue is empty. The QH can become idle if it is fully
-+ * unlinked. */
-+ else if (QH_FINISHED_UNLINKING(qh))
-+ uhci_make_qh_idle(uhci, qh);
- }
-
- static void uhci_free_pending_tds(struct uhci_hcd *uhci)
-@@ -1406,36 +1359,13 @@ static void uhci_free_pending_tds(struct
- }
- }
-
--static void
--uhci_finish_urb(struct usb_hcd *hcd, struct urb *urb, struct pt_regs *regs)
--__releases(uhci->lock)
--__acquires(uhci->lock)
--{
-- struct uhci_hcd *uhci = hcd_to_uhci(hcd);
--
-- uhci_free_urb_priv(uhci, (struct urb_priv *) (urb->hcpriv));
--
-- spin_unlock(&uhci->lock);
-- usb_hcd_giveback_urb(hcd, urb, regs);
-- spin_lock(&uhci->lock);
--}
--
--static void uhci_finish_completion(struct uhci_hcd *uhci, struct pt_regs *regs)
--{
-- struct urb_priv *urbp, *tmp;
--
-- list_for_each_entry_safe(urbp, tmp, &uhci->complete_list, urb_list) {
-- struct urb *urb = urbp->urb;
--
-- list_del_init(&urbp->urb_list);
-- uhci_finish_urb(uhci_to_hcd(uhci), urb, regs);
-- }
--}
--
--/* Process events in the schedule, but only in one thread at a time */
-+/*
-+ * Process events in the schedule, but only in one thread at a time
-+ */
- static void uhci_scan_schedule(struct uhci_hcd *uhci, struct pt_regs *regs)
- {
-- struct urb_priv *urbp, *tmp;
-+ int i;
-+ struct uhci_qh *qh;
-
- /* Don't allow re-entrant calls */
- if (uhci->scan_in_progress) {
-@@ -1452,26 +1382,24 @@ static void uhci_scan_schedule(struct uh
- if (uhci->frame_number + uhci->is_stopped != uhci->td_remove_age)
- uhci_free_pending_tds(uhci);
-
-- /* Walk the list of pending URBs to see which ones completed
-- * (must be _safe because uhci_transfer_result() dequeues URBs) */
-- list_for_each_entry_safe(urbp, tmp, &uhci->urb_list, urb_list) {
-- struct urb *urb = urbp->urb;
--
-- /* Checks the status and does all of the magic necessary */
-- uhci_transfer_result(uhci, urb);
-+ /* Go through all the QH queues and process the URBs in each one */
-+ for (i = 0; i < UHCI_NUM_SKELQH - 1; ++i) {
-+ uhci->next_qh = list_entry(uhci->skelqh[i]->node.next,
-+ struct uhci_qh, node);
-+ while ((qh = uhci->next_qh) != uhci->skelqh[i]) {
-+ uhci->next_qh = list_entry(qh->node.next,
-+ struct uhci_qh, node);
-+ uhci_scan_qh(uhci, qh, regs);
-+ }
- }
-- uhci_finish_completion(uhci, regs);
--
-- /* If the controller is stopped, we can finish these off right now */
-- if (uhci->is_stopped)
-- uhci_free_pending_tds(uhci);
-
- if (uhci->need_rescan)
- goto rescan;
- uhci->scan_in_progress = 0;
-
-- /* Check out the QHs waiting for unlinking */
-- uhci_scan_unlinking_qhs(uhci);
-+ /* If the controller is stopped, we can finish these off right now */
-+ if (uhci->is_stopped)
-+ uhci_free_pending_tds(uhci);
-
- if (list_empty(&uhci->td_remove_list) &&
- list_empty(&uhci->skel_unlink_qh->node))
-@@ -1482,19 +1410,8 @@ static void uhci_scan_schedule(struct uh
-
- static void check_fsbr(struct uhci_hcd *uhci)
- {
-- struct urb_priv *up;
--
-- list_for_each_entry(up, &uhci->urb_list, urb_list) {
-- struct urb *u = up->urb;
--
-- spin_lock(&u->lock);
--
-- /* Check if the FSBR timed out */
-- if (up->fsbr && !up->fsbr_timeout && time_after_eq(jiffies, up->fsbrtime + IDLE_TIMEOUT))
-- uhci_fsbr_timeout(uhci, u);
--
-- spin_unlock(&u->lock);
-- }
-+ /* For now, don't scan URBs for FSBR timeouts.
-+ * Add it back in later... */
-
- /* Really disable FSBR */
- if (!uhci->fsbr && uhci->fsbrtimeout && time_after_eq(jiffies, uhci->fsbrtimeout)) {
diff --git a/usb/uhci-use-dummy-tds.patch b/usb/uhci-use-dummy-tds.patch
deleted file mode 100644
index 16b02efed5462..0000000000000
--- a/usb/uhci-use-dummy-tds.patch
+++ /dev/null
@@ -1,320 +0,0 @@
-From stern@rowland.harvard.edu Sat Dec 17 15:13:52 2005
-Date: Sat, 17 Dec 2005 18:00:12 -0500 (EST)
-From: Alan Stern <stern@rowland.harvard.edu>
-To: Greg KH <greg@kroah.com>
-Subject: [PATCH 2/4] UHCI: use dummy TDs
-Message-ID: <Pine.LNX.4.44L0.0512171722380.14730-100000@netrider.rowland.org>
-
-This patch (as624) fixes a hardware race in uhci-hcd by adding a dummy
-TD to the end of each endpoint's queue. Without the dummy the host
-controller will effectively turn off the queue when it reaches the end,
-which happens asynchronously. This leads to a potential problem when
-new transfer descriptors are added to the end of the queue; they may
-never get used.
-
-With a dummy TD present the controller never turns off the queue;
-instead it just stops at the dummy and leaves the queue on but inactive.
-When new TDs are added to the end of the queue, the first new one gets
-written over the dummy. Thus there's never any question about whether
-the queue is running or needs to be restarted.
-
-Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-
----
- drivers/usb/host/uhci-debug.c | 5 +
- drivers/usb/host/uhci-hcd.h | 1
- drivers/usb/host/uhci-q.c | 138 +++++++++++++++++++++++-------------------
- 3 files changed, 83 insertions(+), 61 deletions(-)
-
---- gregkh-2.6.orig/drivers/usb/host/uhci-debug.c
-+++ gregkh-2.6/drivers/usb/host/uhci-debug.c
-@@ -189,6 +189,11 @@ static int uhci_show_qh(struct uhci_qh *
- space, "", nurbs);
- }
-
-+ if (qh->udev) {
-+ out += sprintf(out, "%*s Dummy TD\n", space, "");
-+ out += uhci_show_td(qh->dummy_td, out, len - (out - buf), 0);
-+ }
-+
- return out - buf;
- }
-
---- gregkh-2.6.orig/drivers/usb/host/uhci-hcd.h
-+++ gregkh-2.6/drivers/usb/host/uhci-hcd.h
-@@ -128,6 +128,7 @@ struct uhci_qh {
- struct usb_device *udev;
- struct list_head queue; /* Queue of urbps for this QH */
- struct uhci_qh *skel; /* Skeleton for this QH */
-+ struct uhci_td *dummy_td; /* Dummy TD to end the queue */
-
- unsigned int unlink_frame; /* When the QH was unlinked */
- int state; /* QH_STATE_xxx; see above */
---- gregkh-2.6.orig/drivers/usb/host/uhci-q.c
-+++ gregkh-2.6/drivers/usb/host/uhci-q.c
-@@ -48,10 +48,6 @@ static struct uhci_td *uhci_alloc_td(str
- return NULL;
-
- td->dma_handle = dma_handle;
--
-- td->link = UHCI_PTR_TERM;
-- td->buffer = 0;
--
- td->frame = -1;
-
- INIT_LIST_HEAD(&td->list);
-@@ -221,6 +217,11 @@ static struct uhci_qh *uhci_alloc_qh(str
- INIT_LIST_HEAD(&qh->node);
-
- if (udev) { /* Normal QH */
-+ qh->dummy_td = uhci_alloc_td(uhci);
-+ if (!qh->dummy_td) {
-+ dma_pool_free(uhci->qh_pool, qh, dma_handle);
-+ return NULL;
-+ }
- qh->state = QH_STATE_IDLE;
- qh->hep = hep;
- qh->udev = udev;
-@@ -244,6 +245,7 @@ static void uhci_free_qh(struct uhci_hcd
- if (qh->udev) {
- qh->hep->hcpriv = NULL;
- usb_put_dev(qh->udev);
-+ uhci_free_td(uhci, qh->dummy_td);
- }
- dma_pool_free(uhci->qh_pool, qh, qh->dma_handle);
- }
-@@ -531,22 +533,20 @@ static int uhci_submit_control(struct uh
- /* The "pipe" thing contains the destination in bits 8--18 */
- destination = (urb->pipe & PIPE_DEVEP_MASK) | USB_PID_SETUP;
-
-- /* 3 errors */
-- status = TD_CTRL_ACTIVE | uhci_maxerr(3);
-+ /* 3 errors, dummy TD remains inactive */
-+ status = uhci_maxerr(3);
- if (urb->dev->speed == USB_SPEED_LOW)
- status |= TD_CTRL_LS;
-
- /*
- * Build the TD for the control request setup packet
- */
-- td = uhci_alloc_td(uhci);
-- if (!td)
-- return -ENOMEM;
--
-+ td = qh->dummy_td;
- uhci_add_td_to_urb(urb, td);
- uhci_fill_td(td, status, destination | uhci_explen(8),
- urb->setup_dma);
- plink = &td->link;
-+ status |= TD_CTRL_ACTIVE;
-
- /*
- * If direction is "send", change the packet ID from SETUP (0x2D)
-@@ -568,7 +568,7 @@ static int uhci_submit_control(struct uh
-
- td = uhci_alloc_td(uhci);
- if (!td)
-- return -ENOMEM;
-+ goto nomem;
- *plink = cpu_to_le32(td->dma_handle);
-
- /* Alternate Data0/1 (start with Data1) */
-@@ -588,7 +588,7 @@ static int uhci_submit_control(struct uh
- */
- td = uhci_alloc_td(uhci);
- if (!td)
-- return -ENOMEM;
-+ goto nomem;
- *plink = cpu_to_le32(td->dma_handle);
-
- /*
-@@ -608,6 +608,20 @@ static int uhci_submit_control(struct uh
- uhci_add_td_to_urb(urb, td);
- uhci_fill_td(td, status | TD_CTRL_IOC,
- destination | uhci_explen(0), 0);
-+ plink = &td->link;
-+
-+ /*
-+ * Build the new dummy TD and activate the old one
-+ */
-+ td = uhci_alloc_td(uhci);
-+ if (!td)
-+ goto nomem;
-+ *plink = cpu_to_le32(td->dma_handle);
-+
-+ uhci_fill_td(td, 0, USB_PID_OUT | uhci_explen(0), 0);
-+ wmb();
-+ qh->dummy_td->status |= __constant_cpu_to_le32(TD_CTRL_ACTIVE);
-+ qh->dummy_td = td;
-
- /* Low-speed transfers get a different queue, and won't hog the bus.
- * Also, some devices enumerate better without FSBR; the easiest way
-@@ -620,8 +634,12 @@ static int uhci_submit_control(struct uh
- qh->skel = uhci->skel_fs_control_qh;
- uhci_inc_fsbr(uhci, urb);
- }
--
- return 0;
-+
-+nomem:
-+ /* Remove the dummy TD from the td_list so it doesn't get freed */
-+ uhci_remove_td_from_urb(qh->dummy_td);
-+ return -ENOMEM;
- }
-
- /*
-@@ -761,16 +779,19 @@ static int uhci_submit_common(struct uhc
- int maxsze = le16_to_cpu(qh->hep->desc.wMaxPacketSize);
- int len = urb->transfer_buffer_length;
- dma_addr_t data = urb->transfer_dma;
-- __le32 *plink, fake_link;
-+ __le32 *plink;
-+ unsigned int toggle;
-
- if (len < 0)
- return -EINVAL;
-
- /* The "pipe" thing contains the destination in bits 8--18 */
- destination = (urb->pipe & PIPE_DEVEP_MASK) | usb_packetid(urb->pipe);
-+ toggle = usb_gettoggle(urb->dev, usb_pipeendpoint(urb->pipe),
-+ usb_pipeout(urb->pipe));
-
-- /* 3 errors */
-- status = TD_CTRL_ACTIVE | uhci_maxerr(3);
-+ /* 3 errors, dummy TD remains inactive */
-+ status = uhci_maxerr(3);
- if (urb->dev->speed == USB_SPEED_LOW)
- status |= TD_CTRL_LS;
- if (usb_pipein(urb->pipe))
-@@ -779,7 +800,8 @@ static int uhci_submit_common(struct uhc
- /*
- * Build the DATA TDs
- */
-- plink = &fake_link;
-+ plink = NULL;
-+ td = qh->dummy_td;
- do { /* Allow zero length packets */
- int pktsze = maxsze;
-
-@@ -789,24 +811,23 @@ static int uhci_submit_common(struct uhc
- status &= ~TD_CTRL_SPD;
- }
-
-- td = uhci_alloc_td(uhci);
-- if (!td)
-- return -ENOMEM;
-- *plink = cpu_to_le32(td->dma_handle);
--
-+ if (plink) {
-+ td = uhci_alloc_td(uhci);
-+ if (!td)
-+ goto nomem;
-+ *plink = cpu_to_le32(td->dma_handle);
-+ }
- uhci_add_td_to_urb(urb, td);
- uhci_fill_td(td, status,
-- destination | uhci_explen(pktsze) |
-- (usb_gettoggle(urb->dev, usb_pipeendpoint(urb->pipe),
-- usb_pipeout(urb->pipe)) << TD_TOKEN_TOGGLE_SHIFT),
-- data);
-+ destination | uhci_explen(pktsze) |
-+ (toggle << TD_TOKEN_TOGGLE_SHIFT),
-+ data);
- plink = &td->link;
-+ status |= TD_CTRL_ACTIVE;
-
- data += pktsze;
- len -= maxsze;
--
-- usb_dotoggle(urb->dev, usb_pipeendpoint(urb->pipe),
-- usb_pipeout(urb->pipe));
-+ toggle ^= 1;
- } while (len > 0);
-
- /*
-@@ -821,17 +842,17 @@ static int uhci_submit_common(struct uhc
- urb->transfer_buffer_length > 0) {
- td = uhci_alloc_td(uhci);
- if (!td)
-- return -ENOMEM;
-+ goto nomem;
- *plink = cpu_to_le32(td->dma_handle);
-
- uhci_add_td_to_urb(urb, td);
-- uhci_fill_td(td, status, destination | uhci_explen(0) |
-- (usb_gettoggle(urb->dev, usb_pipeendpoint(urb->pipe),
-- usb_pipeout(urb->pipe)) << TD_TOKEN_TOGGLE_SHIFT),
-- data);
-+ uhci_fill_td(td, status,
-+ destination | uhci_explen(0) |
-+ (toggle << TD_TOKEN_TOGGLE_SHIFT),
-+ data);
-+ plink = &td->link;
-
-- usb_dotoggle(urb->dev, usb_pipeendpoint(urb->pipe),
-- usb_pipeout(urb->pipe));
-+ toggle ^= 1;
- }
-
- /* Set the interrupt-on-completion flag on the last packet.
-@@ -842,7 +863,27 @@ static int uhci_submit_common(struct uhc
- * flag setting. */
- td->status |= __constant_cpu_to_le32(TD_CTRL_IOC);
-
-+ /*
-+ * Build the new dummy TD and activate the old one
-+ */
-+ td = uhci_alloc_td(uhci);
-+ if (!td)
-+ goto nomem;
-+ *plink = cpu_to_le32(td->dma_handle);
-+
-+ uhci_fill_td(td, 0, USB_PID_OUT | uhci_explen(0), 0);
-+ wmb();
-+ qh->dummy_td->status |= __constant_cpu_to_le32(TD_CTRL_ACTIVE);
-+ qh->dummy_td = td;
-+
-+ usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe),
-+ usb_pipeout(urb->pipe), toggle);
- return 0;
-+
-+nomem:
-+ /* Remove the dummy TD from the td_list so it doesn't get freed */
-+ uhci_remove_td_from_urb(qh->dummy_td);
-+ return -ENOMEM;
- }
-
- /*
-@@ -1169,31 +1210,6 @@ static int uhci_urb_enqueue(struct usb_h
- * become idle, so we can activate it right away. */
- if (qh->queue.next == &urbp->node)
- uhci_activate_qh(uhci, qh);
--
-- /* If the QH is already active, we have a race with the hardware.
-- * This won't get fixed until dummy TDs are added. */
-- else if (qh->state == QH_STATE_ACTIVE) {
--
-- /* If the URB isn't first on its queue, adjust the link pointer
-- * of the last TD in the previous URB. */
-- if (urbp->node.prev != &urbp->qh->queue) {
-- struct urb_priv *purbp = list_entry(urbp->node.prev,
-- struct urb_priv, node);
-- struct uhci_td *ptd = list_entry(purbp->td_list.prev,
-- struct uhci_td, list);
-- struct uhci_td *td = list_entry(urbp->td_list.next,
-- struct uhci_td, list);
--
-- ptd->link = cpu_to_le32(td->dma_handle);
--
-- }
-- if (qh_element(qh) == UHCI_PTR_TERM) {
-- struct uhci_td *td = list_entry(urbp->td_list.next,
-- struct uhci_td, list);
--
-- qh->element = cpu_to_le32(td->dma_handle);
-- }
-- }
- goto done;
-
- err_submit_failed:
diff --git a/usb/uhci-use-one-qh-per-endpoint-not-per-urb.patch b/usb/uhci-use-one-qh-per-endpoint-not-per-urb.patch
deleted file mode 100644
index ed3417ac5b96c..0000000000000
--- a/usb/uhci-use-one-qh-per-endpoint-not-per-urb.patch
+++ /dev/null
@@ -1,2397 +0,0 @@
-From stern@rowland.harvard.edu Sat Dec 17 15:13:30 2005
-Date: Sat, 17 Dec 2005 17:58:46 -0500 (EST)
-From: Alan Stern <stern@rowland.harvard.edu>
-To: Greg KH <greg@kroah.com>
-Subject: [PATCH 1/4] UHCI: use one QH per endpoint, not per URB
-Message-ID: <Pine.LNX.4.44L0.0512171718340.14730-100000@netrider.rowland.org>
-
-This patch (as623) changes the uhci-hcd driver to make it use one QH per
-device endpoint, instead of a QH per URB as it does now. Numerous areas
-of the code are affected by this. For example, the distinction between
-"queued" URBs and non-"queued" URBs no longer exists; all URBs belong to
-a queue and some just happen to be at the queue's head.
-
-Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-
----
- drivers/usb/host/uhci-debug.c | 320 +++----------
- drivers/usb/host/uhci-hcd.c | 65 +-
- drivers/usb/host/uhci-hcd.h | 183 ++++---
- drivers/usb/host/uhci-q.c | 987 +++++++++++++++++++-----------------------
- 4 files changed, 689 insertions(+), 866 deletions(-)
-
---- gregkh-2.6.orig/drivers/usb/host/uhci-debug.c
-+++ gregkh-2.6/drivers/usb/host/uhci-debug.c
-@@ -90,13 +90,60 @@ static int uhci_show_td(struct uhci_td *
- return out - buf;
- }
-
--static int uhci_show_qh(struct uhci_qh *qh, char *buf, int len, int space)
-+static int uhci_show_urbp(struct urb_priv *urbp, char *buf, int len, int space)
- {
- char *out = buf;
-- struct urb_priv *urbp;
-- struct list_head *head, *tmp;
- struct uhci_td *td;
-- int i = 0, checked = 0, prevactive = 0;
-+ int i, nactive, ninactive;
-+
-+ if (len < 200)
-+ return 0;
-+
-+ out += sprintf(out, "urb_priv [%p] ", urbp);
-+ out += sprintf(out, "urb [%p] ", urbp->urb);
-+ out += sprintf(out, "qh [%p] ", urbp->qh);
-+ out += sprintf(out, "Dev=%d ", usb_pipedevice(urbp->urb->pipe));
-+ out += sprintf(out, "EP=%x(%s) ", usb_pipeendpoint(urbp->urb->pipe),
-+ (usb_pipein(urbp->urb->pipe) ? "IN" : "OUT"));
-+
-+ switch (usb_pipetype(urbp->urb->pipe)) {
-+ case PIPE_ISOCHRONOUS: out += sprintf(out, "ISO"); break;
-+ case PIPE_INTERRUPT: out += sprintf(out, "INT"); break;
-+ case PIPE_BULK: out += sprintf(out, "BLK"); break;
-+ case PIPE_CONTROL: out += sprintf(out, "CTL"); break;
-+ }
-+
-+ out += sprintf(out, "%s", (urbp->fsbr ? " FSBR" : ""));
-+ out += sprintf(out, "%s", (urbp->fsbr_timeout ? " FSBR_TO" : ""));
-+
-+ if (urbp->urb->status != -EINPROGRESS)
-+ out += sprintf(out, " Status=%d", urbp->urb->status);
-+ out += sprintf(out, "\n");
-+
-+ i = nactive = ninactive = 0;
-+ list_for_each_entry(td, &urbp->td_list, list) {
-+ if (++i <= 10 || debug > 2) {
-+ out += sprintf(out, "%*s%d: ", space + 2, "", i);
-+ out += uhci_show_td(td, out, len - (out - buf), 0);
-+ } else {
-+ if (td_status(td) & TD_CTRL_ACTIVE)
-+ ++nactive;
-+ else
-+ ++ninactive;
-+ }
-+ }
-+ if (nactive + ninactive > 0)
-+ out += sprintf(out, "%*s[skipped %d inactive and %d active "
-+ "TDs]\n",
-+ space, "", ninactive, nactive);
-+
-+ return out - buf;
-+}
-+
-+static int uhci_show_qh(struct uhci_qh *qh, char *buf, int len, int space)
-+{
-+ char *out = buf;
-+ int i, nurbs;
- __le32 element = qh_element(qh);
-
- /* Try to make sure there's enough memory */
-@@ -118,86 +165,36 @@ static int uhci_show_qh(struct uhci_qh *
- if (!(element & ~(UHCI_PTR_QH | UHCI_PTR_DEPTH)))
- out += sprintf(out, "%*s Element is NULL (bug?)\n", space, "");
-
-- if (!qh->urbp) {
-- out += sprintf(out, "%*s urbp == NULL\n", space, "");
-- goto out;
-- }
--
-- urbp = qh->urbp;
--
-- head = &urbp->td_list;
-- tmp = head->next;
--
-- td = list_entry(tmp, struct uhci_td, list);
--
-- if (cpu_to_le32(td->dma_handle) != (element & ~UHCI_PTR_BITS))
-- out += sprintf(out, "%*s Element != First TD\n", space, "");
--
-- while (tmp != head) {
-- struct uhci_td *td = list_entry(tmp, struct uhci_td, list);
--
-- tmp = tmp->next;
--
-- out += sprintf(out, "%*s%d: ", space + 2, "", i++);
-- out += uhci_show_td(td, out, len - (out - buf), 0);
--
-- if (i > 10 && !checked && prevactive && tmp != head &&
-- debug <= 2) {
-- struct list_head *ntmp = tmp;
-- struct uhci_td *ntd = td;
-- int active = 1, ni = i;
--
-- checked = 1;
--
-- while (ntmp != head && ntmp->next != head && active) {
-- ntd = list_entry(ntmp, struct uhci_td, list);
--
-- ntmp = ntmp->next;
--
-- active = td_status(ntd) & TD_CTRL_ACTIVE;
--
-- ni++;
-- }
--
-- if (active && ni > i) {
-- out += sprintf(out, "%*s[skipped %d active TDs]\n", space, "", ni - i);
-- tmp = ntmp;
-- td = ntd;
-- i = ni;
-- }
-+ if (list_empty(&qh->queue)) {
-+ out += sprintf(out, "%*s queue is empty\n", space, "");
-+ } else {
-+ struct urb_priv *urbp = list_entry(qh->queue.next,
-+ struct urb_priv, node);
-+ struct uhci_td *td = list_entry(urbp->td_list.next,
-+ struct uhci_td, list);
-+
-+ if (cpu_to_le32(td->dma_handle) != (element & ~UHCI_PTR_BITS))
-+ out += sprintf(out, "%*s Element != First TD\n",
-+ space, "");
-+ i = nurbs = 0;
-+ list_for_each_entry(urbp, &qh->queue, node) {
-+ if (++i <= 10)
-+ out += uhci_show_urbp(urbp, out,
-+ len - (out - buf), space + 2);
-+ else
-+ ++nurbs;
- }
--
-- prevactive = td_status(td) & TD_CTRL_ACTIVE;
-- }
--
-- if (list_empty(&urbp->queue_list) || urbp->queued)
-- goto out;
--
-- out += sprintf(out, "%*sQueued QHs:\n", -space, "--");
--
-- head = &urbp->queue_list;
-- tmp = head->next;
--
-- while (tmp != head) {
-- struct urb_priv *nurbp = list_entry(tmp, struct urb_priv,
-- queue_list);
-- tmp = tmp->next;
--
-- out += uhci_show_qh(nurbp->qh, out, len - (out - buf), space);
-+ if (nurbs > 0)
-+ out += sprintf(out, "%*s Skipped %d URBs\n",
-+ space, "", nurbs);
- }
-
--out:
- return out - buf;
- }
-
--#define show_frame_num() \
-- if (!shown) { \
-- shown = 1; \
-- out += sprintf(out, "- Frame %d\n", i); \
-- }
--
- #ifdef CONFIG_PROC_FS
- static const char * const qh_names[] = {
-+ "skel_unlink_qh", "skel_iso_qh",
- "skel_int128_qh", "skel_int64_qh",
- "skel_int32_qh", "skel_int16_qh",
- "skel_int8_qh", "skel_int4_qh",
-@@ -206,12 +203,6 @@ static const char * const qh_names[] = {
- "skel_bulk_qh", "skel_term_qh"
- };
-
--#define show_qh_name() \
-- if (!shown) { \
-- shown = 1; \
-- out += sprintf(out, "- %s\n", qh_names[i]); \
-- }
--
- static int uhci_show_sc(int port, unsigned short status, char *buf, int len)
- {
- char *out = buf;
-@@ -321,139 +312,29 @@ static int uhci_show_status(struct uhci_
- return out - buf;
- }
-
--static int uhci_show_urbp(struct uhci_hcd *uhci, struct urb_priv *urbp, char *buf, int len)
--{
-- struct list_head *tmp;
-- char *out = buf;
-- int count = 0;
--
-- if (len < 200)
-- return 0;
--
-- out += sprintf(out, "urb_priv [%p] ", urbp);
-- out += sprintf(out, "urb [%p] ", urbp->urb);
-- out += sprintf(out, "qh [%p] ", urbp->qh);
-- out += sprintf(out, "Dev=%d ", usb_pipedevice(urbp->urb->pipe));
-- out += sprintf(out, "EP=%x(%s) ", usb_pipeendpoint(urbp->urb->pipe), (usb_pipein(urbp->urb->pipe) ? "IN" : "OUT"));
--
-- switch (usb_pipetype(urbp->urb->pipe)) {
-- case PIPE_ISOCHRONOUS: out += sprintf(out, "ISO "); break;
-- case PIPE_INTERRUPT: out += sprintf(out, "INT "); break;
-- case PIPE_BULK: out += sprintf(out, "BLK "); break;
-- case PIPE_CONTROL: out += sprintf(out, "CTL "); break;
-- }
--
-- out += sprintf(out, "%s", (urbp->fsbr ? "FSBR " : ""));
-- out += sprintf(out, "%s", (urbp->fsbr_timeout ? "FSBR_TO " : ""));
--
-- if (urbp->urb->status != -EINPROGRESS)
-- out += sprintf(out, "Status=%d ", urbp->urb->status);
-- //out += sprintf(out, "FSBRtime=%lx ",urbp->fsbrtime);
--
-- count = 0;
-- list_for_each(tmp, &urbp->td_list)
-- count++;
-- out += sprintf(out, "TDs=%d ",count);
--
-- if (urbp->queued)
-- out += sprintf(out, "queued\n");
-- else {
-- count = 0;
-- list_for_each(tmp, &urbp->queue_list)
-- count++;
-- out += sprintf(out, "queued URBs=%d\n", count);
-- }
--
-- return out - buf;
--}
--
--static int uhci_show_lists(struct uhci_hcd *uhci, char *buf, int len)
--{
-- char *out = buf;
-- struct list_head *head, *tmp;
-- int count;
--
-- out += sprintf(out, "Main list URBs:");
-- if (list_empty(&uhci->urb_list))
-- out += sprintf(out, " Empty\n");
-- else {
-- out += sprintf(out, "\n");
-- count = 0;
-- head = &uhci->urb_list;
-- tmp = head->next;
-- while (tmp != head) {
-- struct urb_priv *urbp = list_entry(tmp, struct urb_priv, urb_list);
--
-- out += sprintf(out, " %d: ", ++count);
-- out += uhci_show_urbp(uhci, urbp, out, len - (out - buf));
-- tmp = tmp->next;
-- }
-- }
--
-- out += sprintf(out, "Remove list URBs:");
-- if (list_empty(&uhci->urb_remove_list))
-- out += sprintf(out, " Empty\n");
-- else {
-- out += sprintf(out, "\n");
-- count = 0;
-- head = &uhci->urb_remove_list;
-- tmp = head->next;
-- while (tmp != head) {
-- struct urb_priv *urbp = list_entry(tmp, struct urb_priv, urb_list);
--
-- out += sprintf(out, " %d: ", ++count);
-- out += uhci_show_urbp(uhci, urbp, out, len - (out - buf));
-- tmp = tmp->next;
-- }
-- }
--
-- out += sprintf(out, "Complete list URBs:");
-- if (list_empty(&uhci->complete_list))
-- out += sprintf(out, " Empty\n");
-- else {
-- out += sprintf(out, "\n");
-- count = 0;
-- head = &uhci->complete_list;
-- tmp = head->next;
-- while (tmp != head) {
-- struct urb_priv *urbp = list_entry(tmp, struct urb_priv, urb_list);
--
-- out += sprintf(out, " %d: ", ++count);
-- out += uhci_show_urbp(uhci, urbp, out, len - (out - buf));
-- tmp = tmp->next;
-- }
-- }
--
-- return out - buf;
--}
--
- static int uhci_sprint_schedule(struct uhci_hcd *uhci, char *buf, int len)
- {
-- unsigned long flags;
- char *out = buf;
- int i, j;
- struct uhci_qh *qh;
- struct uhci_td *td;
- struct list_head *tmp, *head;
-
-- spin_lock_irqsave(&uhci->lock, flags);
--
- out += uhci_show_root_hub_state(uhci, out, len - (out - buf));
- out += sprintf(out, "HC status\n");
- out += uhci_show_status(uhci, out, len - (out - buf));
-+ if (debug <= 1)
-+ return out - buf;
-
- out += sprintf(out, "Frame List\n");
- for (i = 0; i < UHCI_NUMFRAMES; ++i) {
-- int shown = 0;
- td = uhci->frame_cpu[i];
- if (!td)
- continue;
-
-- if (td->dma_handle != (dma_addr_t)uhci->frame[i]) {
-- show_frame_num();
-+ out += sprintf(out, "- Frame %d\n", i); \
-+ if (td->dma_handle != (dma_addr_t)uhci->frame[i])
- out += sprintf(out, " frame list does not match td->dma_handle!\n");
-- }
-- show_frame_num();
-
- head = &td->fl_list;
- tmp = head;
-@@ -467,14 +348,11 @@ static int uhci_sprint_schedule(struct u
- out += sprintf(out, "Skeleton QHs\n");
-
- for (i = 0; i < UHCI_NUM_SKELQH; ++i) {
-- int shown = 0;
-+ int cnt = 0;
-
- qh = uhci->skelqh[i];
--
-- if (debug > 1) {
-- show_qh_name();
-- out += uhci_show_qh(qh, out, len - (out - buf), 4);
-- }
-+ out += sprintf(out, "- %s\n", qh_names[i]); \
-+ out += uhci_show_qh(qh, out, len - (out - buf), 4);
-
- /* Last QH is the Terminating QH, it's different */
- if (i == UHCI_NUM_SKELQH - 1) {
-@@ -487,44 +365,27 @@ static int uhci_sprint_schedule(struct u
- continue;
- }
-
-- j = (i < 7) ? 7 : i+1; /* Next skeleton */
-- if (list_empty(&qh->list)) {
-- if (i < UHCI_NUM_SKELQH - 1) {
-- if (qh->link !=
-- (cpu_to_le32(uhci->skelqh[j]->dma_handle) | UHCI_PTR_QH)) {
-- show_qh_name();
-- out += sprintf(out, " skeleton QH not linked to next skeleton QH!\n");
-- }
-- }
--
-- continue;
-- }
--
-- show_qh_name();
--
-- head = &qh->list;
-+ j = (i < 9) ? 9 : i+1; /* Next skeleton */
-+ head = &qh->node;
- tmp = head->next;
-
- while (tmp != head) {
-- qh = list_entry(tmp, struct uhci_qh, list);
--
-+ qh = list_entry(tmp, struct uhci_qh, node);
- tmp = tmp->next;
--
-- out += uhci_show_qh(qh, out, len - (out - buf), 4);
-+ if (++cnt <= 10)
-+ out += uhci_show_qh(qh, out,
-+ len - (out - buf), 4);
- }
-+ if ((cnt -= 10) > 0)
-+ out += sprintf(out, " Skipped %d QHs\n", cnt);
-
-- if (i < UHCI_NUM_SKELQH - 1) {
-+ if (i > 1 && i < UHCI_NUM_SKELQH - 1) {
- if (qh->link !=
- (cpu_to_le32(uhci->skelqh[j]->dma_handle) | UHCI_PTR_QH))
- out += sprintf(out, " last QH not linked to next skeleton!\n");
- }
- }
-
-- if (debug > 2)
-- out += uhci_show_lists(uhci, out, len - (out - buf));
--
-- spin_unlock_irqrestore(&uhci->lock, flags);
--
- return out - buf;
- }
-
-@@ -541,6 +402,7 @@ static int uhci_debug_open(struct inode
- struct uhci_hcd *uhci = inode->u.generic_ip;
- struct uhci_debug *up;
- int ret = -ENOMEM;
-+ unsigned long flags;
-
- lock_kernel();
- up = kmalloc(sizeof(*up), GFP_KERNEL);
-@@ -553,7 +415,9 @@ static int uhci_debug_open(struct inode
- goto out;
- }
-
-+ spin_lock_irqsave(&uhci->lock, flags);
- up->size = uhci_sprint_schedule(uhci, up->data, MAX_OUTPUT);
-+ spin_unlock_irqrestore(&uhci->lock, flags);
-
- file->private_data = up;
-
---- gregkh-2.6.orig/drivers/usb/host/uhci-hcd.c
-+++ gregkh-2.6/drivers/usb/host/uhci-hcd.c
-@@ -54,7 +54,7 @@
- /*
- * Version Information
- */
--#define DRIVER_VERSION "v2.3"
-+#define DRIVER_VERSION "v3.0"
- #define DRIVER_AUTHOR "Linus 'Frodo Rabbit' Torvalds, Johannes Erdfelt, \
- Randy Dunlap, Georg Acher, Deti Fliegl, Thomas Sailer, Roman Weissgaerber, \
- Alan Stern"
-@@ -489,15 +489,11 @@ static int uhci_start(struct usb_hcd *hc
- uhci->fsbrtimeout = 0;
-
- spin_lock_init(&uhci->lock);
-- INIT_LIST_HEAD(&uhci->qh_remove_list);
-
- INIT_LIST_HEAD(&uhci->td_remove_list);
--
-- INIT_LIST_HEAD(&uhci->urb_remove_list);
--
- INIT_LIST_HEAD(&uhci->urb_list);
--
- INIT_LIST_HEAD(&uhci->complete_list);
-+ INIT_LIST_HEAD(&uhci->idle_qh_list);
-
- init_waitqueue_head(&uhci->waitqh);
-
-@@ -540,7 +536,7 @@ static int uhci_start(struct usb_hcd *hc
- }
-
- for (i = 0; i < UHCI_NUM_SKELQH; i++) {
-- uhci->skelqh[i] = uhci_alloc_qh(uhci);
-+ uhci->skelqh[i] = uhci_alloc_qh(uhci, NULL, NULL);
- if (!uhci->skelqh[i]) {
- dev_err(uhci_dev(uhci), "unable to allocate QH\n");
- goto err_alloc_skelqh;
-@@ -557,13 +553,17 @@ static int uhci_start(struct usb_hcd *hc
- uhci->skel_int16_qh->link =
- uhci->skel_int8_qh->link =
- uhci->skel_int4_qh->link =
-- uhci->skel_int2_qh->link =
-- cpu_to_le32(uhci->skel_int1_qh->dma_handle) | UHCI_PTR_QH;
-- uhci->skel_int1_qh->link = cpu_to_le32(uhci->skel_ls_control_qh->dma_handle) | UHCI_PTR_QH;
--
-- uhci->skel_ls_control_qh->link = cpu_to_le32(uhci->skel_fs_control_qh->dma_handle) | UHCI_PTR_QH;
-- uhci->skel_fs_control_qh->link = cpu_to_le32(uhci->skel_bulk_qh->dma_handle) | UHCI_PTR_QH;
-- uhci->skel_bulk_qh->link = cpu_to_le32(uhci->skel_term_qh->dma_handle) | UHCI_PTR_QH;
-+ uhci->skel_int2_qh->link = UHCI_PTR_QH |
-+ cpu_to_le32(uhci->skel_int1_qh->dma_handle);
-+
-+ uhci->skel_int1_qh->link = UHCI_PTR_QH |
-+ cpu_to_le32(uhci->skel_ls_control_qh->dma_handle);
-+ uhci->skel_ls_control_qh->link = UHCI_PTR_QH |
-+ cpu_to_le32(uhci->skel_fs_control_qh->dma_handle);
-+ uhci->skel_fs_control_qh->link = UHCI_PTR_QH |
-+ cpu_to_le32(uhci->skel_bulk_qh->dma_handle);
-+ uhci->skel_bulk_qh->link = UHCI_PTR_QH |
-+ cpu_to_le32(uhci->skel_term_qh->dma_handle);
-
- /* This dummy TD is to work around a bug in Intel PIIX controllers */
- uhci_fill_td(uhci->term_td, 0, uhci_explen(0) |
-@@ -589,15 +589,15 @@ static int uhci_start(struct usb_hcd *hc
-
- /*
- * ffs (Find First bit Set) does exactly what we need:
-- * 1,3,5,... => ffs = 0 => use skel_int2_qh = skelqh[6],
-- * 2,6,10,... => ffs = 1 => use skel_int4_qh = skelqh[5], etc.
-- * ffs > 6 => not on any high-period queue, so use
-- * skel_int1_qh = skelqh[7].
-+ * 1,3,5,... => ffs = 0 => use skel_int2_qh = skelqh[8],
-+ * 2,6,10,... => ffs = 1 => use skel_int4_qh = skelqh[7], etc.
-+ * ffs >= 7 => not on any high-period queue, so use
-+ * skel_int1_qh = skelqh[9].
- * Add UHCI_NUMFRAMES to insure at least one bit is set.
- */
-- irq = 6 - (int) __ffs(i + UHCI_NUMFRAMES);
-- if (irq < 0)
-- irq = 7;
-+ irq = 8 - (int) __ffs(i + UHCI_NUMFRAMES);
-+ if (irq <= 1)
-+ irq = 9;
-
- /* Only place we don't use the frame list routines */
- uhci->frame[i] = UHCI_PTR_QH |
-@@ -767,13 +767,30 @@ static int uhci_resume(struct usb_hcd *h
- }
- #endif
-
--/* Wait until all the URBs for a particular device/endpoint are gone */
-+/* Wait until a particular device/endpoint's QH is idle, and free it */
- static void uhci_hcd_endpoint_disable(struct usb_hcd *hcd,
-- struct usb_host_endpoint *ep)
-+ struct usb_host_endpoint *hep)
- {
- struct uhci_hcd *uhci = hcd_to_uhci(hcd);
-+ struct uhci_qh *qh;
-+
-+ spin_lock_irq(&uhci->lock);
-+ qh = (struct uhci_qh *) hep->hcpriv;
-+ if (qh == NULL)
-+ goto done;
-
-- wait_event_interruptible(uhci->waitqh, list_empty(&ep->urb_list));
-+ while (qh->state != QH_STATE_IDLE) {
-+ ++uhci->num_waiting;
-+ spin_unlock_irq(&uhci->lock);
-+ wait_event_interruptible(uhci->waitqh,
-+ qh->state == QH_STATE_IDLE);
-+ spin_lock_irq(&uhci->lock);
-+ --uhci->num_waiting;
-+ }
-+
-+ uhci_free_qh(uhci, qh);
-+done:
-+ spin_unlock_irq(&uhci->lock);
- }
-
- static int uhci_hcd_get_frame_number(struct usb_hcd *hcd)
---- gregkh-2.6.orig/drivers/usb/host/uhci-hcd.h
-+++ gregkh-2.6/drivers/usb/host/uhci-hcd.h
-@@ -28,8 +28,9 @@
- #define USBSTS_USBINT 0x0001 /* Interrupt due to IOC */
- #define USBSTS_ERROR 0x0002 /* Interrupt due to error */
- #define USBSTS_RD 0x0004 /* Resume Detect */
--#define USBSTS_HSE 0x0008 /* Host System Error - basically PCI problems */
--#define USBSTS_HCPE 0x0010 /* Host Controller Process Error - the scripts were buggy */
-+#define USBSTS_HSE 0x0008 /* Host System Error: PCI problems */
-+#define USBSTS_HCPE 0x0010 /* Host Controller Process Error:
-+ * the schedule is buggy */
- #define USBSTS_HCH 0x0020 /* HC Halted */
-
- /* Interrupt enable register */
-@@ -47,7 +48,8 @@
- /* USB port status and control registers */
- #define USBPORTSC1 16
- #define USBPORTSC2 18
--#define USBPORTSC_CCS 0x0001 /* Current Connect Status ("device present") */
-+#define USBPORTSC_CCS 0x0001 /* Current Connect Status
-+ * ("device present") */
- #define USBPORTSC_CSC 0x0002 /* Connect Status Change */
- #define USBPORTSC_PE 0x0004 /* Port Enable */
- #define USBPORTSC_PEC 0x0008 /* Port Enable Change */
-@@ -71,15 +73,16 @@
- #define USBLEGSUP_RWC 0x8f00 /* the R/WC bits */
- #define USBLEGSUP_RO 0x5040 /* R/O and reserved bits */
-
--#define UHCI_PTR_BITS cpu_to_le32(0x000F)
--#define UHCI_PTR_TERM cpu_to_le32(0x0001)
--#define UHCI_PTR_QH cpu_to_le32(0x0002)
--#define UHCI_PTR_DEPTH cpu_to_le32(0x0004)
--#define UHCI_PTR_BREADTH cpu_to_le32(0x0000)
-+#define UHCI_PTR_BITS __constant_cpu_to_le32(0x000F)
-+#define UHCI_PTR_TERM __constant_cpu_to_le32(0x0001)
-+#define UHCI_PTR_QH __constant_cpu_to_le32(0x0002)
-+#define UHCI_PTR_DEPTH __constant_cpu_to_le32(0x0004)
-+#define UHCI_PTR_BREADTH __constant_cpu_to_le32(0x0000)
-
- #define UHCI_NUMFRAMES 1024 /* in the frame list [array] */
- #define UHCI_MAX_SOF_NUMBER 2047 /* in an SOF packet */
--#define CAN_SCHEDULE_FRAMES 1000 /* how far future frames can be scheduled */
-+#define CAN_SCHEDULE_FRAMES 1000 /* how far in the future frames
-+ * can be scheduled */
-
-
- /*
-@@ -87,38 +90,54 @@
- */
-
- /*
-- * One role of a QH is to hold a queue of TDs for some endpoint. Each QH is
-- * used with one URB, and qh->element (updated by the HC) is either:
-- * - the next unprocessed TD for the URB, or
-- * - UHCI_PTR_TERM (when there's no more traffic for this endpoint), or
-- * - the QH for the next URB queued to the same endpoint.
-+ * One role of a QH is to hold a queue of TDs for some endpoint. One QH goes
-+ * with each endpoint, and qh->element (updated by the HC) is either:
-+ * - the next unprocessed TD in the endpoint's queue, or
-+ * - UHCI_PTR_TERM (when there's no more traffic for this endpoint).
- *
- * The other role of a QH is to serve as a "skeleton" framelist entry, so we
- * can easily splice a QH for some endpoint into the schedule at the right
- * place. Then qh->element is UHCI_PTR_TERM.
- *
-- * In the frame list, qh->link maintains a list of QHs seen by the HC:
-+ * In the schedule, qh->link maintains a list of QHs seen by the HC:
- * skel1 --> ep1-qh --> ep2-qh --> ... --> skel2 --> ...
-- */
-+ *
-+ * qh->node is the software equivalent of qh->link. The differences
-+ * are that the software list is doubly-linked and QHs in the UNLINKING
-+ * state are on the software list but not the hardware schedule.
-+ *
-+ * For bookkeeping purposes we maintain QHs even for Isochronous endpoints,
-+ * but they never get added to the hardware schedule.
-+ */
-+#define QH_STATE_IDLE 1 /* QH is not being used */
-+#define QH_STATE_UNLINKING 2 /* QH has been removed from the
-+ * schedule but the hardware may
-+ * still be using it */
-+#define QH_STATE_ACTIVE 3 /* QH is on the schedule */
-+
- struct uhci_qh {
- /* Hardware fields */
-- __le32 link; /* Next queue */
-- __le32 element; /* Queue element pointer */
-+ __le32 link; /* Next QH in the schedule */
-+ __le32 element; /* Queue element (TD) pointer */
-
- /* Software fields */
- dma_addr_t dma_handle;
-
-- struct urb_priv *urbp;
-+ struct list_head node; /* Node in the list of QHs */
-+ struct usb_host_endpoint *hep; /* Endpoint information */
-+ struct usb_device *udev;
-+ struct list_head queue; /* Queue of urbps for this QH */
-+ struct uhci_qh *skel; /* Skeleton for this QH */
-
-- struct list_head list;
-- struct list_head remove_list;
-+ unsigned int unlink_frame; /* When the QH was unlinked */
-+ int state; /* QH_STATE_xxx; see above */
- } __attribute__((aligned(16)));
-
- /*
- * We need a special accessor for the element pointer because it is
- * subject to asynchronous updates by the controller.
- */
--static __le32 inline qh_element(struct uhci_qh *qh) {
-+static inline __le32 qh_element(struct uhci_qh *qh) {
- __le32 element = qh->element;
-
- barrier();
-@@ -149,11 +168,13 @@ static __le32 inline qh_element(struct u
- #define TD_CTRL_ACTLEN_MASK 0x7FF /* actual length, encoded as n - 1 */
-
- #define TD_CTRL_ANY_ERROR (TD_CTRL_STALLED | TD_CTRL_DBUFERR | \
-- TD_CTRL_BABBLE | TD_CTRL_CRCTIME | TD_CTRL_BITSTUFF)
-+ TD_CTRL_BABBLE | TD_CTRL_CRCTIME | \
-+ TD_CTRL_BITSTUFF)
-
- #define uhci_maxerr(err) ((err) << TD_CTRL_C_ERR_SHIFT)
- #define uhci_status_bits(ctrl_sts) ((ctrl_sts) & 0xF60000)
--#define uhci_actual_length(ctrl_sts) (((ctrl_sts) + 1) & TD_CTRL_ACTLEN_MASK) /* 1-based */
-+#define uhci_actual_length(ctrl_sts) (((ctrl_sts) + 1) & \
-+ TD_CTRL_ACTLEN_MASK) /* 1-based */
-
- /*
- * for TD <info>: (a.k.a. Token)
-@@ -163,7 +184,7 @@ static __le32 inline qh_element(struct u
- #define TD_TOKEN_TOGGLE_SHIFT 19
- #define TD_TOKEN_TOGGLE (1 << 19)
- #define TD_TOKEN_EXPLEN_SHIFT 21
--#define TD_TOKEN_EXPLEN_MASK 0x7FF /* expected length, encoded as n - 1 */
-+#define TD_TOKEN_EXPLEN_MASK 0x7FF /* expected length, encoded as n-1 */
- #define TD_TOKEN_PID_MASK 0xFF
-
- #define uhci_explen(len) ((((len) - 1) & TD_TOKEN_EXPLEN_MASK) << \
-@@ -187,7 +208,7 @@ static __le32 inline qh_element(struct u
- * sw space after the TD entry.
- *
- * td->link points to either another TD (not necessarily for the same urb or
-- * even the same endpoint), or nothing (PTR_TERM), or a QH (for queued urbs).
-+ * even the same endpoint), or nothing (PTR_TERM), or a QH.
- */
- struct uhci_td {
- /* Hardware fields */
-@@ -210,7 +231,7 @@ struct uhci_td {
- * We need a special accessor for the control/status word because it is
- * subject to asynchronous updates by the controller.
- */
--static u32 inline td_status(struct uhci_td *td) {
-+static inline u32 td_status(struct uhci_td *td) {
- __le32 status = td->status;
-
- barrier();
-@@ -223,17 +244,14 @@ static u32 inline td_status(struct uhci_
- */
-
- /*
-- * The UHCI driver places Interrupt, Control and Bulk into QHs both
-- * to group together TDs for one transfer, and also to facilitate queuing
-- * of URBs. To make it easy to insert entries into the schedule, we have
-- * a skeleton of QHs for each predefined Interrupt latency, low-speed
-- * control, full-speed control and terminating QH (see explanation for
-- * the terminating QH below).
-+ * The UHCI driver uses QHs with Interrupt, Control and Bulk URBs for
-+ * automatic queuing. To make it easy to insert entries into the schedule,
-+ * we have a skeleton of QHs for each predefined Interrupt latency,
-+ * low-speed control, full-speed control, bulk, and terminating QH
-+ * (see explanation for the terminating QH below).
- *
- * When we want to add a new QH, we add it to the end of the list for the
-- * skeleton QH.
-- *
-- * For instance, the queue can look like this:
-+ * skeleton QH. For instance, the schedule list can look like this:
- *
- * skel int128 QH
- * dev 1 interrupt QH
-@@ -256,26 +274,31 @@ static u32 inline td_status(struct uhci_
- * - To loop back to the full-speed control queue for full-speed bandwidth
- * reclamation.
- *
-- * Isochronous transfers are stored before the start of the skeleton
-- * schedule and don't use QHs. While the UHCI spec doesn't forbid the
-- * use of QHs for Isochronous, it doesn't use them either. And the spec
-- * says that queues never advance on an error completion status, which
-- * makes them totally unsuitable for Isochronous transfers.
-- */
--
--#define UHCI_NUM_SKELQH 12
--#define skel_int128_qh skelqh[0]
--#define skel_int64_qh skelqh[1]
--#define skel_int32_qh skelqh[2]
--#define skel_int16_qh skelqh[3]
--#define skel_int8_qh skelqh[4]
--#define skel_int4_qh skelqh[5]
--#define skel_int2_qh skelqh[6]
--#define skel_int1_qh skelqh[7]
--#define skel_ls_control_qh skelqh[8]
--#define skel_fs_control_qh skelqh[9]
--#define skel_bulk_qh skelqh[10]
--#define skel_term_qh skelqh[11]
-+ * There's a special skeleton QH for Isochronous QHs. It never appears
-+ * on the schedule, and Isochronous TDs go on the schedule before the
-+ * the skeleton QHs. The hardware accesses them directly rather than
-+ * through their QH, which is used only for bookkeeping purposes.
-+ * While the UHCI spec doesn't forbid the use of QHs for Isochronous,
-+ * it doesn't use them either. And the spec says that queues never
-+ * advance on an error completion status, which makes them totally
-+ * unsuitable for Isochronous transfers.
-+ */
-+
-+#define UHCI_NUM_SKELQH 14
-+#define skel_unlink_qh skelqh[0]
-+#define skel_iso_qh skelqh[1]
-+#define skel_int128_qh skelqh[2]
-+#define skel_int64_qh skelqh[3]
-+#define skel_int32_qh skelqh[4]
-+#define skel_int16_qh skelqh[5]
-+#define skel_int8_qh skelqh[6]
-+#define skel_int4_qh skelqh[7]
-+#define skel_int2_qh skelqh[8]
-+#define skel_int1_qh skelqh[9]
-+#define skel_ls_control_qh skelqh[10]
-+#define skel_fs_control_qh skelqh[11]
-+#define skel_bulk_qh skelqh[12]
-+#define skel_term_qh skelqh[13]
-
- /*
- * Search tree for determining where <interval> fits in the skelqh[]
-@@ -293,21 +316,21 @@ static inline int __interval_to_skel(int
- if (interval < 16) {
- if (interval < 4) {
- if (interval < 2)
-- return 7; /* int1 for 0-1 ms */
-- return 6; /* int2 for 2-3 ms */
-+ return 9; /* int1 for 0-1 ms */
-+ return 8; /* int2 for 2-3 ms */
- }
- if (interval < 8)
-- return 5; /* int4 for 4-7 ms */
-- return 4; /* int8 for 8-15 ms */
-+ return 7; /* int4 for 4-7 ms */
-+ return 6; /* int8 for 8-15 ms */
- }
- if (interval < 64) {
- if (interval < 32)
-- return 3; /* int16 for 16-31 ms */
-- return 2; /* int32 for 32-63 ms */
-+ return 5; /* int16 for 16-31 ms */
-+ return 4; /* int32 for 32-63 ms */
- }
- if (interval < 128)
-- return 1; /* int64 for 64-127 ms */
-- return 0; /* int128 for 128-255 ms (Max.) */
-+ return 3; /* int64 for 64-127 ms */
-+ return 2; /* int128 for 128-255 ms (Max.) */
- }
-
-
-@@ -363,12 +386,12 @@ struct uhci_hcd {
-
- spinlock_t lock;
-
-- dma_addr_t frame_dma_handle; /* Hardware frame list */
-+ dma_addr_t frame_dma_handle; /* Hardware frame list */
- __le32 *frame;
-- void **frame_cpu; /* CPU's frame list */
-+ void **frame_cpu; /* CPU's frame list */
-
-- int fsbr; /* Full-speed bandwidth reclamation */
-- unsigned long fsbrtimeout; /* FSBR delay */
-+ int fsbr; /* Full-speed bandwidth reclamation */
-+ unsigned long fsbrtimeout; /* FSBR delay */
-
- enum uhci_rh_state rh_state;
- unsigned long auto_stop_time; /* When to AUTO_STOP */
-@@ -392,24 +415,19 @@ struct uhci_hcd {
- /* Main list of URBs currently controlled by this HC */
- struct list_head urb_list;
-
-- /* List of QHs that are done, but waiting to be unlinked (race) */
-- struct list_head qh_remove_list;
-- unsigned int qh_remove_age; /* Age in frames */
--
- /* List of TDs that are done, but waiting to be freed (race) */
- struct list_head td_remove_list;
- unsigned int td_remove_age; /* Age in frames */
-
-- /* List of asynchronously unlinked URBs */
-- struct list_head urb_remove_list;
-- unsigned int urb_remove_age; /* Age in frames */
--
- /* List of URBs awaiting completion callback */
- struct list_head complete_list;
-
-+ struct list_head idle_qh_list; /* Where the idle QHs live */
-+
- int rh_numports; /* Number of root-hub ports */
-
- wait_queue_head_t waitqh; /* endpoint_disable waiters */
-+ int num_waiting; /* Number of waiters */
- };
-
- /* Convert between a usb_hcd pointer and the corresponding uhci_hcd */
-@@ -430,22 +448,19 @@ static inline struct usb_hcd *uhci_to_hc
- */
- struct urb_priv {
- struct list_head urb_list;
-+ struct list_head node; /* Node in the QH's urbp list */
-
- struct urb *urb;
-
- struct uhci_qh *qh; /* QH for this URB */
- struct list_head td_list;
-
-- unsigned fsbr : 1; /* URB turned on FSBR */
-- unsigned fsbr_timeout : 1; /* URB timed out on FSBR */
-- unsigned queued : 1; /* QH was queued (not linked in) */
-- unsigned short_control_packet : 1; /* If we get a short packet during */
-- /* a control transfer, retrigger */
-- /* the status phase */
--
- unsigned long fsbrtime; /* In jiffies */
-
-- struct list_head queue_list;
-+ unsigned fsbr : 1; /* URB turned on FSBR */
-+ unsigned fsbr_timeout : 1; /* URB timed out on FSBR */
-+ unsigned short_transfer : 1; /* URB got a short transfer, no
-+ * need to rescan */
- };
-
-
---- gregkh-2.6.orig/drivers/usb/host/uhci-q.c
-+++ gregkh-2.6/drivers/usb/host/uhci-q.c
-@@ -13,13 +13,9 @@
- * (C) Copyright 2000 Yggdrasil Computing, Inc. (port of new PCI interface
- * support from usb-ohci.c by Adam Richter, adam@yggdrasil.com).
- * (C) Copyright 1999 Gregory P. Smith (from usb-ohci.c)
-- * (C) Copyright 2004 Alan Stern, stern@rowland.harvard.edu
-+ * (C) Copyright 2004-2005 Alan Stern, stern@rowland.harvard.edu
- */
-
--static int uhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb);
--static void uhci_unlink_generic(struct uhci_hcd *uhci, struct urb *urb);
--static void uhci_remove_pending_urbps(struct uhci_hcd *uhci);
--static void uhci_free_pending_qhs(struct uhci_hcd *uhci);
- static void uhci_free_pending_tds(struct uhci_hcd *uhci);
-
- /*
-@@ -30,7 +26,7 @@ static void uhci_free_pending_tds(struct
- * games with the FSBR code to make sure we get the correct order in all
- * the cases. I don't think it's worth the effort
- */
--static inline void uhci_set_next_interrupt(struct uhci_hcd *uhci)
-+static void uhci_set_next_interrupt(struct uhci_hcd *uhci)
- {
- if (uhci->is_stopped)
- mod_timer(&uhci_to_hcd(uhci)->rh_timer, jiffies);
-@@ -42,12 +38,6 @@ static inline void uhci_clear_next_inter
- uhci->term_td->status &= ~cpu_to_le32(TD_CTRL_IOC);
- }
-
--static inline void uhci_moveto_complete(struct uhci_hcd *uhci,
-- struct urb_priv *urbp)
--{
-- list_move_tail(&urbp->urb_list, &uhci->complete_list);
--}
--
- static struct uhci_td *uhci_alloc_td(struct uhci_hcd *uhci)
- {
- dma_addr_t dma_handle;
-@@ -71,6 +61,18 @@ static struct uhci_td *uhci_alloc_td(str
- return td;
- }
-
-+static void uhci_free_td(struct uhci_hcd *uhci, struct uhci_td *td)
-+{
-+ if (!list_empty(&td->list))
-+ dev_warn(uhci_dev(uhci), "td %p still in list!\n", td);
-+ if (!list_empty(&td->remove_list))
-+ dev_warn(uhci_dev(uhci), "td %p still in remove_list!\n", td);
-+ if (!list_empty(&td->fl_list))
-+ dev_warn(uhci_dev(uhci), "td %p still in fl_list!\n", td);
-+
-+ dma_pool_free(uhci->td_pool, td, td->dma_handle);
-+}
-+
- static inline void uhci_fill_td(struct uhci_td *td, u32 status,
- u32 token, u32 buffer)
- {
-@@ -82,7 +84,8 @@ static inline void uhci_fill_td(struct u
- /*
- * We insert Isochronous URBs directly into the frame list at the beginning
- */
--static void uhci_insert_td_frame_list(struct uhci_hcd *uhci, struct uhci_td *td, unsigned framenum)
-+static inline void uhci_insert_td_in_frame_list(struct uhci_hcd *uhci,
-+ struct uhci_td *td, unsigned framenum)
- {
- framenum &= (UHCI_NUMFRAMES - 1);
-
-@@ -108,7 +111,7 @@ static void uhci_insert_td_frame_list(st
- }
- }
-
--static inline void uhci_remove_td_frame_list(struct uhci_hcd *uhci,
-+static inline void uhci_remove_td_from_frame_list(struct uhci_hcd *uhci,
- struct uhci_td *td)
- {
- /* If it's not inserted, don't remove it */
-@@ -139,48 +142,68 @@ static inline void uhci_remove_td_frame_
- td->frame = -1;
- }
-
--static void unlink_isochronous_tds(struct uhci_hcd *uhci, struct urb *urb)
-+/*
-+ * Remove all the TDs for an Isochronous URB from the frame list
-+ */
-+static void uhci_unlink_isochronous_tds(struct uhci_hcd *uhci, struct urb *urb)
- {
- struct urb_priv *urbp = (struct urb_priv *) urb->hcpriv;
- struct uhci_td *td;
-
- list_for_each_entry(td, &urbp->td_list, list)
-- uhci_remove_td_frame_list(uhci, td);
-+ uhci_remove_td_from_frame_list(uhci, td);
- wmb();
- }
-
- /*
-- * Inserts a td list into qh.
-+ * Remove an URB's TDs from the hardware schedule
- */
--static void uhci_insert_tds_in_qh(struct uhci_qh *qh, struct urb *urb, __le32 breadth)
-+static void uhci_remove_tds_from_schedule(struct uhci_hcd *uhci,
-+ struct urb *urb, int status)
- {
-- struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv;
-- struct uhci_td *td;
-- __le32 *plink;
-+ struct urb_priv *urbp = (struct urb_priv *) urb->hcpriv;
-
-- /* Ordering isn't important here yet since the QH hasn't been */
-- /* inserted into the schedule yet */
-- plink = &qh->element;
-- list_for_each_entry(td, &urbp->td_list, list) {
-- *plink = cpu_to_le32(td->dma_handle) | breadth;
-- plink = &td->link;
-+ /* Isochronous TDs get unlinked directly from the frame list */
-+ if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
-+ uhci_unlink_isochronous_tds(uhci, urb);
-+ return;
- }
-- *plink = UHCI_PTR_TERM;
--}
-
--static void uhci_free_td(struct uhci_hcd *uhci, struct uhci_td *td)
--{
-- if (!list_empty(&td->list))
-- dev_warn(uhci_dev(uhci), "td %p still in list!\n", td);
-- if (!list_empty(&td->remove_list))
-- dev_warn(uhci_dev(uhci), "td %p still in remove_list!\n", td);
-- if (!list_empty(&td->fl_list))
-- dev_warn(uhci_dev(uhci), "td %p still in fl_list!\n", td);
--
-- dma_pool_free(uhci->td_pool, td, td->dma_handle);
-+ /* If the URB isn't first on its queue, adjust the link pointer
-+ * of the last TD in the previous URB. */
-+ if (urbp->node.prev != &urbp->qh->queue) {
-+ struct urb_priv *purbp;
-+ struct uhci_td *ptd, *ltd;
-+
-+ if (status == -EINPROGRESS)
-+ status = 0;
-+ purbp = list_entry(urbp->node.prev, struct urb_priv, node);
-+ ptd = list_entry(purbp->td_list.prev, struct uhci_td,
-+ list);
-+ ltd = list_entry(urbp->td_list.prev, struct uhci_td,
-+ list);
-+ ptd->link = ltd->link;
-+ }
-+
-+ /* If the URB completed with an error, then the QH element certainly
-+ * points to one of the URB's TDs. If it completed normally then
-+ * the QH element has certainly moved on to the next URB. And if
-+ * the URB is still in progress then it must have been dequeued.
-+ * The QH element either hasn't reached it yet or is somewhere in
-+ * the middle. If the URB wasn't first we can assume that it
-+ * hasn't started yet (see above): Otherwise all the preceding URBs
-+ * would have completed and been removed from the queue, so this one
-+ * _would_ be first.
-+ *
-+ * If the QH element is inside this URB, clear it. It will be
-+ * set properly when the QH is activated.
-+ */
-+ if (status < 0)
-+ urbp->qh->element = UHCI_PTR_TERM;
- }
-
--static struct uhci_qh *uhci_alloc_qh(struct uhci_hcd *uhci)
-+static struct uhci_qh *uhci_alloc_qh(struct uhci_hcd *uhci,
-+ struct usb_device *udev, struct usb_host_endpoint *hep)
- {
- dma_addr_t dma_handle;
- struct uhci_qh *qh;
-@@ -194,256 +217,120 @@ static struct uhci_qh *uhci_alloc_qh(str
- qh->element = UHCI_PTR_TERM;
- qh->link = UHCI_PTR_TERM;
-
-- qh->urbp = NULL;
--
-- INIT_LIST_HEAD(&qh->list);
-- INIT_LIST_HEAD(&qh->remove_list);
-+ INIT_LIST_HEAD(&qh->queue);
-+ INIT_LIST_HEAD(&qh->node);
-
-+ if (udev) { /* Normal QH */
-+ qh->state = QH_STATE_IDLE;
-+ qh->hep = hep;
-+ qh->udev = udev;
-+ hep->hcpriv = qh;
-+ usb_get_dev(udev);
-+
-+ } else { /* Skeleton QH */
-+ qh->state = QH_STATE_ACTIVE;
-+ qh->udev = NULL;
-+ }
- return qh;
- }
-
- static void uhci_free_qh(struct uhci_hcd *uhci, struct uhci_qh *qh)
- {
-- if (!list_empty(&qh->list))
-+ WARN_ON(qh->state != QH_STATE_IDLE && qh->udev);
-+ if (!list_empty(&qh->queue))
- dev_warn(uhci_dev(uhci), "qh %p list not empty!\n", qh);
-- if (!list_empty(&qh->remove_list))
-- dev_warn(uhci_dev(uhci), "qh %p still in remove_list!\n", qh);
-
-+ list_del(&qh->node);
-+ if (qh->udev) {
-+ qh->hep->hcpriv = NULL;
-+ usb_put_dev(qh->udev);
-+ }
- dma_pool_free(uhci->qh_pool, qh, qh->dma_handle);
- }
-
- /*
-- * Append this urb's qh after the last qh in skelqh->list
-- *
-- * Note that urb_priv.queue_list doesn't have a separate queue head;
-- * it's a ring with every element "live".
-+ * Put a QH on the schedule in both hardware and software
- */
--static void uhci_insert_qh(struct uhci_hcd *uhci, struct uhci_qh *skelqh, struct urb *urb)
-+static void uhci_activate_qh(struct uhci_hcd *uhci, struct uhci_qh *qh)
- {
-- struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv;
-- struct urb_priv *turbp;
-- struct uhci_qh *lqh;
-+ struct uhci_qh *pqh;
-
-- /* Grab the last QH */
-- lqh = list_entry(skelqh->list.prev, struct uhci_qh, list);
-+ WARN_ON(list_empty(&qh->queue));
-
-- /* Point to the next skelqh */
-- urbp->qh->link = lqh->link;
-- wmb(); /* Ordering is important */
-+ /* Set the element pointer if it isn't set already.
-+ * This isn't needed for Isochronous queues, but it doesn't hurt. */
-+ if (qh_element(qh) == UHCI_PTR_TERM) {
-+ struct urb_priv *urbp = list_entry(qh->queue.next,
-+ struct urb_priv, node);
-+ struct uhci_td *td = list_entry(urbp->td_list.next,
-+ struct uhci_td, list);
-
-- /*
-- * Patch QHs for previous endpoint's queued URBs? HC goes
-- * here next, not to the next skelqh it now points to.
-- *
-- * lqh --> td ... --> qh ... --> td --> qh ... --> td
-- * | | |
-- * v v v
-- * +<----------------+-----------------+
-- * v
-- * newqh --> td ... --> td
-- * |
-- * v
-- * ...
-- *
-- * The HC could see (and use!) any of these as we write them.
-- */
-- lqh->link = cpu_to_le32(urbp->qh->dma_handle) | UHCI_PTR_QH;
-- if (lqh->urbp) {
-- list_for_each_entry(turbp, &lqh->urbp->queue_list, queue_list)
-- turbp->qh->link = lqh->link;
-+ qh->element = cpu_to_le32(td->dma_handle);
- }
-
-- list_add_tail(&urbp->qh->list, &skelqh->list);
-+ if (qh->state == QH_STATE_ACTIVE)
-+ return;
-+ qh->state = QH_STATE_ACTIVE;
-+
-+ /* Move the QH from its old list to the end of the appropriate
-+ * skeleton's list */
-+ list_move_tail(&qh->node, &qh->skel->node);
-+
-+ /* Link it into the schedule */
-+ pqh = list_entry(qh->node.prev, struct uhci_qh, node);
-+ qh->link = pqh->link;
-+ wmb();
-+ pqh->link = UHCI_PTR_QH | cpu_to_le32(qh->dma_handle);
- }
-
- /*
-- * Start removal of QH from schedule; it finishes next frame.
-- * TDs should be unlinked before this is called.
-+ * Take a QH off the hardware schedule
- */
--static void uhci_remove_qh(struct uhci_hcd *uhci, struct uhci_qh *qh)
-+static void uhci_unlink_qh(struct uhci_hcd *uhci, struct uhci_qh *qh)
- {
- struct uhci_qh *pqh;
-- __le32 newlink;
-
-- if (!qh)
-+ if (qh->state == QH_STATE_UNLINKING)
- return;
-+ WARN_ON(qh->state != QH_STATE_ACTIVE || !qh->udev);
-+ qh->state = QH_STATE_UNLINKING;
-
-- /*
-- * Only go through the hoops if it's actually linked in
-- */
-- if (!list_empty(&qh->list)) {
--
-- /* If our queue is nonempty, make the next URB the head */
-- if (!list_empty(&qh->urbp->queue_list)) {
-- struct urb_priv *nurbp;
--
-- nurbp = list_entry(qh->urbp->queue_list.next,
-- struct urb_priv, queue_list);
-- nurbp->queued = 0;
-- list_add(&nurbp->qh->list, &qh->list);
-- newlink = cpu_to_le32(nurbp->qh->dma_handle) | UHCI_PTR_QH;
-- } else
-- newlink = qh->link;
--
-- /* Fix up the previous QH's queue to link to either
-- * the new head of this queue or the start of the
-- * next endpoint's queue. */
-- pqh = list_entry(qh->list.prev, struct uhci_qh, list);
-- pqh->link = newlink;
-- if (pqh->urbp) {
-- struct urb_priv *turbp;
--
-- list_for_each_entry(turbp, &pqh->urbp->queue_list,
-- queue_list)
-- turbp->qh->link = newlink;
-- }
-- wmb();
--
-- /* Leave qh->link in case the HC is on the QH now, it will */
-- /* continue the rest of the schedule */
-- qh->element = UHCI_PTR_TERM;
--
-- list_del_init(&qh->list);
-- }
--
-- list_del_init(&qh->urbp->queue_list);
-- qh->urbp = NULL;
-+ /* Unlink the QH from the schedule and record when we did it */
-+ pqh = list_entry(qh->node.prev, struct uhci_qh, node);
-+ pqh->link = qh->link;
-+ mb();
-
- uhci_get_current_frame_number(uhci);
-- if (uhci->frame_number + uhci->is_stopped != uhci->qh_remove_age) {
-- uhci_free_pending_qhs(uhci);
-- uhci->qh_remove_age = uhci->frame_number;
-- }
-+ qh->unlink_frame = uhci->frame_number;
-
-- /* Check to see if the remove list is empty. Set the IOC bit */
-- /* to force an interrupt so we can remove the QH */
-- if (list_empty(&uhci->qh_remove_list))
-+ /* Force an interrupt so we know when the QH is fully unlinked */
-+ if (list_empty(&uhci->skel_unlink_qh->node))
- uhci_set_next_interrupt(uhci);
-
-- list_add(&qh->remove_list, &uhci->qh_remove_list);
--}
--
--static int uhci_fixup_toggle(struct urb *urb, unsigned int toggle)
--{
-- struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv;
-- struct uhci_td *td;
--
-- list_for_each_entry(td, &urbp->td_list, list) {
-- if (toggle)
-- td->token |= cpu_to_le32(TD_TOKEN_TOGGLE);
-- else
-- td->token &= ~cpu_to_le32(TD_TOKEN_TOGGLE);
--
-- toggle ^= 1;
-- }
--
-- return toggle;
--}
--
--/* This function will append one URB's QH to another URB's QH. This is for */
--/* queuing interrupt, control or bulk transfers */
--static void uhci_append_queued_urb(struct uhci_hcd *uhci, struct urb *eurb, struct urb *urb)
--{
-- struct urb_priv *eurbp, *urbp, *furbp, *lurbp;
-- struct uhci_td *lltd;
--
-- eurbp = eurb->hcpriv;
-- urbp = urb->hcpriv;
--
-- /* Find the first URB in the queue */
-- furbp = eurbp;
-- if (eurbp->queued) {
-- list_for_each_entry(furbp, &eurbp->queue_list, queue_list)
-- if (!furbp->queued)
-- break;
-- }
--
-- lurbp = list_entry(furbp->queue_list.prev, struct urb_priv, queue_list);
--
-- lltd = list_entry(lurbp->td_list.prev, struct uhci_td, list);
--
-- /* Control transfers always start with toggle 0 */
-- if (!usb_pipecontrol(urb->pipe))
-- usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe),
-- usb_pipeout(urb->pipe),
-- uhci_fixup_toggle(urb,
-- uhci_toggle(td_token(lltd)) ^ 1));
--
-- /* All qhs in the queue need to link to the next queue */
-- urbp->qh->link = eurbp->qh->link;
--
-- wmb(); /* Make sure we flush everything */
--
-- lltd->link = cpu_to_le32(urbp->qh->dma_handle) | UHCI_PTR_QH;
--
-- list_add_tail(&urbp->queue_list, &furbp->queue_list);
--
-- urbp->queued = 1;
-+ /* Move the QH from its old list to the end of the unlinking list */
-+ list_move_tail(&qh->node, &uhci->skel_unlink_qh->node);
- }
-
--static void uhci_delete_queued_urb(struct uhci_hcd *uhci, struct urb *urb)
-+/*
-+ * When we and the controller are through with a QH, it becomes IDLE.
-+ * This happens when a QH has been off the schedule (on the unlinking
-+ * list) for more than one frame, or when an error occurs while adding
-+ * the first URB onto a new QH.
-+ */
-+static void uhci_make_qh_idle(struct uhci_hcd *uhci, struct uhci_qh *qh)
- {
-- struct urb_priv *urbp, *nurbp, *purbp, *turbp;
-- struct uhci_td *pltd;
-- unsigned int toggle;
--
-- urbp = urb->hcpriv;
--
-- if (list_empty(&urbp->queue_list))
-- return;
--
-- nurbp = list_entry(urbp->queue_list.next, struct urb_priv, queue_list);
--
-- /*
-- * Fix up the toggle for the following URBs in the queue.
-- * Only needed for bulk and interrupt: control and isochronous
-- * endpoints don't propagate toggles between messages.
-- */
-- if (usb_pipebulk(urb->pipe) || usb_pipeint(urb->pipe)) {
-- if (!urbp->queued)
-- /* We just set the toggle in uhci_unlink_generic */
-- toggle = usb_gettoggle(urb->dev,
-- usb_pipeendpoint(urb->pipe),
-- usb_pipeout(urb->pipe));
-- else {
-- /* If we're in the middle of the queue, grab the */
-- /* toggle from the TD previous to us */
-- purbp = list_entry(urbp->queue_list.prev,
-- struct urb_priv, queue_list);
-- pltd = list_entry(purbp->td_list.prev,
-- struct uhci_td, list);
-- toggle = uhci_toggle(td_token(pltd)) ^ 1;
-- }
--
-- list_for_each_entry(turbp, &urbp->queue_list, queue_list) {
-- if (!turbp->queued)
-- break;
-- toggle = uhci_fixup_toggle(turbp->urb, toggle);
-- }
--
-- usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe),
-- usb_pipeout(urb->pipe), toggle);
-- }
-+ WARN_ON(qh->state == QH_STATE_ACTIVE);
-
-- if (urbp->queued) {
-- /* We're somewhere in the middle (or end). The case where
-- * we're at the head is handled in uhci_remove_qh(). */
-- purbp = list_entry(urbp->queue_list.prev, struct urb_priv,
-- queue_list);
--
-- pltd = list_entry(purbp->td_list.prev, struct uhci_td, list);
-- if (nurbp->queued)
-- pltd->link = cpu_to_le32(nurbp->qh->dma_handle) | UHCI_PTR_QH;
-- else
-- /* The next URB happens to be the beginning, so */
-- /* we're the last, end the chain */
-- pltd->link = UHCI_PTR_TERM;
-- }
-+ list_move(&qh->node, &uhci->idle_qh_list);
-+ qh->state = QH_STATE_IDLE;
-
-- /* urbp->queue_list is handled in uhci_remove_qh() */
-+ /* If anyone is waiting for a QH to become idle, wake them up */
-+ if (uhci->num_waiting)
-+ wake_up_all(&uhci->waitqh);
- }
-
--static struct urb_priv *uhci_alloc_urb_priv(struct uhci_hcd *uhci, struct urb *urb)
-+static inline struct urb_priv *uhci_alloc_urb_priv(struct uhci_hcd *uhci,
-+ struct urb *urb)
- {
- struct urb_priv *urbp;
-
-@@ -453,17 +340,14 @@ static struct urb_priv *uhci_alloc_urb_p
-
- memset((void *)urbp, 0, sizeof(*urbp));
-
-- urbp->fsbrtime = jiffies;
- urbp->urb = urb;
-+ urb->hcpriv = urbp;
-+ urbp->fsbrtime = jiffies;
-
-+ INIT_LIST_HEAD(&urbp->node);
- INIT_LIST_HEAD(&urbp->td_list);
-- INIT_LIST_HEAD(&urbp->queue_list);
- INIT_LIST_HEAD(&urbp->urb_list);
-
-- list_add_tail(&urbp->urb_list, &uhci->urb_list);
--
-- urb->hcpriv = urbp;
--
- return urbp;
- }
-
-@@ -482,18 +366,17 @@ static void uhci_remove_td_from_urb(stru
- list_del_init(&td->list);
- }
-
--static void uhci_destroy_urb_priv(struct uhci_hcd *uhci, struct urb *urb)
-+static void uhci_free_urb_priv(struct uhci_hcd *uhci,
-+ struct urb_priv *urbp)
- {
- struct uhci_td *td, *tmp;
-- struct urb_priv *urbp;
--
-- urbp = (struct urb_priv *)urb->hcpriv;
-- if (!urbp)
-- return;
-
- if (!list_empty(&urbp->urb_list))
-- dev_warn(uhci_dev(uhci), "urb %p still on uhci->urb_list "
-- "or uhci->remove_list!\n", urb);
-+ dev_warn(uhci_dev(uhci), "urb %p still on uhci->urb_list!\n",
-+ urbp->urb);
-+ if (!list_empty(&urbp->node))
-+ dev_warn(uhci_dev(uhci), "urb %p still on QH's list!\n",
-+ urbp->urb);
-
- uhci_get_current_frame_number(uhci);
- if (uhci->frame_number + uhci->is_stopped != uhci->td_remove_age) {
-@@ -502,7 +385,7 @@ static void uhci_destroy_urb_priv(struct
- }
-
- /* Check to see if the remove list is empty. Set the IOC bit */
-- /* to force an interrupt so we can remove the TDs*/
-+ /* to force an interrupt so we can remove the TDs. */
- if (list_empty(&uhci->td_remove_list))
- uhci_set_next_interrupt(uhci);
-
-@@ -511,7 +394,7 @@ static void uhci_destroy_urb_priv(struct
- list_add(&td->remove_list, &uhci->td_remove_list);
- }
-
-- urb->hcpriv = NULL;
-+ urbp->urb->hcpriv = NULL;
- kmem_cache_free(uhci_up_cachep, urbp);
- }
-
-@@ -568,17 +451,82 @@ static int uhci_map_status(int status, i
- }
-
- /*
-+ * Fix up the data toggles for URBs in a queue, when one of them
-+ * terminates early (short transfer, error, or dequeued).
-+ */
-+static void uhci_fixup_toggles(struct urb *urb)
-+{
-+ struct list_head *head;
-+ struct uhci_td *td;
-+ struct urb_priv *urbp = (struct urb_priv *) urb->hcpriv;
-+ int prevactive = 0;
-+ unsigned int toggle = 0;
-+ struct urb_priv *turbp, *list_end;
-+
-+ /*
-+ * We need to find out what the last successful toggle was so
-+ * we can update the data toggles for the following transfers.
-+ *
-+ * There are 2 ways the last successful completed TD is found:
-+ *
-+ * 1) The TD is NOT active and the actual length < expected length
-+ * 2) The TD is NOT active and it's the last TD in the chain
-+ *
-+ * and a third way the first uncompleted TD is found:
-+ *
-+ * 3) The TD is active and the previous TD is NOT active
-+ */
-+ head = &urbp->td_list;
-+ list_for_each_entry(td, head, list) {
-+ unsigned int ctrlstat = td_status(td);
-+
-+ if (!(ctrlstat & TD_CTRL_ACTIVE) &&
-+ (uhci_actual_length(ctrlstat) <
-+ uhci_expected_length(td_token(td)) ||
-+ td->list.next == head))
-+ toggle = uhci_toggle(td_token(td)) ^ 1;
-+ else if ((ctrlstat & TD_CTRL_ACTIVE) && !prevactive)
-+ toggle = uhci_toggle(td_token(td));
-+
-+ prevactive = ctrlstat & TD_CTRL_ACTIVE;
-+ }
-+
-+ /*
-+ * Fix up the toggle for the following URBs in the queue.
-+ *
-+ * We can stop as soon as we find an URB with toggles set correctly,
-+ * because then all the following URBs will be correct also.
-+ */
-+ list_end = list_entry(&urbp->qh->queue, struct urb_priv, node);
-+ turbp = urbp;
-+ while ((turbp = list_entry(turbp->node.next, struct urb_priv, node))
-+ != list_end) {
-+ td = list_entry(turbp->td_list.next, struct uhci_td, list);
-+ if (uhci_toggle(td_token(td)) == toggle)
-+ return;
-+
-+ list_for_each_entry(td, &turbp->td_list, list) {
-+ td->token ^= __constant_cpu_to_le32(TD_TOKEN_TOGGLE);
-+ toggle ^= 1;
-+ }
-+ }
-+
-+ usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe),
-+ usb_pipeout(urb->pipe), toggle);
-+}
-+
-+/*
- * Control transfers
- */
--static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb, struct urb *eurb)
-+static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb,
-+ struct uhci_qh *qh)
- {
-- struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv;
- struct uhci_td *td;
-- struct uhci_qh *qh, *skelqh;
- unsigned long destination, status;
-- int maxsze = usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe));
-+ int maxsze = le16_to_cpu(qh->hep->desc.wMaxPacketSize);
- int len = urb->transfer_buffer_length;
- dma_addr_t data = urb->transfer_dma;
-+ __le32 *plink;
-
- /* The "pipe" thing contains the destination in bits 8--18 */
- destination = (urb->pipe & PIPE_DEVEP_MASK) | USB_PID_SETUP;
-@@ -597,7 +545,8 @@ static int uhci_submit_control(struct uh
-
- uhci_add_td_to_urb(urb, td);
- uhci_fill_td(td, status, destination | uhci_explen(8),
-- urb->setup_dma);
-+ urb->setup_dma);
-+ plink = &td->link;
-
- /*
- * If direction is "send", change the packet ID from SETUP (0x2D)
-@@ -615,21 +564,20 @@ static int uhci_submit_control(struct uh
- * Build the DATA TDs
- */
- while (len > 0) {
-- int pktsze = len;
--
-- if (pktsze > maxsze)
-- pktsze = maxsze;
-+ int pktsze = min(len, maxsze);
-
- td = uhci_alloc_td(uhci);
- if (!td)
- return -ENOMEM;
-+ *plink = cpu_to_le32(td->dma_handle);
-
- /* Alternate Data0/1 (start with Data1) */
- destination ^= TD_TOKEN_TOGGLE;
-
- uhci_add_td_to_urb(urb, td);
- uhci_fill_td(td, status, destination | uhci_explen(pktsze),
-- data);
-+ data);
-+ plink = &td->link;
-
- data += pktsze;
- len -= pktsze;
-@@ -641,6 +589,7 @@ static int uhci_submit_control(struct uh
- td = uhci_alloc_td(uhci);
- if (!td)
- return -ENOMEM;
-+ *plink = cpu_to_le32(td->dma_handle);
-
- /*
- * It's IN if the pipe is an output pipe or we're not expecting
-@@ -658,16 +607,7 @@ static int uhci_submit_control(struct uh
-
- uhci_add_td_to_urb(urb, td);
- uhci_fill_td(td, status | TD_CTRL_IOC,
-- destination | uhci_explen(0), 0);
--
-- qh = uhci_alloc_qh(uhci);
-- if (!qh)
-- return -ENOMEM;
--
-- urbp->qh = qh;
-- qh->urbp = urbp;
--
-- uhci_insert_tds_in_qh(qh, urb, UHCI_PTR_BREADTH);
-+ destination | uhci_explen(0), 0);
-
- /* Low-speed transfers get a different queue, and won't hog the bus.
- * Also, some devices enumerate better without FSBR; the easiest way
-@@ -675,18 +615,13 @@ static int uhci_submit_control(struct uh
- * isn't in the CONFIGURED state. */
- if (urb->dev->speed == USB_SPEED_LOW ||
- urb->dev->state != USB_STATE_CONFIGURED)
-- skelqh = uhci->skel_ls_control_qh;
-+ qh->skel = uhci->skel_ls_control_qh;
- else {
-- skelqh = uhci->skel_fs_control_qh;
-+ qh->skel = uhci->skel_fs_control_qh;
- uhci_inc_fsbr(uhci, urb);
- }
-
-- if (eurb)
-- uhci_append_queued_urb(uhci, eurb, urb);
-- else
-- uhci_insert_qh(uhci, skelqh, urb);
--
-- return -EINPROGRESS;
-+ return 0;
- }
-
- /*
-@@ -703,7 +638,7 @@ static int usb_control_retrigger_status(
- struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv;
- struct uhci_td *td;
-
-- urbp->short_control_packet = 1;
-+ urbp->short_transfer = 1;
-
- td = list_entry(urbp->td_list.prev, struct uhci_td, list);
- urbp->qh->element = cpu_to_le32(td->dma_handle);
-@@ -720,16 +655,14 @@ static int uhci_result_control(struct uh
- unsigned int status;
- int ret = 0;
-
-- if (list_empty(&urbp->td_list))
-- return -EINVAL;
--
- head = &urbp->td_list;
--
-- if (urbp->short_control_packet) {
-+ if (urbp->short_transfer) {
- tmp = head->prev;
- goto status_stage;
- }
-
-+ urb->actual_length = 0;
-+
- tmp = head->next;
- td = list_entry(tmp, struct uhci_td, list);
-
-@@ -742,8 +675,6 @@ static int uhci_result_control(struct uh
- if (status)
- goto td_error;
-
-- urb->actual_length = 0;
--
- /* The rest of the TDs (but the last) are data */
- tmp = tmp->next;
- while (tmp != head && tmp->next != head) {
-@@ -770,10 +701,7 @@ static int uhci_result_control(struct uh
- goto err;
- }
-
-- if (uhci_packetid(td_token(td)) == USB_PID_IN)
-- return usb_control_retrigger_status(uhci, urb);
-- else
-- return 0;
-+ return usb_control_retrigger_status(uhci, urb);
- }
- }
-
-@@ -825,15 +753,15 @@ err:
- /*
- * Common submit for bulk and interrupt
- */
--static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb, struct urb *eurb, struct uhci_qh *skelqh)
-+static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb,
-+ struct uhci_qh *qh)
- {
- struct uhci_td *td;
-- struct uhci_qh *qh;
- unsigned long destination, status;
-- int maxsze = usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe));
-+ int maxsze = le16_to_cpu(qh->hep->desc.wMaxPacketSize);
- int len = urb->transfer_buffer_length;
-- struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv;
- dma_addr_t data = urb->transfer_dma;
-+ __le32 *plink, fake_link;
-
- if (len < 0)
- return -EINVAL;
-@@ -841,7 +769,8 @@ static int uhci_submit_common(struct uhc
- /* The "pipe" thing contains the destination in bits 8--18 */
- destination = (urb->pipe & PIPE_DEVEP_MASK) | usb_packetid(urb->pipe);
-
-- status = uhci_maxerr(3) | TD_CTRL_ACTIVE;
-+ /* 3 errors */
-+ status = TD_CTRL_ACTIVE | uhci_maxerr(3);
- if (urb->dev->speed == USB_SPEED_LOW)
- status |= TD_CTRL_LS;
- if (usb_pipein(urb->pipe))
-@@ -850,10 +779,11 @@ static int uhci_submit_common(struct uhc
- /*
- * Build the DATA TDs
- */
-+ plink = &fake_link;
- do { /* Allow zero length packets */
- int pktsze = maxsze;
-
-- if (pktsze >= len) {
-+ if (len <= pktsze) { /* The last packet */
- pktsze = len;
- if (!(urb->transfer_flags & URB_SHORT_NOT_OK))
- status &= ~TD_CTRL_SPD;
-@@ -862,12 +792,15 @@ static int uhci_submit_common(struct uhc
- td = uhci_alloc_td(uhci);
- if (!td)
- return -ENOMEM;
-+ *plink = cpu_to_le32(td->dma_handle);
-
- uhci_add_td_to_urb(urb, td);
-- uhci_fill_td(td, status, destination | uhci_explen(pktsze) |
-+ uhci_fill_td(td, status,
-+ destination | uhci_explen(pktsze) |
- (usb_gettoggle(urb->dev, usb_pipeendpoint(urb->pipe),
- usb_pipeout(urb->pipe)) << TD_TOKEN_TOGGLE_SHIFT),
- data);
-+ plink = &td->link;
-
- data += pktsze;
- len -= maxsze;
-@@ -883,11 +816,13 @@ static int uhci_submit_common(struct uhc
- * however, if transfer_length == 0, the zero packet was already
- * prepared above.
- */
-- if (usb_pipeout(urb->pipe) && (urb->transfer_flags & URB_ZERO_PACKET) &&
-- !len && urb->transfer_buffer_length) {
-+ if ((urb->transfer_flags & URB_ZERO_PACKET) &&
-+ usb_pipeout(urb->pipe) && len == 0 &&
-+ urb->transfer_buffer_length > 0) {
- td = uhci_alloc_td(uhci);
- if (!td)
- return -ENOMEM;
-+ *plink = cpu_to_le32(td->dma_handle);
-
- uhci_add_td_to_urb(urb, td);
- uhci_fill_td(td, status, destination | uhci_explen(0) |
-@@ -905,24 +840,9 @@ static int uhci_submit_common(struct uhc
- * fast side but not enough to justify delaying an interrupt
- * more than 2 or 3 URBs, so we will ignore the URB_NO_INTERRUPT
- * flag setting. */
-- td->status |= cpu_to_le32(TD_CTRL_IOC);
--
-- qh = uhci_alloc_qh(uhci);
-- if (!qh)
-- return -ENOMEM;
--
-- urbp->qh = qh;
-- qh->urbp = urbp;
-+ td->status |= __constant_cpu_to_le32(TD_CTRL_IOC);
-
-- /* Always breadth first */
-- uhci_insert_tds_in_qh(qh, urb, UHCI_PTR_BREADTH);
--
-- if (eurb)
-- uhci_append_queued_urb(uhci, eurb, urb);
-- else
-- uhci_insert_qh(uhci, skelqh, urb);
--
-- return -EINPROGRESS;
-+ return 0;
- }
-
- /*
-@@ -954,8 +874,24 @@ static int uhci_result_common(struct uhc
- if (urb->transfer_flags & URB_SHORT_NOT_OK) {
- ret = -EREMOTEIO;
- goto err;
-- } else
-- return 0;
-+ }
-+
-+ /*
-+ * This URB stopped short of its end. We have to
-+ * fix up the toggles of the following URBs on the
-+ * queue and restart the queue.
-+ *
-+ * Do this only the first time we encounter the
-+ * short URB.
-+ */
-+ if (!urbp->short_transfer) {
-+ urbp->short_transfer = 1;
-+ uhci_fixup_toggles(urb);
-+ td = list_entry(urbp->td_list.prev,
-+ struct uhci_td, list);
-+ urbp->qh->element = td->link;
-+ }
-+ break;
- }
- }
-
-@@ -988,7 +924,8 @@ err:
- return ret;
- }
-
--static inline int uhci_submit_bulk(struct uhci_hcd *uhci, struct urb *urb, struct urb *eurb)
-+static inline int uhci_submit_bulk(struct uhci_hcd *uhci, struct urb *urb,
-+ struct uhci_qh *qh)
- {
- int ret;
-
-@@ -996,21 +933,22 @@ static inline int uhci_submit_bulk(struc
- if (urb->dev->speed == USB_SPEED_LOW)
- return -EINVAL;
-
-- ret = uhci_submit_common(uhci, urb, eurb, uhci->skel_bulk_qh);
-- if (ret == -EINPROGRESS)
-+ qh->skel = uhci->skel_bulk_qh;
-+ ret = uhci_submit_common(uhci, urb, qh);
-+ if (ret == 0)
- uhci_inc_fsbr(uhci, urb);
--
- return ret;
- }
-
--static inline int uhci_submit_interrupt(struct uhci_hcd *uhci, struct urb *urb, struct urb *eurb)
-+static inline int uhci_submit_interrupt(struct uhci_hcd *uhci, struct urb *urb,
-+ struct uhci_qh *qh)
- {
-- /* USB 1.1 interrupt transfers only involve one packet per interval;
-- * that's the uhci_submit_common() "breadth first" policy. Drivers
-- * can submit urbs of any length, but longer ones might need many
-- * intervals to complete.
-+ /* USB 1.1 interrupt transfers only involve one packet per interval.
-+ * Drivers can submit URBs of any length, but longer ones will need
-+ * multiple intervals to complete.
- */
-- return uhci_submit_common(uhci, urb, eurb, uhci->skelqh[__interval_to_skel(urb->interval)]);
-+ qh->skel = uhci->skelqh[__interval_to_skel(urb->interval)];
-+ return uhci_submit_common(uhci, urb, qh);
- }
-
- /*
-@@ -1072,11 +1010,12 @@ static int isochronous_find_start(struct
- /*
- * Isochronous transfers
- */
--static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb)
-+static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb,
-+ struct uhci_qh *qh)
- {
-- struct uhci_td *td;
-+ struct uhci_td *td = NULL; /* Since urb->number_of_packets > 0 */
- int i, ret, frame;
-- int status, destination;
-+ unsigned long destination, status;
- struct urb_priv *urbp = (struct urb_priv *) urb->hcpriv;
-
- status = TD_CTRL_ACTIVE | TD_CTRL_IOS;
-@@ -1092,20 +1031,25 @@ static int uhci_submit_isochronous(struc
- return -ENOMEM;
-
- uhci_add_td_to_urb(urb, td);
-- uhci_fill_td(td, status, destination | uhci_explen(urb->iso_frame_desc[i].length),
-- urb->transfer_dma + urb->iso_frame_desc[i].offset);
--
-- if (i + 1 >= urb->number_of_packets)
-- td->status |= cpu_to_le32(TD_CTRL_IOC);
-+ uhci_fill_td(td, status, destination |
-+ uhci_explen(urb->iso_frame_desc[i].length),
-+ urb->transfer_dma +
-+ urb->iso_frame_desc[i].offset);
- }
-
-+ /* Set the interrupt-on-completion flag on the last packet. */
-+ td->status |= __constant_cpu_to_le32(TD_CTRL_IOC);
-+
-+ qh->skel = uhci->skel_iso_qh;
-+
-+ /* Add the TDs to the frame list */
- frame = urb->start_frame;
- list_for_each_entry(td, &urbp->td_list, list) {
-- uhci_insert_td_frame_list(uhci, td, frame);
-+ uhci_insert_td_in_frame_list(uhci, td, frame);
- frame += urb->interval;
- }
-
-- return -EINPROGRESS;
-+ return 0;
- }
-
- static int uhci_result_isochronous(struct uhci_hcd *uhci, struct urb *urb)
-@@ -1139,80 +1083,67 @@ static int uhci_result_isochronous(struc
-
- i++;
- }
-- unlink_isochronous_tds(uhci, urb);
-
- return ret;
- }
-
--static struct urb *uhci_find_urb_ep(struct uhci_hcd *uhci, struct urb *urb)
--{
-- struct urb_priv *up;
--
-- /* We don't match Isoc transfers since they are special */
-- if (usb_pipeisoc(urb->pipe))
-- return NULL;
--
-- list_for_each_entry(up, &uhci->urb_list, urb_list) {
-- struct urb *u = up->urb;
--
-- if (u->dev == urb->dev && u->status == -EINPROGRESS) {
-- /* For control, ignore the direction */
-- if (usb_pipecontrol(urb->pipe) &&
-- (u->pipe & ~USB_DIR_IN) == (urb->pipe & ~USB_DIR_IN))
-- return u;
-- else if (u->pipe == urb->pipe)
-- return u;
-- }
-- }
--
-- return NULL;
--}
--
- static int uhci_urb_enqueue(struct usb_hcd *hcd,
-- struct usb_host_endpoint *ep,
-+ struct usb_host_endpoint *hep,
- struct urb *urb, gfp_t mem_flags)
- {
- int ret;
- struct uhci_hcd *uhci = hcd_to_uhci(hcd);
- unsigned long flags;
-- struct urb *eurb;
-+ struct urb_priv *urbp;
-+ struct uhci_qh *qh;
- int bustime;
-
- spin_lock_irqsave(&uhci->lock, flags);
-
- ret = urb->status;
- if (ret != -EINPROGRESS) /* URB already unlinked! */
-- goto out;
-+ goto done;
-
-- eurb = uhci_find_urb_ep(uhci, urb);
-+ ret = -ENOMEM;
-+ urbp = uhci_alloc_urb_priv(uhci, urb);
-+ if (!urbp)
-+ goto done;
-
-- if (!uhci_alloc_urb_priv(uhci, urb)) {
-- ret = -ENOMEM;
-- goto out;
-+ if (hep->hcpriv)
-+ qh = (struct uhci_qh *) hep->hcpriv;
-+ else {
-+ qh = uhci_alloc_qh(uhci, urb->dev, hep);
-+ if (!qh)
-+ goto err_no_qh;
- }
-+ urbp->qh = qh;
-
- switch (usb_pipetype(urb->pipe)) {
- case PIPE_CONTROL:
-- ret = uhci_submit_control(uhci, urb, eurb);
-+ ret = uhci_submit_control(uhci, urb, qh);
-+ break;
-+ case PIPE_BULK:
-+ ret = uhci_submit_bulk(uhci, urb, qh);
- break;
- case PIPE_INTERRUPT:
-- if (!eurb) {
-+ if (list_empty(&qh->queue)) {
- bustime = usb_check_bandwidth(urb->dev, urb);
- if (bustime < 0)
- ret = bustime;
- else {
-- ret = uhci_submit_interrupt(uhci, urb, eurb);
-- if (ret == -EINPROGRESS)
-+ ret = uhci_submit_interrupt(uhci, urb, qh);
-+ if (ret == 0)
- usb_claim_bandwidth(urb->dev, urb, bustime, 0);
- }
- } else { /* inherit from parent */
-- urb->bandwidth = eurb->bandwidth;
-- ret = uhci_submit_interrupt(uhci, urb, eurb);
-+ struct urb_priv *eurbp;
-+
-+ eurbp = list_entry(qh->queue.prev, struct urb_priv,
-+ node);
-+ urb->bandwidth = eurbp->urb->bandwidth;
-+ ret = uhci_submit_interrupt(uhci, urb, qh);
- }
- break;
-- case PIPE_BULK:
-- ret = uhci_submit_bulk(uhci, urb, eurb);
-- break;
- case PIPE_ISOCHRONOUS:
- bustime = usb_check_bandwidth(urb->dev, urb);
- if (bustime < 0) {
-@@ -1220,22 +1151,59 @@ static int uhci_urb_enqueue(struct usb_h
- break;
- }
-
-- ret = uhci_submit_isochronous(uhci, urb);
-- if (ret == -EINPROGRESS)
-+ ret = uhci_submit_isochronous(uhci, urb, qh);
-+ if (ret == 0)
- usb_claim_bandwidth(urb->dev, urb, bustime, 1);
- break;
- }
-+ if (ret != 0)
-+ goto err_submit_failed;
-
-- if (ret != -EINPROGRESS) {
-- /* Submit failed, so delete it from the urb_list */
-- struct urb_priv *urbp = urb->hcpriv;
-+ /* Add this URB to the QH */
-+ urbp->qh = qh;
-+ list_add_tail(&urbp->node, &qh->queue);
-+ list_add_tail(&urbp->urb_list, &uhci->urb_list);
-
-- list_del_init(&urbp->urb_list);
-- uhci_destroy_urb_priv(uhci, urb);
-- } else
-- ret = 0;
-+ /* If the new URB is the first and only one on this QH then either
-+ * the QH is new and idle or else it's unlinked and waiting to
-+ * become idle, so we can activate it right away. */
-+ if (qh->queue.next == &urbp->node)
-+ uhci_activate_qh(uhci, qh);
-+
-+ /* If the QH is already active, we have a race with the hardware.
-+ * This won't get fixed until dummy TDs are added. */
-+ else if (qh->state == QH_STATE_ACTIVE) {
-+
-+ /* If the URB isn't first on its queue, adjust the link pointer
-+ * of the last TD in the previous URB. */
-+ if (urbp->node.prev != &urbp->qh->queue) {
-+ struct urb_priv *purbp = list_entry(urbp->node.prev,
-+ struct urb_priv, node);
-+ struct uhci_td *ptd = list_entry(purbp->td_list.prev,
-+ struct uhci_td, list);
-+ struct uhci_td *td = list_entry(urbp->td_list.next,
-+ struct uhci_td, list);
-+
-+ ptd->link = cpu_to_le32(td->dma_handle);
-+
-+ }
-+ if (qh_element(qh) == UHCI_PTR_TERM) {
-+ struct uhci_td *td = list_entry(urbp->td_list.next,
-+ struct uhci_td, list);
-+
-+ qh->element = cpu_to_le32(td->dma_handle);
-+ }
-+ }
-+ goto done;
-+
-+err_submit_failed:
-+ if (qh->state == QH_STATE_IDLE)
-+ uhci_make_qh_idle(uhci, qh); /* Reclaim unused QH */
-
--out:
-+err_no_qh:
-+ uhci_free_urb_priv(uhci, urbp);
-+
-+done:
- spin_unlock_irqrestore(&uhci->lock, flags);
- return ret;
- }
-@@ -1245,119 +1213,115 @@ out:
- */
- static void uhci_transfer_result(struct uhci_hcd *uhci, struct urb *urb)
- {
-- int ret = -EINPROGRESS;
-- struct urb_priv *urbp;
--
-- spin_lock(&urb->lock);
--
-- urbp = (struct urb_priv *)urb->hcpriv;
--
-- if (urb->status != -EINPROGRESS) /* URB already dequeued */
-- goto out;
-+ int status;
-+ int okay_to_giveback = 0;
-+ struct urb_priv *urbp = (struct urb_priv *) urb->hcpriv;
-
- switch (usb_pipetype(urb->pipe)) {
- case PIPE_CONTROL:
-- ret = uhci_result_control(uhci, urb);
-- break;
-- case PIPE_BULK:
-- case PIPE_INTERRUPT:
-- ret = uhci_result_common(uhci, urb);
-+ status = uhci_result_control(uhci, urb);
- break;
- case PIPE_ISOCHRONOUS:
-- ret = uhci_result_isochronous(uhci, urb);
-+ status = uhci_result_isochronous(uhci, urb);
-+ break;
-+ default: /* PIPE_BULK or PIPE_INTERRUPT */
-+ status = uhci_result_common(uhci, urb);
- break;
- }
-
-- if (ret == -EINPROGRESS)
-- goto out;
-- urb->status = ret;
-+ spin_lock(&urb->lock);
-+ if (urb->status == -EINPROGRESS) { /* Not yet dequeued */
-+ if (status != -EINPROGRESS) { /* URB has completed */
-+ urb->status = status;
-+
-+ /* If the URB got a real error (as opposed to
-+ * simply being dequeued), we don't have to
-+ * unlink the QH. Fix this later... */
-+ if (status < 0)
-+ uhci_unlink_qh(uhci, urbp->qh);
-+ else
-+ okay_to_giveback = 1;
-+ }
-+ } else { /* Already dequeued */
-+ if (urbp->qh->state == QH_STATE_UNLINKING &&
-+ uhci->frame_number + uhci->is_stopped !=
-+ urbp->qh->unlink_frame)
-+ okay_to_giveback = 1;
-+ }
-+ spin_unlock(&urb->lock);
-+ if (!okay_to_giveback)
-+ return;
-
- switch (usb_pipetype(urb->pipe)) {
-- case PIPE_CONTROL:
-- case PIPE_BULK:
- case PIPE_ISOCHRONOUS:
- /* Release bandwidth for Interrupt or Isoc. transfers */
- if (urb->bandwidth)
- usb_release_bandwidth(urb->dev, urb, 1);
-- uhci_unlink_generic(uhci, urb);
- break;
- case PIPE_INTERRUPT:
- /* Release bandwidth for Interrupt or Isoc. transfers */
- /* Make sure we don't release if we have a queued URB */
-- if (list_empty(&urbp->queue_list) && urb->bandwidth)
-+ if (list_empty(&urbp->qh->queue) && urb->bandwidth)
- usb_release_bandwidth(urb->dev, urb, 0);
- else
- /* bandwidth was passed on to queued URB, */
- /* so don't let usb_unlink_urb() release it */
- urb->bandwidth = 0;
-- uhci_unlink_generic(uhci, urb);
-+ /* Falls through */
-+ case PIPE_BULK:
-+ if (status < 0)
-+ uhci_fixup_toggles(urb);
-+ break;
-+ default: /* PIPE_CONTROL */
- break;
-- default:
-- dev_info(uhci_dev(uhci), "%s: unknown pipe type %d "
-- "for urb %p\n",
-- __FUNCTION__, usb_pipetype(urb->pipe), urb);
- }
-
-- /* Move it from uhci->urb_list to uhci->complete_list */
-- uhci_moveto_complete(uhci, urbp);
-+ /* Take the URB's TDs off the hardware schedule */
-+ uhci_remove_tds_from_schedule(uhci, urb, status);
-
--out:
-- spin_unlock(&urb->lock);
-+ /* Take the URB off the QH's queue and see if the QH is now unused */
-+ list_del_init(&urbp->node);
-+ if (list_empty(&urbp->qh->queue))
-+ uhci_unlink_qh(uhci, urbp->qh);
-+
-+ uhci_dec_fsbr(uhci, urb); /* Safe since it checks */
-+
-+ /* Queue it for giving back */
-+ list_move_tail(&urbp->urb_list, &uhci->complete_list);
- }
-
--static void uhci_unlink_generic(struct uhci_hcd *uhci, struct urb *urb)
-+/*
-+ * Check out the QHs waiting to be fully unlinked
-+ */
-+static void uhci_scan_unlinking_qhs(struct uhci_hcd *uhci)
- {
-- struct list_head *head;
-- struct uhci_td *td;
-- struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv;
-- int prevactive = 0;
-+ struct uhci_qh *qh, *tmp;
-
-- uhci_dec_fsbr(uhci, urb); /* Safe since it checks */
-+ list_for_each_entry_safe(qh, tmp, &uhci->skel_unlink_qh->node, node) {
-
-- /*
-- * Now we need to find out what the last successful toggle was
-- * so we can update the local data toggle for the next transfer
-- *
-- * There are 2 ways the last successful completed TD is found:
-- *
-- * 1) The TD is NOT active and the actual length < expected length
-- * 2) The TD is NOT active and it's the last TD in the chain
-- *
-- * and a third way the first uncompleted TD is found:
-- *
-- * 3) The TD is active and the previous TD is NOT active
-- *
-- * Control and Isochronous ignore the toggle, so this is safe
-- * for all types
-- *
-- * FIXME: The toggle fixups won't be 100% reliable until we
-- * change over to using a single queue for each endpoint and
-- * stop the queue before unlinking.
-- */
-- head = &urbp->td_list;
-- list_for_each_entry(td, head, list) {
-- unsigned int ctrlstat = td_status(td);
-+ /* If the queue is empty and the QH is fully unlinked then
-+ * it can become IDLE. */
-+ if (list_empty(&qh->queue)) {
-+ if (uhci->frame_number + uhci->is_stopped !=
-+ qh->unlink_frame)
-+ uhci_make_qh_idle(uhci, qh);
-
-- if (!(ctrlstat & TD_CTRL_ACTIVE) &&
-- (uhci_actual_length(ctrlstat) <
-- uhci_expected_length(td_token(td)) ||
-- td->list.next == head))
-- usb_settoggle(urb->dev, uhci_endpoint(td_token(td)),
-- uhci_packetout(td_token(td)),
-- uhci_toggle(td_token(td)) ^ 1);
-- else if ((ctrlstat & TD_CTRL_ACTIVE) && !prevactive)
-- usb_settoggle(urb->dev, uhci_endpoint(td_token(td)),
-- uhci_packetout(td_token(td)),
-- uhci_toggle(td_token(td)));
-+ /* If none of the QH's URBs have been dequeued then the QH
-+ * should be re-activated. */
-+ } else {
-+ struct urb_priv *urbp;
-+ int any_dequeued = 0;
-
-- prevactive = ctrlstat & TD_CTRL_ACTIVE;
-+ list_for_each_entry(urbp, &qh->queue, node) {
-+ if (urbp->urb->status != -EINPROGRESS) {
-+ any_dequeued = 1;
-+ break;
-+ }
-+ }
-+ if (!any_dequeued)
-+ uhci_activate_qh(uhci, qh);
-+ }
- }
--
-- uhci_delete_queued_urb(uhci, urb);
--
-- /* The interrupt loop will reclaim the QHs */
-- uhci_remove_qh(uhci, urbp->qh);
-- urbp->qh = NULL;
- }
-
- static int uhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb)
-@@ -1370,22 +1334,11 @@ static int uhci_urb_dequeue(struct usb_h
- urbp = urb->hcpriv;
- if (!urbp) /* URB was never linked! */
- goto done;
-- list_del_init(&urbp->urb_list);
-
-+ /* Remove Isochronous TDs from the frame list ASAP */
- if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS)
-- unlink_isochronous_tds(uhci, urb);
-- uhci_unlink_generic(uhci, urb);
--
-- uhci_get_current_frame_number(uhci);
-- if (uhci->frame_number + uhci->is_stopped != uhci->urb_remove_age) {
-- uhci_remove_pending_urbps(uhci);
-- uhci->urb_remove_age = uhci->frame_number;
-- }
--
-- /* If we're the first, set the next interrupt bit */
-- if (list_empty(&uhci->urb_remove_list))
-- uhci_set_next_interrupt(uhci);
-- list_add_tail(&urbp->urb_list, &uhci->urb_remove_list);
-+ uhci_unlink_isochronous_tds(uhci, urb);
-+ uhci_unlink_qh(uhci, urbp->qh);
-
- done:
- spin_unlock_irqrestore(&uhci->lock, flags);
-@@ -1426,17 +1379,6 @@ static int uhci_fsbr_timeout(struct uhci
- return 0;
- }
-
--static void uhci_free_pending_qhs(struct uhci_hcd *uhci)
--{
-- struct uhci_qh *qh, *tmp;
--
-- list_for_each_entry_safe(qh, tmp, &uhci->qh_remove_list, remove_list) {
-- list_del_init(&qh->remove_list);
--
-- uhci_free_qh(uhci, qh);
-- }
--}
--
- static void uhci_free_pending_tds(struct uhci_hcd *uhci)
- {
- struct uhci_td *td, *tmp;
-@@ -1455,7 +1397,7 @@ __acquires(uhci->lock)
- {
- struct uhci_hcd *uhci = hcd_to_uhci(hcd);
-
-- uhci_destroy_urb_priv(uhci, urb);
-+ uhci_free_urb_priv(uhci, (struct urb_priv *) (urb->hcpriv));
-
- spin_unlock(&uhci->lock);
- usb_hcd_giveback_urb(hcd, urb, regs);
-@@ -1474,13 +1416,6 @@ static void uhci_finish_completion(struc
- }
- }
-
--static void uhci_remove_pending_urbps(struct uhci_hcd *uhci)
--{
--
-- /* Splice the urb_remove_list onto the end of the complete_list */
-- list_splice_init(&uhci->urb_remove_list, uhci->complete_list.prev);
--}
--
- /* Process events in the schedule, but only in one thread at a time */
- static void uhci_scan_schedule(struct uhci_hcd *uhci, struct pt_regs *regs)
- {
-@@ -1498,12 +1433,8 @@ static void uhci_scan_schedule(struct uh
- uhci_clear_next_interrupt(uhci);
- uhci_get_current_frame_number(uhci);
-
-- if (uhci->frame_number + uhci->is_stopped != uhci->qh_remove_age)
-- uhci_free_pending_qhs(uhci);
- if (uhci->frame_number + uhci->is_stopped != uhci->td_remove_age)
- uhci_free_pending_tds(uhci);
-- if (uhci->frame_number + uhci->is_stopped != uhci->urb_remove_age)
-- uhci_remove_pending_urbps(uhci);
-
- /* Walk the list of pending URBs to see which ones completed
- * (must be _safe because uhci_transfer_result() dequeues URBs) */
-@@ -1516,25 +1447,21 @@ static void uhci_scan_schedule(struct uh
- uhci_finish_completion(uhci, regs);
-
- /* If the controller is stopped, we can finish these off right now */
-- if (uhci->is_stopped) {
-- uhci_free_pending_qhs(uhci);
-+ if (uhci->is_stopped)
- uhci_free_pending_tds(uhci);
-- uhci_remove_pending_urbps(uhci);
-- }
-
- if (uhci->need_rescan)
- goto rescan;
- uhci->scan_in_progress = 0;
-
-- if (list_empty(&uhci->urb_remove_list) &&
-- list_empty(&uhci->td_remove_list) &&
-- list_empty(&uhci->qh_remove_list))
-+ /* Check out the QHs waiting for unlinking */
-+ uhci_scan_unlinking_qhs(uhci);
-+
-+ if (list_empty(&uhci->td_remove_list) &&
-+ list_empty(&uhci->skel_unlink_qh->node))
- uhci_clear_next_interrupt(uhci);
- else
- uhci_set_next_interrupt(uhci);
--
-- /* Wake up anyone waiting for an URB to complete */
-- wake_up_all(&uhci->waitqh);
- }
-
- static void check_fsbr(struct uhci_hcd *uhci)
diff --git a/usb/usb-add-support-for-at91-gadget.patch b/usb/usb-add-support-for-at91-gadget.patch
deleted file mode 100644
index 4ae77f61f6d4a..0000000000000
--- a/usb/usb-add-support-for-at91-gadget.patch
+++ /dev/null
@@ -1,2022 +0,0 @@
-From david-b@pacbell.net Sun Jan 22 11:29:00 2006
-From: David Brownell <david-b@pacbell.net>
-To: Greg KH <greg@kroah.com>
-Subject: USB: add support for AT91 gadget
-Date: Sun, 22 Jan 2006 10:32:37 -0800
-Cc: Andrew Victor <andrew@sanpeople.com>
-Message-Id: <200601221032.37299.david-b@pacbell.net>
-
-
-This adds support for the USB peripheral controller on AT91
-(rm9200, eventually also sam9261 or uClinux) platforms.
-
-More SOC support for Linux-USB ... an uncomplicated pure PIO driver.
-It'd be worth using this as a model, if you're starting a driver
-for some other peripheral controller.
-
-Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-
----
- drivers/usb/gadget/Kconfig | 17
- drivers/usb/gadget/Makefile | 1
- drivers/usb/gadget/at91_udc.c | 1773 ++++++++++++++++++++++++++++++++++++++++++
- drivers/usb/gadget/at91_udc.h | 181 ++++
- 4 files changed, 1972 insertions(+)
-
---- gregkh-2.6.orig/drivers/usb/gadget/Kconfig
-+++ gregkh-2.6/drivers/usb/gadget/Kconfig
-@@ -187,6 +187,23 @@ config USB_OTG
-
- Select this only if your OMAP board has a Mini-AB connector.
-
-+config USB_GADGET_AT91
-+ boolean "AT91 USB Device Port"
-+ depends on ARCH_AT91RM9200
-+ select USB_GADGET_SELECTED
-+ help
-+ Many Atmel AT91 processors (such as the AT91RM2000) have a
-+ full speed USB Device Port with support for five configurable
-+ endpoints (plus endpoint zero).
-+
-+ Say "y" to link the driver statically, or "m" to build a
-+ dynamically linked module called "at91_udc" and force all
-+ gadget drivers to also be dynamically linked.
-+
-+config USB_AT91
-+ tristate
-+ depends on USB_GADGET_AT91
-+ default USB_GADGET
-
- config USB_GADGET_DUMMY_HCD
- boolean "Dummy HCD (DEVELOPMENT)"
---- gregkh-2.6.orig/drivers/usb/gadget/Makefile
-+++ gregkh-2.6/drivers/usb/gadget/Makefile
-@@ -7,6 +7,7 @@ obj-$(CONFIG_USB_PXA2XX) += pxa2xx_udc.o
- obj-$(CONFIG_USB_GOKU) += goku_udc.o
- obj-$(CONFIG_USB_OMAP) += omap_udc.o
- obj-$(CONFIG_USB_LH7A40X) += lh7a40x_udc.o
-+obj-$(CONFIG_USB_AT91) += at91_udc.o
-
- #
- # USB gadget drivers
---- /dev/null
-+++ gregkh-2.6/drivers/usb/gadget/at91_udc.c
-@@ -0,0 +1,1773 @@
-+/*
-+ * at91_udc -- driver for at91-series USB peripheral controller
-+ *
-+ * Copyright (C) 2004 by Thomas Rathbone
-+ * Copyright (C) 2005 by HP Labs
-+ * Copyright (C) 2005 by David Brownell
-+ *
-+ * 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., 59 Temple Place - Suite 330,
-+ * Boston, MA 02111-1307, USA.
-+ */
-+
-+#undef DEBUG
-+#undef VERBOSE
-+#undef PACKET_TRACE
-+
-+#include <linux/config.h>
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/platform_device.h>
-+#include <linux/delay.h>
-+#include <linux/ioport.h>
-+#include <linux/sched.h>
-+#include <linux/slab.h>
-+#include <linux/smp_lock.h>
-+#include <linux/errno.h>
-+#include <linux/init.h>
-+#include <linux/list.h>
-+#include <linux/interrupt.h>
-+#include <linux/proc_fs.h>
-+#include <linux/clk.h>
-+#include <linux/usb_ch9.h>
-+#include <linux/usb_gadget.h>
-+
-+#include <asm/byteorder.h>
-+#include <asm/io.h>
-+#include <asm/irq.h>
-+#include <asm/system.h>
-+#include <asm/mach-types.h>
-+
-+#include <asm/arch/hardware.h>
-+#include <asm/arch/gpio.h>
-+#include <asm/arch/board.h>
-+
-+#include "at91_udc.h"
-+
-+
-+/*
-+ * This controller is simple and PIO-only. It's used in many AT91-series
-+ * ARMv4T controllers, including the at91rm9200 (arm920T, with MMU),
-+ * at91sam9261 (arm926ejs, with MMU), and several no-mmu versions.
-+ *
-+ * This driver expects the board has been wired with two GPIOs suppporting
-+ * a VBUS sensing IRQ, and a D+ pullup. (They may be omitted, but the
-+ * testing hasn't covered such cases.) The pullup is most important; it
-+ * provides software control over whether the host enumerates the device.
-+ * The VBUS sensing helps during enumeration, and allows both USB clocks
-+ * (and the transceiver) to stay gated off until they're necessary, saving
-+ * power. During USB suspend, the 48 MHz clock is gated off.
-+ */
-+
-+#define DRIVER_VERSION "8 March 2005"
-+
-+static const char driver_name [] = "at91_udc";
-+static const char ep0name[] = "ep0";
-+
-+/*-------------------------------------------------------------------------*/
-+
-+/*
-+ * Read from a UDP register.
-+ */
-+static inline unsigned long at91_udp_read(unsigned int reg)
-+{
-+ void __iomem *udp_base = (void __iomem *)AT91_VA_BASE_UDP;
-+
-+ return __raw_readl(udp_base + reg);
-+}
-+
-+/*
-+ * Write to a UDP register.
-+ */
-+static inline void at91_udp_write(unsigned int reg, unsigned long value)
-+{
-+ void __iomem *udp_base = (void __iomem *)AT91_VA_BASE_UDP;
-+
-+ __raw_writel(value, udp_base + reg);
-+}
-+
-+/*-------------------------------------------------------------------------*/
-+
-+#ifdef CONFIG_USB_GADGET_DEBUG_FILES
-+
-+#include <linux/seq_file.h>
-+
-+static const char debug_filename[] = "driver/udc";
-+
-+#define FOURBITS "%s%s%s%s"
-+#define EIGHTBITS FOURBITS FOURBITS
-+
-+static void proc_ep_show(struct seq_file *s, struct at91_ep *ep)
-+{
-+ static char *types[] = {
-+ "control", "out-iso", "out-bulk", "out-int",
-+ "BOGUS", "in-iso", "in-bulk", "in-int"};
-+
-+ u32 csr;
-+ struct at91_request *req;
-+ unsigned long flags;
-+
-+ local_irq_save(flags);
-+
-+ csr = __raw_readl(ep->creg);
-+
-+ /* NOTE: not collecting per-endpoint irq statistics... */
-+
-+ seq_printf(s, "\n");
-+ seq_printf(s, "%s, maxpacket %d %s%s %s%s\n",
-+ ep->ep.name, ep->ep.maxpacket,
-+ ep->is_in ? "in" : "out",
-+ ep->is_iso ? " iso" : "",
-+ ep->is_pingpong
-+ ? (ep->fifo_bank ? "pong" : "ping")
-+ : "",
-+ ep->stopped ? " stopped" : "");
-+ seq_printf(s, "csr %08x rxbytes=%d %s %s %s" EIGHTBITS "\n",
-+ csr,
-+ (csr & 0x07ff0000) >> 16,
-+ (csr & (1 << 15)) ? "enabled" : "disabled",
-+ (csr & (1 << 11)) ? "DATA1" : "DATA0",
-+ types[(csr & 0x700) >> 8],
-+
-+ /* iff type is control then print current direction */
-+ (!(csr & 0x700))
-+ ? ((csr & (1 << 7)) ? " IN" : " OUT")
-+ : "",
-+ (csr & (1 << 6)) ? " rxdatabk1" : "",
-+ (csr & (1 << 5)) ? " forcestall" : "",
-+ (csr & (1 << 4)) ? " txpktrdy" : "",
-+
-+ (csr & (1 << 3)) ? " stallsent" : "",
-+ (csr & (1 << 2)) ? " rxsetup" : "",
-+ (csr & (1 << 1)) ? " rxdatabk0" : "",
-+ (csr & (1 << 0)) ? " txcomp" : "");
-+ if (list_empty (&ep->queue))
-+ seq_printf(s, "\t(queue empty)\n");
-+
-+ else list_for_each_entry (req, &ep->queue, queue) {
-+ unsigned length = req->req.actual;
-+
-+ seq_printf(s, "\treq %p len %d/%d buf %p\n",
-+ &req->req, length,
-+ req->req.length, req->req.buf);
-+ }
-+ local_irq_restore(flags);
-+}
-+
-+static void proc_irq_show(struct seq_file *s, const char *label, u32 mask)
-+{
-+ int i;
-+
-+ seq_printf(s, "%s %04x:%s%s" FOURBITS, label, mask,
-+ (mask & (1 << 13)) ? " wakeup" : "",
-+ (mask & (1 << 12)) ? " endbusres" : "",
-+
-+ (mask & (1 << 11)) ? " sofint" : "",
-+ (mask & (1 << 10)) ? " extrsm" : "",
-+ (mask & (1 << 9)) ? " rxrsm" : "",
-+ (mask & (1 << 8)) ? " rxsusp" : "");
-+ for (i = 0; i < 8; i++) {
-+ if (mask & (1 << i))
-+ seq_printf(s, " ep%d", i);
-+ }
-+ seq_printf(s, "\n");
-+}
-+
-+static int proc_udc_show(struct seq_file *s, void *unused)
-+{
-+ struct at91_udc *udc = s->private;
-+ struct at91_ep *ep;
-+ u32 tmp;
-+
-+ seq_printf(s, "%s: version %s\n", driver_name, DRIVER_VERSION);
-+
-+ seq_printf(s, "vbus %s, pullup %s, %s powered%s, gadget %s\n\n",
-+ udc->vbus ? "present" : "off",
-+ udc->enabled
-+ ? (udc->vbus ? "active" : "enabled")
-+ : "disabled",
-+ udc->selfpowered ? "self" : "VBUS",
-+ udc->suspended ? ", suspended" : "",
-+ udc->driver ? udc->driver->driver.name : "(none)");
-+
-+ /* don't access registers when interface isn't clocked */
-+ if (!udc->clocked) {
-+ seq_printf(s, "(not clocked)\n");
-+ return 0;
-+ }
-+
-+ tmp = at91_udp_read(AT91_UDP_FRM_NUM);
-+ seq_printf(s, "frame %05x:%s%s frame=%d\n", tmp,
-+ (tmp & AT91_UDP_FRM_OK) ? " ok" : "",
-+ (tmp & AT91_UDP_FRM_ERR) ? " err" : "",
-+ (tmp & AT91_UDP_NUM));
-+
-+ tmp = at91_udp_read(AT91_UDP_GLB_STAT);
-+ seq_printf(s, "glbstate %02x:%s" FOURBITS "\n", tmp,
-+ (tmp & AT91_UDP_RMWUPE) ? " rmwupe" : "",
-+ (tmp & AT91_UDP_RSMINPR) ? " rsminpr" : "",
-+ (tmp & AT91_UDP_ESR) ? " esr" : "",
-+ (tmp & AT91_UDP_CONFG) ? " confg" : "",
-+ (tmp & AT91_UDP_FADDEN) ? " fadden" : "");
-+
-+ tmp = at91_udp_read(AT91_UDP_FADDR);
-+ seq_printf(s, "faddr %03x:%s fadd=%d\n", tmp,
-+ (tmp & AT91_UDP_FEN) ? " fen" : "",
-+ (tmp & AT91_UDP_FADD));
-+
-+ proc_irq_show(s, "imr ", at91_udp_read(AT91_UDP_IMR));
-+ proc_irq_show(s, "isr ", at91_udp_read(AT91_UDP_ISR));
-+
-+ if (udc->enabled && udc->vbus) {
-+ proc_ep_show(s, &udc->ep[0]);
-+ list_for_each_entry (ep, &udc->gadget.ep_list, ep.ep_list) {
-+ if (ep->desc)
-+ proc_ep_show(s, ep);
-+ }
-+ }
-+ return 0;
-+}
-+
-+static int proc_udc_open(struct inode *inode, struct file *file)
-+{
-+ return single_open(file, proc_udc_show, PDE(inode)->data);
-+}
-+
-+static struct file_operations proc_ops = {
-+ .open = proc_udc_open,
-+ .read = seq_read,
-+ .llseek = seq_lseek,
-+ .release = single_release,
-+};
-+
-+static void create_debug_file(struct at91_udc *udc)
-+{
-+ struct proc_dir_entry *pde;
-+
-+ pde = create_proc_entry (debug_filename, 0, NULL);
-+ udc->pde = pde;
-+ if (pde == NULL)
-+ return;
-+
-+ pde->proc_fops = &proc_ops;
-+ pde->data = udc;
-+}
-+
-+static void remove_debug_file(struct at91_udc *udc)
-+{
-+ if (udc->pde)
-+ remove_proc_entry(debug_filename, NULL);
-+}
-+
-+#else
-+
-+static inline void create_debug_file(struct at91_udc *udc) {}
-+static inline void remove_debug_file(struct at91_udc *udc) {}
-+
-+#endif
-+
-+
-+/*-------------------------------------------------------------------------*/
-+
-+static void done(struct at91_ep *ep, struct at91_request *req, int status)
-+{
-+ unsigned stopped = ep->stopped;
-+
-+ list_del_init(&req->queue);
-+ if (req->req.status == -EINPROGRESS)
-+ req->req.status = status;
-+ else
-+ status = req->req.status;
-+ if (status && status != -ESHUTDOWN)
-+ VDBG("%s done %p, status %d\n", ep->ep.name, req, status);
-+
-+ ep->stopped = 1;
-+ req->req.complete(&ep->ep, &req->req);
-+ ep->stopped = stopped;
-+
-+ /* ep0 is always ready; other endpoints need a non-empty queue */
-+ if (list_empty(&ep->queue) && ep->int_mask != (1 << 0))
-+ at91_udp_write(AT91_UDP_IDR, ep->int_mask);
-+}
-+
-+/*-------------------------------------------------------------------------*/
-+
-+/* bits indicating OUT fifo has data ready */
-+#define RX_DATA_READY (AT91_UDP_RX_DATA_BK0 | AT91_UDP_RX_DATA_BK1)
-+
-+/*
-+ * Endpoint FIFO CSR bits have a mix of bits, making it unsafe to just write
-+ * back most of the value you just read (because of side effects, including
-+ * bits that may change after reading and before writing).
-+ *
-+ * Except when changing a specific bit, always write values which:
-+ * - clear SET_FX bits (setting them could change something)
-+ * - set CLR_FX bits (clearing them could change something)
-+ *
-+ * There are also state bits like FORCESTALL, EPEDS, DIR, and EPTYPE
-+ * that shouldn't normally be changed.
-+ */
-+#define SET_FX (AT91_UDP_TXPKTRDY)
-+#define CLR_FX (RX_DATA_READY | AT91_UDP_RXSETUP | AT91_UDP_STALLSENT | AT91_UDP_TXCOMP)
-+
-+/* pull OUT packet data from the endpoint's fifo */
-+static int read_fifo (struct at91_ep *ep, struct at91_request *req)
-+{
-+ u32 __iomem *creg = ep->creg;
-+ u8 __iomem *dreg = ep->creg + (AT91_UDP_FDR(0) - AT91_UDP_CSR(0));
-+ u32 csr;
-+ u8 *buf;
-+ unsigned int count, bufferspace, is_done;
-+
-+ buf = req->req.buf + req->req.actual;
-+ bufferspace = req->req.length - req->req.actual;
-+
-+ /*
-+ * there might be nothing to read if ep_queue() calls us,
-+ * or if we already emptied both pingpong buffers
-+ */
-+rescan:
-+ csr = __raw_readl(creg);
-+ if ((csr & RX_DATA_READY) == 0)
-+ return 0;
-+
-+ count = (csr & AT91_UDP_RXBYTECNT) >> 16;
-+ if (count > ep->ep.maxpacket)
-+ count = ep->ep.maxpacket;
-+ if (count > bufferspace) {
-+ DBG("%s buffer overflow\n", ep->ep.name);
-+ req->req.status = -EOVERFLOW;
-+ count = bufferspace;
-+ }
-+ __raw_readsb(dreg, buf, count);
-+
-+ /* release and swap pingpong mem bank */
-+ csr |= CLR_FX;
-+ if (ep->is_pingpong) {
-+ if (ep->fifo_bank == 0) {
-+ csr &= ~(SET_FX | AT91_UDP_RX_DATA_BK0);
-+ ep->fifo_bank = 1;
-+ } else {
-+ csr &= ~(SET_FX | AT91_UDP_RX_DATA_BK1);
-+ ep->fifo_bank = 0;
-+ }
-+ } else
-+ csr &= ~(SET_FX | AT91_UDP_RX_DATA_BK0);
-+ __raw_writel(csr, creg);
-+
-+ req->req.actual += count;
-+ is_done = (count < ep->ep.maxpacket);
-+ if (count == bufferspace)
-+ is_done = 1;
-+
-+ PACKET("%s %p out/%d%s\n", ep->ep.name, &req->req, count,
-+ is_done ? " (done)" : "");
-+
-+ /*
-+ * avoid extra trips through IRQ logic for packets already in
-+ * the fifo ... maybe preventing an extra (expensive) OUT-NAK
-+ */
-+ if (is_done)
-+ done(ep, req, 0);
-+ else if (ep->is_pingpong) {
-+ bufferspace -= count;
-+ buf += count;
-+ goto rescan;
-+ }
-+
-+ return is_done;
-+}
-+
-+/* load fifo for an IN packet */
-+static int write_fifo(struct at91_ep *ep, struct at91_request *req)
-+{
-+ u32 __iomem *creg = ep->creg;
-+ u32 csr = __raw_readl(creg);
-+ u8 __iomem *dreg = ep->creg + (AT91_UDP_FDR(0) - AT91_UDP_CSR(0));
-+ unsigned total, count, is_last;
-+
-+ /*
-+ * TODO: allow for writing two packets to the fifo ... that'll
-+ * reduce the amount of IN-NAKing, but probably won't affect
-+ * throughput much. (Unlike preventing OUT-NAKing!)
-+ */
-+
-+ /*
-+ * If ep_queue() calls us, the queue is empty and possibly in
-+ * odd states like TXCOMP not yet cleared (we do it, saving at
-+ * least one IRQ) or the fifo not yet being free. Those aren't
-+ * issues normally (IRQ handler fast path).
-+ */
-+ if (unlikely(csr & (AT91_UDP_TXCOMP | AT91_UDP_TXPKTRDY))) {
-+ if (csr & AT91_UDP_TXCOMP) {
-+ csr |= CLR_FX;
-+ csr &= ~(SET_FX | AT91_UDP_TXCOMP);
-+ __raw_writel(csr, creg);
-+ csr = __raw_readl(creg);
-+ }
-+ if (csr & AT91_UDP_TXPKTRDY)
-+ return 0;
-+ }
-+
-+ total = req->req.length - req->req.actual;
-+ if (ep->ep.maxpacket < total) {
-+ count = ep->ep.maxpacket;
-+ is_last = 0;
-+ } else {
-+ count = total;
-+ is_last = (count < ep->ep.maxpacket) || !req->req.zero;
-+ }
-+
-+ /*
-+ * Write the packet, maybe it's a ZLP.
-+ *
-+ * NOTE: incrementing req->actual before we receive the ACK means
-+ * gadget driver IN bytecounts can be wrong in fault cases. That's
-+ * fixable with PIO drivers like this one (save "count" here, and
-+ * do the increment later on TX irq), but not for most DMA hardware.
-+ *
-+ * So all gadget drivers must accept that potential error. Some
-+ * hardware supports precise fifo status reporting, letting them
-+ * recover when the actual bytecount matters (e.g. for USB Test
-+ * and Measurement Class devices).
-+ */
-+ __raw_writesb(dreg, req->req.buf + req->req.actual, count);
-+ csr &= ~SET_FX;
-+ csr |= CLR_FX | AT91_UDP_TXPKTRDY;
-+ __raw_writel(csr, creg);
-+ req->req.actual += count;
-+
-+ PACKET("%s %p in/%d%s\n", ep->ep.name, &req->req, count,
-+ is_last ? " (done)" : "");
-+ if (is_last)
-+ done(ep, req, 0);
-+ return is_last;
-+}
-+
-+static void nuke(struct at91_ep *ep, int status)
-+{
-+ struct at91_request *req;
-+
-+ // terminer chaque requete dans la queue
-+ ep->stopped = 1;
-+ if (list_empty(&ep->queue))
-+ return;
-+
-+ VDBG("%s %s\n", __FUNCTION__, ep->ep.name);
-+ while (!list_empty(&ep->queue)) {
-+ req = list_entry(ep->queue.next, struct at91_request, queue);
-+ done(ep, req, status);
-+ }
-+}
-+
-+/*-------------------------------------------------------------------------*/
-+
-+static int at91_ep_enable(struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc)
-+{
-+ struct at91_ep *ep = container_of(_ep, struct at91_ep, ep);
-+ struct at91_udc *dev = ep->udc;
-+ u16 maxpacket;
-+ u32 tmp;
-+ unsigned long flags;
-+
-+ if (!_ep || !ep
-+ || !desc || ep->desc
-+ || _ep->name == ep0name
-+ || desc->bDescriptorType != USB_DT_ENDPOINT
-+ || (maxpacket = le16_to_cpu(desc->wMaxPacketSize)) == 0
-+ || maxpacket > ep->maxpacket) {
-+ DBG("bad ep or descriptor\n");
-+ return -EINVAL;
-+ }
-+
-+ if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN) {
-+ DBG("bogus device state\n");
-+ return -ESHUTDOWN;
-+ }
-+
-+ tmp = desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
-+ switch (tmp) {
-+ case USB_ENDPOINT_XFER_CONTROL:
-+ DBG("only one control endpoint\n");
-+ return -EINVAL;
-+ case USB_ENDPOINT_XFER_INT:
-+ if (maxpacket > 64)
-+ goto bogus_max;
-+ break;
-+ case USB_ENDPOINT_XFER_BULK:
-+ switch (maxpacket) {
-+ case 8:
-+ case 16:
-+ case 32:
-+ case 64:
-+ goto ok;
-+ }
-+bogus_max:
-+ DBG("bogus maxpacket %d\n", maxpacket);
-+ return -EINVAL;
-+ case USB_ENDPOINT_XFER_ISOC:
-+ if (!ep->is_pingpong) {
-+ DBG("iso requires double buffering\n");
-+ return -EINVAL;
-+ }
-+ break;
-+ }
-+
-+ok:
-+ local_irq_save(flags);
-+
-+ /* initialize endpoint to match this descriptor */
-+ ep->is_in = (desc->bEndpointAddress & USB_DIR_IN) != 0;
-+ ep->is_iso = (tmp == USB_ENDPOINT_XFER_ISOC);
-+ ep->stopped = 0;
-+ if (ep->is_in)
-+ tmp |= 0x04;
-+ tmp <<= 8;
-+ tmp |= AT91_UDP_EPEDS;
-+ __raw_writel(tmp, ep->creg);
-+
-+ ep->desc = desc;
-+ ep->ep.maxpacket = maxpacket;
-+
-+ /*
-+ * reset/init endpoint fifo. NOTE: leaves fifo_bank alone,
-+ * since endpoint resets don't reset hw pingpong state.
-+ */
-+ at91_udp_write(AT91_UDP_RST_EP, ep->int_mask);
-+ at91_udp_write(AT91_UDP_RST_EP, 0);
-+
-+ local_irq_restore(flags);
-+ return 0;
-+}
-+
-+static int at91_ep_disable (struct usb_ep * _ep)
-+{
-+ struct at91_ep *ep = container_of(_ep, struct at91_ep, ep);
-+ unsigned long flags;
-+
-+ if (ep == &ep->udc->ep[0])
-+ return -EINVAL;
-+
-+ local_irq_save(flags);
-+
-+ nuke(ep, -ESHUTDOWN);
-+
-+ /* restore the endpoint's pristine config */
-+ ep->desc = NULL;
-+ ep->ep.maxpacket = ep->maxpacket;
-+
-+ /* reset fifos and endpoint */
-+ if (ep->udc->clocked) {
-+ at91_udp_write(AT91_UDP_RST_EP, ep->int_mask);
-+ at91_udp_write(AT91_UDP_RST_EP, 0);
-+ __raw_writel(0, ep->creg);
-+ }
-+
-+ local_irq_restore(flags);
-+ return 0;
-+}
-+
-+/*
-+ * this is a PIO-only driver, so there's nothing
-+ * interesting for request or buffer allocation.
-+ */
-+
-+static struct usb_request *at91_ep_alloc_request (struct usb_ep *_ep, unsigned int gfp_flags)
-+{
-+ struct at91_request *req;
-+
-+ req = kcalloc(1, sizeof (struct at91_request), SLAB_KERNEL);
-+ if (!req)
-+ return NULL;
-+
-+ INIT_LIST_HEAD(&req->queue);
-+ return &req->req;
-+}
-+
-+static void at91_ep_free_request(struct usb_ep *_ep, struct usb_request *_req)
-+{
-+ struct at91_request *req;
-+
-+ req = container_of(_req, struct at91_request, req);
-+ BUG_ON(!list_empty(&req->queue));
-+ kfree(req);
-+}
-+
-+static void *at91_ep_alloc_buffer(
-+ struct usb_ep *_ep,
-+ unsigned bytes,
-+ dma_addr_t *dma,
-+ gfp_t gfp_flags)
-+{
-+ *dma = ~0;
-+ return kmalloc(bytes, gfp_flags);
-+}
-+
-+static void at91_ep_free_buffer(
-+ struct usb_ep *ep,
-+ void *buf,
-+ dma_addr_t dma,
-+ unsigned bytes)
-+{
-+ kfree(buf);
-+}
-+
-+static int at91_ep_queue(struct usb_ep *_ep,
-+ struct usb_request *_req, gfp_t gfp_flags)
-+{
-+ struct at91_request *req;
-+ struct at91_ep *ep;
-+ struct at91_udc *dev;
-+ int status;
-+ unsigned long flags;
-+
-+ req = container_of(_req, struct at91_request, req);
-+ ep = container_of(_ep, struct at91_ep, ep);
-+
-+ if (!_req || !_req->complete
-+ || !_req->buf || !list_empty(&req->queue)) {
-+ DBG("invalid request\n");
-+ return -EINVAL;
-+ }
-+
-+ if (!_ep || (!ep->desc && ep->ep.name != ep0name)) {
-+ DBG("invalid ep\n");
-+ return -EINVAL;
-+ }
-+
-+ dev = ep->udc;
-+
-+ if (!dev || !dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN) {
-+ DBG("invalid device\n");
-+ return -EINVAL;
-+ }
-+
-+ _req->status = -EINPROGRESS;
-+ _req->actual = 0;
-+
-+ local_irq_save(flags);
-+
-+ /* try to kickstart any empty and idle queue */
-+ if (list_empty(&ep->queue) && !ep->stopped) {
-+ int is_ep0;
-+
-+ /*
-+ * If this control request has a non-empty DATA stage, this
-+ * will start that stage. It works just like a non-control
-+ * request (until the status stage starts, maybe early).
-+ *
-+ * If the data stage is empty, then this starts a successful
-+ * IN/STATUS stage. (Unsuccessful ones use set_halt.)
-+ */
-+ is_ep0 = (ep->ep.name == ep0name);
-+ if (is_ep0) {
-+ u32 tmp;
-+
-+ if (!dev->req_pending) {
-+ status = -EINVAL;
-+ goto done;
-+ }
-+
-+ /*
-+ * defer changing CONFG until after the gadget driver
-+ * reconfigures the endpoints.
-+ */
-+ if (dev->wait_for_config_ack) {
-+ tmp = at91_udp_read(AT91_UDP_GLB_STAT);
-+ tmp ^= AT91_UDP_CONFG;
-+ VDBG("toggle config\n");
-+ at91_udp_write(AT91_UDP_GLB_STAT, tmp);
-+ }
-+ if (req->req.length == 0) {
-+ep0_in_status:
-+ PACKET("ep0 in/status\n");
-+ status = 0;
-+ tmp = __raw_readl(ep->creg);
-+ tmp &= ~SET_FX;
-+ tmp |= CLR_FX | AT91_UDP_TXPKTRDY;
-+ __raw_writel(tmp, ep->creg);
-+ dev->req_pending = 0;
-+ goto done;
-+ }
-+ }
-+
-+ if (ep->is_in)
-+ status = write_fifo(ep, req);
-+ else {
-+ status = read_fifo(ep, req);
-+
-+ /* IN/STATUS stage is otherwise triggered by irq */
-+ if (status && is_ep0)
-+ goto ep0_in_status;
-+ }
-+ } else
-+ status = 0;
-+
-+ if (req && !status) {
-+ list_add_tail (&req->queue, &ep->queue);
-+ at91_udp_write(AT91_UDP_IER, ep->int_mask);
-+ }
-+done:
-+ local_irq_restore(flags);
-+ return (status < 0) ? status : 0;
-+}
-+
-+static int at91_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req)
-+{
-+ struct at91_ep *ep;
-+ struct at91_request *req;
-+
-+ ep = container_of(_ep, struct at91_ep, ep);
-+ if (!_ep || ep->ep.name == ep0name)
-+ return -EINVAL;
-+
-+ /* make sure it's actually queued on this endpoint */
-+ list_for_each_entry (req, &ep->queue, queue) {
-+ if (&req->req == _req)
-+ break;
-+ }
-+ if (&req->req != _req)
-+ return -EINVAL;
-+
-+ done(ep, req, -ECONNRESET);
-+ return 0;
-+}
-+
-+static int at91_ep_set_halt(struct usb_ep *_ep, int value)
-+{
-+ struct at91_ep *ep = container_of(_ep, struct at91_ep, ep);
-+ u32 __iomem *creg;
-+ u32 csr;
-+ unsigned long flags;
-+ int status = 0;
-+
-+ if (!_ep || ep->is_iso || !ep->udc->clocked)
-+ return -EINVAL;
-+
-+ creg = ep->creg;
-+ local_irq_save(flags);
-+
-+ csr = __raw_readl(creg);
-+
-+ /*
-+ * fail with still-busy IN endpoints, ensuring correct sequencing
-+ * of data tx then stall. note that the fifo rx bytecount isn't
-+ * completely accurate as a tx bytecount.
-+ */
-+ if (ep->is_in && (!list_empty(&ep->queue) || (csr >> 16) != 0))
-+ status = -EAGAIN;
-+ else {
-+ csr |= CLR_FX;
-+ csr &= ~SET_FX;
-+ if (value) {
-+ csr |= AT91_UDP_FORCESTALL;
-+ VDBG("halt %s\n", ep->ep.name);
-+ } else {
-+ at91_udp_write(AT91_UDP_RST_EP, ep->int_mask);
-+ at91_udp_write(AT91_UDP_RST_EP, 0);
-+ csr &= ~AT91_UDP_FORCESTALL;
-+ }
-+ __raw_writel(csr, creg);
-+ }
-+
-+ local_irq_restore(flags);
-+ return status;
-+}
-+
-+static struct usb_ep_ops at91_ep_ops = {
-+ .enable = at91_ep_enable,
-+ .disable = at91_ep_disable,
-+ .alloc_request = at91_ep_alloc_request,
-+ .free_request = at91_ep_free_request,
-+ .alloc_buffer = at91_ep_alloc_buffer,
-+ .free_buffer = at91_ep_free_buffer,
-+ .queue = at91_ep_queue,
-+ .dequeue = at91_ep_dequeue,
-+ .set_halt = at91_ep_set_halt,
-+ // there's only imprecise fifo status reporting
-+};
-+
-+/*-------------------------------------------------------------------------*/
-+
-+static int at91_get_frame(struct usb_gadget *gadget)
-+{
-+ if (!to_udc(gadget)->clocked)
-+ return -EINVAL;
-+ return at91_udp_read(AT91_UDP_FRM_NUM) & AT91_UDP_NUM;
-+}
-+
-+static int at91_wakeup(struct usb_gadget *gadget)
-+{
-+ struct at91_udc *udc = to_udc(gadget);
-+ u32 glbstate;
-+ int status = -EINVAL;
-+ unsigned long flags;
-+
-+ DBG("%s\n", __FUNCTION__ );
-+ local_irq_save(flags);
-+
-+ if (!udc->clocked || !udc->suspended)
-+ goto done;
-+
-+ /* NOTE: some "early versions" handle ESR differently ... */
-+
-+ glbstate = at91_udp_read(AT91_UDP_GLB_STAT);
-+ if (!(glbstate & AT91_UDP_ESR))
-+ goto done;
-+ glbstate |= AT91_UDP_ESR;
-+ at91_udp_write(AT91_UDP_GLB_STAT, glbstate);
-+
-+done:
-+ local_irq_restore(flags);
-+ return status;
-+}
-+
-+/* reinit == restore inital software state */
-+static void udc_reinit(struct at91_udc *udc)
-+{
-+ u32 i;
-+
-+ INIT_LIST_HEAD(&udc->gadget.ep_list);
-+ INIT_LIST_HEAD(&udc->gadget.ep0->ep_list);
-+
-+ for (i = 0; i < NUM_ENDPOINTS; i++) {
-+ struct at91_ep *ep = &udc->ep[i];
-+
-+ if (i != 0)
-+ list_add_tail(&ep->ep.ep_list, &udc->gadget.ep_list);
-+ ep->desc = NULL;
-+ ep->stopped = 0;
-+ ep->fifo_bank = 0;
-+ ep->ep.maxpacket = ep->maxpacket;
-+ // initialiser une queue par endpoint
-+ INIT_LIST_HEAD(&ep->queue);
-+ }
-+}
-+
-+static void stop_activity(struct at91_udc *udc)
-+{
-+ struct usb_gadget_driver *driver = udc->driver;
-+ int i;
-+
-+ if (udc->gadget.speed == USB_SPEED_UNKNOWN)
-+ driver = NULL;
-+ udc->gadget.speed = USB_SPEED_UNKNOWN;
-+
-+ for (i = 0; i < NUM_ENDPOINTS; i++) {
-+ struct at91_ep *ep = &udc->ep[i];
-+ ep->stopped = 1;
-+ nuke(ep, -ESHUTDOWN);
-+ }
-+ if (driver)
-+ driver->disconnect(&udc->gadget);
-+
-+ udc_reinit(udc);
-+}
-+
-+static void clk_on(struct at91_udc *udc)
-+{
-+ if (udc->clocked)
-+ return;
-+ udc->clocked = 1;
-+ clk_enable(udc->iclk);
-+ clk_enable(udc->fclk);
-+}
-+
-+static void clk_off(struct at91_udc *udc)
-+{
-+ if (!udc->clocked)
-+ return;
-+ udc->clocked = 0;
-+ udc->gadget.speed = USB_SPEED_UNKNOWN;
-+ clk_disable(udc->iclk);
-+ clk_disable(udc->fclk);
-+}
-+
-+/*
-+ * activate/deactivate link with host; minimize power usage for
-+ * inactive links by cutting clocks and transceiver power.
-+ */
-+static void pullup(struct at91_udc *udc, int is_on)
-+{
-+ if (!udc->enabled || !udc->vbus)
-+ is_on = 0;
-+ DBG("%sactive\n", is_on ? "" : "in");
-+ if (is_on) {
-+ clk_on(udc);
-+ at91_udp_write(AT91_UDP_TXVC, 0);
-+ at91_set_gpio_value(udc->board.pullup_pin, 1);
-+ } else {
-+ stop_activity(udc);
-+ at91_udp_write(AT91_UDP_TXVC, AT91_UDP_TXVC_TXVDIS);
-+ at91_set_gpio_value(udc->board.pullup_pin, 0);
-+ clk_off(udc);
-+
-+ // REVISIT: with transceiver disabled, will D- float
-+ // so that a host would falsely detect a device?
-+ }
-+}
-+
-+/* vbus is here! turn everything on that's ready */
-+static int at91_vbus_session(struct usb_gadget *gadget, int is_active)
-+{
-+ struct at91_udc *udc = to_udc(gadget);
-+ unsigned long flags;
-+
-+ // VDBG("vbus %s\n", is_active ? "on" : "off");
-+ local_irq_save(flags);
-+ udc->vbus = (is_active != 0);
-+ pullup(udc, is_active);
-+ local_irq_restore(flags);
-+ return 0;
-+}
-+
-+static int at91_pullup(struct usb_gadget *gadget, int is_on)
-+{
-+ struct at91_udc *udc = to_udc(gadget);
-+ unsigned long flags;
-+
-+ local_irq_save(flags);
-+ udc->enabled = is_on = !!is_on;
-+ pullup(udc, is_on);
-+ local_irq_restore(flags);
-+ return 0;
-+}
-+
-+static int at91_set_selfpowered(struct usb_gadget *gadget, int is_on)
-+{
-+ struct at91_udc *udc = to_udc(gadget);
-+ unsigned long flags;
-+
-+ local_irq_save(flags);
-+ udc->selfpowered = (is_on != 0);
-+ local_irq_restore(flags);
-+ return 0;
-+}
-+
-+static const struct usb_gadget_ops at91_udc_ops = {
-+ .get_frame = at91_get_frame,
-+ .wakeup = at91_wakeup,
-+ .set_selfpowered = at91_set_selfpowered,
-+ .vbus_session = at91_vbus_session,
-+ .pullup = at91_pullup,
-+
-+ /*
-+ * VBUS-powered devices may also also want to support bigger
-+ * power budgets after an appropriate SET_CONFIGURATION.
-+ */
-+ // .vbus_power = at91_vbus_power,
-+};
-+
-+/*-------------------------------------------------------------------------*/
-+
-+static int handle_ep(struct at91_ep *ep)
-+{
-+ struct at91_request *req;
-+ u32 __iomem *creg = ep->creg;
-+ u32 csr = __raw_readl(creg);
-+
-+ if (!list_empty(&ep->queue))
-+ req = list_entry(ep->queue.next,
-+ struct at91_request, queue);
-+ else
-+ req = NULL;
-+
-+ if (ep->is_in) {
-+ if (csr & (AT91_UDP_STALLSENT | AT91_UDP_TXCOMP)) {
-+ csr |= CLR_FX;
-+ csr &= ~(SET_FX | AT91_UDP_STALLSENT | AT91_UDP_TXCOMP);
-+ __raw_writel(csr, creg);
-+ }
-+ if (req)
-+ return write_fifo(ep, req);
-+
-+ } else {
-+ if (csr & AT91_UDP_STALLSENT) {
-+ /* STALLSENT bit == ISOERR */
-+ if (ep->is_iso && req)
-+ req->req.status = -EILSEQ;
-+ csr |= CLR_FX;
-+ csr &= ~(SET_FX | AT91_UDP_STALLSENT);
-+ __raw_writel(csr, creg);
-+ csr = __raw_readl(creg);
-+ }
-+ if (req && (csr & RX_DATA_READY))
-+ return read_fifo(ep, req);
-+ }
-+ return 0;
-+}
-+
-+union setup {
-+ u8 raw[8];
-+ struct usb_ctrlrequest r;
-+};
-+
-+static void handle_setup(struct at91_udc *udc, struct at91_ep *ep, u32 csr)
-+{
-+ u32 __iomem *creg = ep->creg;
-+ u8 __iomem *dreg = ep->creg + (AT91_UDP_FDR(0) - AT91_UDP_CSR(0));
-+ unsigned rxcount, i = 0;
-+ u32 tmp;
-+ union setup pkt;
-+ int status = 0;
-+
-+ /* read and ack SETUP; hard-fail for bogus packets */
-+ rxcount = (csr & AT91_UDP_RXBYTECNT) >> 16;
-+ if (likely(rxcount == 8)) {
-+ while (rxcount--)
-+ pkt.raw[i++] = __raw_readb(dreg);
-+ if (pkt.r.bRequestType & USB_DIR_IN) {
-+ csr |= AT91_UDP_DIR;
-+ ep->is_in = 1;
-+ } else {
-+ csr &= ~AT91_UDP_DIR;
-+ ep->is_in = 0;
-+ }
-+ } else {
-+ // REVISIT this happens sometimes under load; why??
-+ ERR("SETUP len %d, csr %08x\n", rxcount, csr);
-+ status = -EINVAL;
-+ }
-+ csr |= CLR_FX;
-+ csr &= ~(SET_FX | AT91_UDP_RXSETUP);
-+ __raw_writel(csr, creg);
-+ udc->wait_for_addr_ack = 0;
-+ udc->wait_for_config_ack = 0;
-+ ep->stopped = 0;
-+ if (unlikely(status != 0))
-+ goto stall;
-+
-+#define w_index le16_to_cpu(pkt.r.wIndex)
-+#define w_value le16_to_cpu(pkt.r.wValue)
-+#define w_length le16_to_cpu(pkt.r.wLength)
-+
-+ VDBG("SETUP %02x.%02x v%04x i%04x l%04x\n",
-+ pkt.r.bRequestType, pkt.r.bRequest,
-+ w_value, w_index, w_length);
-+
-+ /*
-+ * A few standard requests get handled here, ones that touch
-+ * hardware ... notably for device and endpoint features.
-+ */
-+ udc->req_pending = 1;
-+ csr = __raw_readl(creg);
-+ csr |= CLR_FX;
-+ csr &= ~SET_FX;
-+ switch ((pkt.r.bRequestType << 8) | pkt.r.bRequest) {
-+
-+ case ((USB_TYPE_STANDARD|USB_RECIP_DEVICE) << 8)
-+ | USB_REQ_SET_ADDRESS:
-+ __raw_writel(csr | AT91_UDP_TXPKTRDY, creg);
-+ udc->addr = w_value;
-+ udc->wait_for_addr_ack = 1;
-+ udc->req_pending = 0;
-+ /* FADDR is set later, when we ack host STATUS */
-+ return;
-+
-+ case ((USB_TYPE_STANDARD|USB_RECIP_DEVICE) << 8)
-+ | USB_REQ_SET_CONFIGURATION:
-+ tmp = at91_udp_read(AT91_UDP_GLB_STAT) & AT91_UDP_CONFG;
-+ if (pkt.r.wValue)
-+ udc->wait_for_config_ack = (tmp == 0);
-+ else
-+ udc->wait_for_config_ack = (tmp != 0);
-+ if (udc->wait_for_config_ack)
-+ VDBG("wait for config\n");
-+ /* CONFG is toggled later, if gadget driver succeeds */
-+ break;
-+
-+ /*
-+ * Hosts may set or clear remote wakeup status, and
-+ * devices may report they're VBUS powered.
-+ */
-+ case ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_DEVICE) << 8)
-+ | USB_REQ_GET_STATUS:
-+ tmp = (udc->selfpowered << USB_DEVICE_SELF_POWERED);
-+ if (at91_udp_read(AT91_UDP_GLB_STAT) & AT91_UDP_ESR)
-+ tmp |= (1 << USB_DEVICE_REMOTE_WAKEUP);
-+ PACKET("get device status\n");
-+ __raw_writeb(tmp, dreg);
-+ __raw_writeb(0, dreg);
-+ goto write_in;
-+ /* then STATUS starts later, automatically */
-+ case ((USB_TYPE_STANDARD|USB_RECIP_DEVICE) << 8)
-+ | USB_REQ_SET_FEATURE:
-+ if (w_value != USB_DEVICE_REMOTE_WAKEUP)
-+ goto stall;
-+ tmp = at91_udp_read(AT91_UDP_GLB_STAT);
-+ tmp |= AT91_UDP_ESR;
-+ at91_udp_write(AT91_UDP_GLB_STAT, tmp);
-+ goto succeed;
-+ case ((USB_TYPE_STANDARD|USB_RECIP_DEVICE) << 8)
-+ | USB_REQ_CLEAR_FEATURE:
-+ if (w_value != USB_DEVICE_REMOTE_WAKEUP)
-+ goto stall;
-+ tmp = at91_udp_read(AT91_UDP_GLB_STAT);
-+ tmp &= ~AT91_UDP_ESR;
-+ at91_udp_write(AT91_UDP_GLB_STAT, tmp);
-+ goto succeed;
-+
-+ /*
-+ * Interfaces have no feature settings; this is pretty useless.
-+ * we won't even insist the interface exists...
-+ */
-+ case ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_INTERFACE) << 8)
-+ | USB_REQ_GET_STATUS:
-+ PACKET("get interface status\n");
-+ __raw_writeb(0, dreg);
-+ __raw_writeb(0, dreg);
-+ goto write_in;
-+ /* then STATUS starts later, automatically */
-+ case ((USB_TYPE_STANDARD|USB_RECIP_INTERFACE) << 8)
-+ | USB_REQ_SET_FEATURE:
-+ case ((USB_TYPE_STANDARD|USB_RECIP_INTERFACE) << 8)
-+ | USB_REQ_CLEAR_FEATURE:
-+ goto stall;
-+
-+ /*
-+ * Hosts may clear bulk/intr endpoint halt after the gadget
-+ * driver sets it (not widely used); or set it (for testing)
-+ */
-+ case ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_ENDPOINT) << 8)
-+ | USB_REQ_GET_STATUS:
-+ tmp = w_index & USB_ENDPOINT_NUMBER_MASK;
-+ ep = &udc->ep[tmp];
-+ if (tmp > NUM_ENDPOINTS || (tmp && !ep->desc))
-+ goto stall;
-+
-+ if (tmp) {
-+ if ((w_index & USB_DIR_IN)) {
-+ if (!ep->is_in)
-+ goto stall;
-+ } else if (ep->is_in)
-+ goto stall;
-+ }
-+ PACKET("get %s status\n", ep->ep.name);
-+ if (__raw_readl(ep->creg) & AT91_UDP_FORCESTALL)
-+ tmp = (1 << USB_ENDPOINT_HALT);
-+ else
-+ tmp = 0;
-+ __raw_writeb(tmp, dreg);
-+ __raw_writeb(0, dreg);
-+ goto write_in;
-+ /* then STATUS starts later, automatically */
-+ case ((USB_TYPE_STANDARD|USB_RECIP_ENDPOINT) << 8)
-+ | USB_REQ_SET_FEATURE:
-+ tmp = w_index & USB_ENDPOINT_NUMBER_MASK;
-+ ep = &udc->ep[tmp];
-+ if (w_value != USB_ENDPOINT_HALT || tmp > NUM_ENDPOINTS)
-+ goto stall;
-+ if (!ep->desc || ep->is_iso)
-+ goto stall;
-+ if ((w_index & USB_DIR_IN)) {
-+ if (!ep->is_in)
-+ goto stall;
-+ } else if (ep->is_in)
-+ goto stall;
-+
-+ tmp = __raw_readl(ep->creg);
-+ tmp &= ~SET_FX;
-+ tmp |= CLR_FX | AT91_UDP_FORCESTALL;
-+ __raw_writel(tmp, ep->creg);
-+ goto succeed;
-+ case ((USB_TYPE_STANDARD|USB_RECIP_ENDPOINT) << 8)
-+ | USB_REQ_CLEAR_FEATURE:
-+ tmp = w_index & USB_ENDPOINT_NUMBER_MASK;
-+ ep = &udc->ep[tmp];
-+ if (w_value != USB_ENDPOINT_HALT || tmp > NUM_ENDPOINTS)
-+ goto stall;
-+ if (tmp == 0)
-+ goto succeed;
-+ if (!ep->desc || ep->is_iso)
-+ goto stall;
-+ if ((w_index & USB_DIR_IN)) {
-+ if (!ep->is_in)
-+ goto stall;
-+ } else if (ep->is_in)
-+ goto stall;
-+
-+ at91_udp_write(AT91_UDP_RST_EP, ep->int_mask);
-+ at91_udp_write(AT91_UDP_RST_EP, 0);
-+ tmp = __raw_readl(ep->creg);
-+ tmp |= CLR_FX;
-+ tmp &= ~(SET_FX | AT91_UDP_FORCESTALL);
-+ __raw_writel(tmp, ep->creg);
-+ if (!list_empty(&ep->queue))
-+ handle_ep(ep);
-+ goto succeed;
-+ }
-+
-+#undef w_value
-+#undef w_index
-+#undef w_length
-+
-+ /* pass request up to the gadget driver */
-+ status = udc->driver->setup(&udc->gadget, &pkt.r);
-+ if (status < 0) {
-+stall:
-+ VDBG("req %02x.%02x protocol STALL; stat %d\n",
-+ pkt.r.bRequestType, pkt.r.bRequest, status);
-+ csr |= AT91_UDP_FORCESTALL;
-+ __raw_writel(csr, creg);
-+ udc->req_pending = 0;
-+ }
-+ return;
-+
-+succeed:
-+ /* immediate successful (IN) STATUS after zero length DATA */
-+ PACKET("ep0 in/status\n");
-+write_in:
-+ csr |= AT91_UDP_TXPKTRDY;
-+ __raw_writel(csr, creg);
-+ udc->req_pending = 0;
-+ return;
-+}
-+
-+static void handle_ep0(struct at91_udc *udc)
-+{
-+ struct at91_ep *ep0 = &udc->ep[0];
-+ u32 __iomem *creg = ep0->creg;
-+ u32 csr = __raw_readl(creg);
-+ struct at91_request *req;
-+
-+ if (unlikely(csr & AT91_UDP_STALLSENT)) {
-+ nuke(ep0, -EPROTO);
-+ udc->req_pending = 0;
-+ csr |= CLR_FX;
-+ csr &= ~(SET_FX | AT91_UDP_STALLSENT | AT91_UDP_FORCESTALL);
-+ __raw_writel(csr, creg);
-+ VDBG("ep0 stalled\n");
-+ csr = __raw_readl(creg);
-+ }
-+ if (csr & AT91_UDP_RXSETUP) {
-+ nuke(ep0, 0);
-+ udc->req_pending = 0;
-+ handle_setup(udc, ep0, csr);
-+ return;
-+ }
-+
-+ if (list_empty(&ep0->queue))
-+ req = NULL;
-+ else
-+ req = list_entry(ep0->queue.next, struct at91_request, queue);
-+
-+ /* host ACKed an IN packet that we sent */
-+ if (csr & AT91_UDP_TXCOMP) {
-+ csr |= CLR_FX;
-+ csr &= ~(SET_FX | AT91_UDP_TXCOMP);
-+
-+ /* write more IN DATA? */
-+ if (req && ep0->is_in) {
-+ if (handle_ep(ep0))
-+ udc->req_pending = 0;
-+
-+ /*
-+ * Ack after:
-+ * - last IN DATA packet (including GET_STATUS)
-+ * - IN/STATUS for OUT DATA
-+ * - IN/STATUS for any zero-length DATA stage
-+ * except for the IN DATA case, the host should send
-+ * an OUT status later, which we'll ack.
-+ */
-+ } else {
-+ udc->req_pending = 0;
-+ __raw_writel(csr, creg);
-+
-+ /*
-+ * SET_ADDRESS takes effect only after the STATUS
-+ * (to the original address) gets acked.
-+ */
-+ if (udc->wait_for_addr_ack) {
-+ u32 tmp;
-+
-+ at91_udp_write(AT91_UDP_FADDR, AT91_UDP_FEN | udc->addr);
-+ tmp = at91_udp_read(AT91_UDP_GLB_STAT);
-+ tmp &= ~AT91_UDP_FADDEN;
-+ if (udc->addr)
-+ tmp |= AT91_UDP_FADDEN;
-+ at91_udp_write(AT91_UDP_GLB_STAT, tmp);
-+
-+ udc->wait_for_addr_ack = 0;
-+ VDBG("address %d\n", udc->addr);
-+ }
-+ }
-+ }
-+
-+ /* OUT packet arrived ... */
-+ else if (csr & AT91_UDP_RX_DATA_BK0) {
-+ csr |= CLR_FX;
-+ csr &= ~(SET_FX | AT91_UDP_RX_DATA_BK0);
-+
-+ /* OUT DATA stage */
-+ if (!ep0->is_in) {
-+ if (req) {
-+ if (handle_ep(ep0)) {
-+ /* send IN/STATUS */
-+ PACKET("ep0 in/status\n");
-+ csr = __raw_readl(creg);
-+ csr &= ~SET_FX;
-+ csr |= CLR_FX | AT91_UDP_TXPKTRDY;
-+ __raw_writel(csr, creg);
-+ udc->req_pending = 0;
-+ }
-+ } else if (udc->req_pending) {
-+ /*
-+ * AT91 hardware has a hard time with this
-+ * "deferred response" mode for control-OUT
-+ * transfers. (For control-IN it's fine.)
-+ *
-+ * The normal solution leaves OUT data in the
-+ * fifo until the gadget driver is ready.
-+ * We couldn't do that here without disabling
-+ * the IRQ that tells about SETUP packets,
-+ * e.g. when the host gets impatient...
-+ *
-+ * Working around it by copying into a buffer
-+ * would almost be a non-deferred response,
-+ * except that it wouldn't permit reliable
-+ * stalling of the request. Instead, demand
-+ * that gadget drivers not use this mode.
-+ */
-+ DBG("no control-OUT deferred responses!\n");
-+ __raw_writel(csr | AT91_UDP_FORCESTALL, creg);
-+ udc->req_pending = 0;
-+ }
-+
-+ /* STATUS stage for control-IN; ack. */
-+ } else {
-+ PACKET("ep0 out/status ACK\n");
-+ __raw_writel(csr, creg);
-+
-+ /* "early" status stage */
-+ if (req)
-+ done(ep0, req, 0);
-+ }
-+ }
-+}
-+
-+static irqreturn_t at91_udc_irq (int irq, void *_udc, struct pt_regs *r)
-+{
-+ struct at91_udc *udc = _udc;
-+ u32 rescans = 5;
-+
-+ while (rescans--) {
-+ u32 status = at91_udp_read(AT91_UDP_ISR);
-+
-+ status &= at91_udp_read(AT91_UDP_IMR);
-+ if (!status)
-+ break;
-+
-+ /* USB reset irq: not maskable */
-+ if (status & AT91_UDP_ENDBUSRES) {
-+ at91_udp_write(AT91_UDP_IDR, ~MINIMUS_INTERRUPTUS);
-+ at91_udp_write(AT91_UDP_IER, MINIMUS_INTERRUPTUS);
-+ /* Atmel code clears this irq twice */
-+ at91_udp_write(AT91_UDP_ICR, AT91_UDP_ENDBUSRES);
-+ at91_udp_write(AT91_UDP_ICR, AT91_UDP_ENDBUSRES);
-+ VDBG("end bus reset\n");
-+ udc->addr = 0;
-+ stop_activity(udc);
-+
-+ /* enable ep0 */
-+ at91_udp_write(AT91_UDP_CSR(0), AT91_UDP_EPEDS | AT91_UDP_EPTYPE_CTRL);
-+ udc->gadget.speed = USB_SPEED_FULL;
-+ udc->suspended = 0;
-+ at91_udp_write(AT91_UDP_IER, AT91_UDP_EP(0));
-+
-+ /*
-+ * NOTE: this driver keeps clocks off unless the
-+ * USB host is present. That saves power, and also
-+ * eliminates IRQs (reset, resume, suspend) that can
-+ * otherwise flood from the controller. If your
-+ * board doesn't support VBUS detection, suspend and
-+ * resume irq logic may need more attention...
-+ */
-+
-+ /* host initiated suspend (3+ms bus idle) */
-+ } else if (status & AT91_UDP_RXSUSP) {
-+ at91_udp_write(AT91_UDP_IDR, AT91_UDP_RXSUSP);
-+ at91_udp_write(AT91_UDP_IER, AT91_UDP_RXRSM);
-+ at91_udp_write(AT91_UDP_ICR, AT91_UDP_RXSUSP);
-+ // VDBG("bus suspend\n");
-+ if (udc->suspended)
-+ continue;
-+ udc->suspended = 1;
-+
-+ /*
-+ * NOTE: when suspending a VBUS-powered device, the
-+ * gadget driver should switch into slow clock mode
-+ * and then into standby to avoid drawing more than
-+ * 500uA power (2500uA for some high-power configs).
-+ */
-+ if (udc->driver && udc->driver->suspend)
-+ udc->driver->suspend(&udc->gadget);
-+
-+ /* host initiated resume */
-+ } else if (status & AT91_UDP_RXRSM) {
-+ at91_udp_write(AT91_UDP_IDR, AT91_UDP_RXRSM);
-+ at91_udp_write(AT91_UDP_IER, AT91_UDP_RXSUSP);
-+ at91_udp_write(AT91_UDP_ICR, AT91_UDP_RXRSM);
-+ // VDBG("bus resume\n");
-+ if (!udc->suspended)
-+ continue;
-+ udc->suspended = 0;
-+
-+ /*
-+ * NOTE: for a VBUS-powered device, the gadget driver
-+ * would normally want to switch out of slow clock
-+ * mode into normal mode.
-+ */
-+ if (udc->driver && udc->driver->resume)
-+ udc->driver->resume(&udc->gadget);
-+
-+ /* endpoint IRQs are cleared by handling them */
-+ } else {
-+ int i;
-+ unsigned mask = 1;
-+ struct at91_ep *ep = &udc->ep[1];
-+
-+ if (status & mask)
-+ handle_ep0(udc);
-+ for (i = 1; i < NUM_ENDPOINTS; i++) {
-+ mask <<= 1;
-+ if (status & mask)
-+ handle_ep(ep);
-+ ep++;
-+ }
-+ }
-+ }
-+
-+ return IRQ_HANDLED;
-+}
-+
-+/*-------------------------------------------------------------------------*/
-+
-+static struct at91_udc controller = {
-+ .gadget = {
-+ .ops = &at91_udc_ops,
-+ .ep0 = &controller.ep[0].ep,
-+ .name = driver_name,
-+ .dev = {
-+ .bus_id = "gadget"
-+ }
-+ },
-+ .ep[0] = {
-+ .ep = {
-+ .name = ep0name,
-+ .ops = &at91_ep_ops,
-+ },
-+ .udc = &controller,
-+ .maxpacket = 8,
-+ .creg = (void __iomem *)(AT91_VA_BASE_UDP + AT91_UDP_CSR(0)),
-+ .int_mask = 1 << 0,
-+ },
-+ .ep[1] = {
-+ .ep = {
-+ .name = "ep1",
-+ .ops = &at91_ep_ops,
-+ },
-+ .udc = &controller,
-+ .is_pingpong = 1,
-+ .maxpacket = 64,
-+ .creg = (void __iomem *)(AT91_VA_BASE_UDP + AT91_UDP_CSR(1)),
-+ .int_mask = 1 << 1,
-+ },
-+ .ep[2] = {
-+ .ep = {
-+ .name = "ep2",
-+ .ops = &at91_ep_ops,
-+ },
-+ .udc = &controller,
-+ .is_pingpong = 1,
-+ .maxpacket = 64,
-+ .creg = (void __iomem *)(AT91_VA_BASE_UDP + AT91_UDP_CSR(2)),
-+ .int_mask = 1 << 2,
-+ },
-+ .ep[3] = {
-+ .ep = {
-+ /* could actually do bulk too */
-+ .name = "ep3-int",
-+ .ops = &at91_ep_ops,
-+ },
-+ .udc = &controller,
-+ .maxpacket = 8,
-+ .creg = (void __iomem *)(AT91_VA_BASE_UDP + AT91_UDP_CSR(3)),
-+ .int_mask = 1 << 3,
-+ },
-+ .ep[4] = {
-+ .ep = {
-+ .name = "ep4",
-+ .ops = &at91_ep_ops,
-+ },
-+ .udc = &controller,
-+ .is_pingpong = 1,
-+ .maxpacket = 256,
-+ .creg = (void __iomem *)(AT91_VA_BASE_UDP + AT91_UDP_CSR(4)),
-+ .int_mask = 1 << 4,
-+ },
-+ .ep[5] = {
-+ .ep = {
-+ .name = "ep5",
-+ .ops = &at91_ep_ops,
-+ },
-+ .udc = &controller,
-+ .is_pingpong = 1,
-+ .maxpacket = 256,
-+ .creg = (void __iomem *)(AT91_VA_BASE_UDP + AT91_UDP_CSR(5)),
-+ .int_mask = 1 << 5,
-+ },
-+ /* ep6 and ep7 are also reserved */
-+};
-+
-+static irqreturn_t at91_vbus_irq(int irq, void *_udc, struct pt_regs *r)
-+{
-+ struct at91_udc *udc = _udc;
-+ unsigned value;
-+
-+ /* vbus needs at least brief debouncing */
-+ udelay(10);
-+ value = at91_get_gpio_value(udc->board.vbus_pin);
-+ if (value != udc->vbus)
-+ at91_vbus_session(&udc->gadget, value);
-+
-+ return IRQ_HANDLED;
-+}
-+
-+int usb_gadget_register_driver (struct usb_gadget_driver *driver)
-+{
-+ struct at91_udc *udc = &controller;
-+ int retval;
-+
-+ if (!driver
-+ || driver->speed != USB_SPEED_FULL
-+ || !driver->bind
-+ || !driver->unbind
-+ || !driver->setup) {
-+ DBG("bad parameter.\n");
-+ return -EINVAL;
-+ }
-+
-+ if (udc->driver) {
-+ DBG("UDC already has a gadget driver\n");
-+ return -EBUSY;
-+ }
-+
-+ udc->driver = driver;
-+ udc->gadget.dev.driver = &driver->driver;
-+ udc->gadget.dev.driver_data = &driver->driver;
-+ udc->enabled = 1;
-+ udc->selfpowered = 1;
-+
-+ retval = driver->bind(&udc->gadget);
-+ if (retval) {
-+ DBG("driver->bind() returned %d\n", retval);
-+ udc->driver = NULL;
-+ return retval;
-+ }
-+
-+ local_irq_disable();
-+ pullup(udc, 1);
-+ local_irq_enable();
-+
-+ DBG("bound to %s\n", driver->driver.name);
-+ return 0;
-+}
-+EXPORT_SYMBOL (usb_gadget_register_driver);
-+
-+int usb_gadget_unregister_driver (struct usb_gadget_driver *driver)
-+{
-+ struct at91_udc *udc = &controller;
-+
-+ if (!driver || driver != udc->driver)
-+ return -EINVAL;
-+
-+ local_irq_disable();
-+ udc->enabled = 0;
-+ pullup(udc, 0);
-+ local_irq_enable();
-+
-+ driver->unbind(&udc->gadget);
-+ udc->driver = NULL;
-+
-+ DBG("unbound from %s\n", driver->driver.name);
-+ return 0;
-+}
-+EXPORT_SYMBOL (usb_gadget_unregister_driver);
-+
-+/*-------------------------------------------------------------------------*/
-+
-+static void at91udc_shutdown(struct platform_device *dev)
-+{
-+ /* force disconnect on reboot */
-+ pullup(platform_get_drvdata(dev), 0);
-+}
-+
-+static int __devinit at91udc_probe(struct platform_device *pdev)
-+{
-+ struct device *dev = &pdev->dev;
-+ struct at91_udc *udc;
-+ int retval;
-+
-+ if (!dev->platform_data) {
-+ /* small (so we copy it) but critical! */
-+ DBG("missing platform_data\n");
-+ return -ENODEV;
-+ }
-+
-+ if (!request_mem_region(AT91_BASE_UDP, SZ_16K, driver_name)) {
-+ DBG("someone's using UDC memory\n");
-+ return -EBUSY;
-+ }
-+
-+ /* init software state */
-+ udc = &controller;
-+ udc->gadget.dev.parent = dev;
-+ udc->board = *(struct at91_udc_data *) dev->platform_data;
-+ udc->pdev = pdev;
-+ udc_reinit(udc);
-+ udc->enabled = 0;
-+
-+ /* get interface and function clocks */
-+ udc->iclk = clk_get(dev, "udc_clk");
-+ udc->fclk = clk_get(dev, "udpck");
-+ if (IS_ERR(udc->iclk) || IS_ERR(udc->fclk)) {
-+ DBG("clocks missing\n");
-+ return -ENODEV;
-+ }
-+
-+ retval = device_register(&udc->gadget.dev);
-+ if (retval < 0)
-+ goto fail0;
-+
-+ /* disable everything until there's a gadget driver and vbus */
-+ pullup(udc, 0);
-+
-+ /* request UDC and maybe VBUS irqs */
-+ if (request_irq(AT91_ID_UDP, at91_udc_irq, SA_INTERRUPT, driver_name, udc)) {
-+ DBG("request irq %d failed\n", AT91_ID_UDP);
-+ retval = -EBUSY;
-+ goto fail1;
-+ }
-+ if (udc->board.vbus_pin > 0) {
-+ if (request_irq(udc->board.vbus_pin, at91_vbus_irq, SA_INTERRUPT, driver_name, udc)) {
-+ DBG("request vbus irq %d failed\n", udc->board.vbus_pin);
-+ free_irq(AT91_ID_UDP, udc);
-+ retval = -EBUSY;
-+ goto fail1;
-+ }
-+ } else {
-+ DBG("no VBUS detection, assuming always-on\n");
-+ udc->vbus = 1;
-+ }
-+ dev_set_drvdata(dev, udc);
-+ create_debug_file(udc);
-+
-+ INFO("%s version %s\n", driver_name, DRIVER_VERSION);
-+ return 0;
-+
-+fail1:
-+ device_unregister(&udc->gadget.dev);
-+fail0:
-+ release_mem_region(AT91_VA_BASE_UDP, SZ_16K);
-+ DBG("%s probe failed, %d\n", driver_name, retval);
-+ return retval;
-+}
-+
-+static int __devexit at91udc_remove(struct platform_device *dev)
-+{
-+ struct at91_udc *udc = platform_get_drvdata(dev);
-+
-+ DBG("remove\n");
-+
-+ pullup(udc, 0);
-+
-+ if (udc->driver != 0)
-+ usb_gadget_unregister_driver(udc->driver);
-+
-+ remove_debug_file(udc);
-+ if (udc->board.vbus_pin > 0)
-+ free_irq(udc->board.vbus_pin, udc);
-+ free_irq(AT91_ID_UDP, udc);
-+ device_unregister(&udc->gadget.dev);
-+ release_mem_region(AT91_BASE_UDP, SZ_16K);
-+
-+ clk_put(udc->iclk);
-+ clk_put(udc->fclk);
-+
-+ return 0;
-+}
-+
-+#ifdef CONFIG_PM
-+static int at91udc_suspend(struct platform_device *dev, u32 state, u32 level)
-+{
-+ struct at91_udc *udc = platform_get_drvdata(dev);
-+
-+ /*
-+ * The "safe" suspend transitions are opportunistic ... e.g. when
-+ * the USB link is suspended (48MHz clock autogated off), or when
-+ * it's disconnected (programmatically gated off, elsewhere).
-+ * Then we can suspend, and the chip can enter slow clock mode.
-+ *
-+ * The problem case is some component (user mode?) suspending this
-+ * device while it's active, with the 48 MHz clock in use. There
-+ * are two basic approaches: (a) veto suspend levels involving slow
-+ * clock mode, (b) disconnect, so 48 MHz will no longer be in use
-+ * and we can enter slow clock mode. This uses (b) for now, since
-+ * it's simplest until AT91 PM exists and supports the other option.
-+ */
-+ if (udc->vbus && !udc->suspended)
-+ pullup(udc, 0);
-+ return 0;
-+}
-+
-+static int at91udc_resume(struct platform_device *dev, u32 level)
-+{
-+ struct at91_udc *udc = platform_get_drvdata(dev);
-+
-+ /* maybe reconnect to host; if so, clocks on */
-+ pullup(udc, 1);
-+ return 0;
-+}
-+#else
-+#define at91udc_suspend NULL
-+#define at91udc_resume NULL
-+#endif
-+
-+static struct platform_driver at91_udc = {
-+ .probe = at91udc_probe,
-+ .remove = __devexit_p(at91udc_remove),
-+ .shutdown = at91udc_shutdown,
-+ .suspend = at91udc_suspend,
-+ .resume = at91udc_resume,
-+ .driver = {
-+ .name = (char *) driver_name,
-+ .owner = THIS_MODULE,
-+ },
-+};
-+
-+static int __devinit udc_init_module(void)
-+{
-+ return platform_driver_register(&at91_udc);
-+}
-+module_init(udc_init_module);
-+
-+static void __devexit udc_exit_module(void)
-+{
-+ platform_driver_unregister(&at91_udc);
-+}
-+module_exit(udc_exit_module);
-+
-+MODULE_DESCRIPTION("AT91RM9200 udc driver");
-+MODULE_AUTHOR("Thomas Rathbone, David Brownell");
-+MODULE_LICENSE("GPL");
---- /dev/null
-+++ gregkh-2.6/drivers/usb/gadget/at91_udc.h
-@@ -0,0 +1,181 @@
-+/*
-+ * Copyright (C) 2004 by Thomas Rathbone, HP Labs
-+ * Copyright (C) 2005 by Ivan Kokshaysky
-+ * Copyright (C) 2006 by SAN People
-+ *
-+ * 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.,
-+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-+ */
-+
-+#ifndef AT91_UDC_H
-+#define AT91_UDC_H
-+
-+/*
-+ * USB Device Port (UDP) registers.
-+ * Based on AT91RM9200 datasheet revision E.
-+ */
-+
-+#define AT91_UDP_FRM_NUM 0x00 /* Frame Number Register */
-+#define AT91_UDP_NUM (0x7ff << 0) /* Frame Number */
-+#define AT91_UDP_FRM_ERR (1 << 16) /* Frame Error */
-+#define AT91_UDP_FRM_OK (1 << 17) /* Frame OK */
-+
-+#define AT91_UDP_GLB_STAT 0x04 /* Global State Register */
-+#define AT91_UDP_FADDEN (1 << 0) /* Function Address Enable */
-+#define AT91_UDP_CONFG (1 << 1) /* Configured */
-+#define AT91_UDP_ESR (1 << 2) /* Enable Send Resume */
-+#define AT91_UDP_RSMINPR (1 << 3) /* Resume has been sent */
-+#define AT91_UDP_RMWUPE (1 << 4) /* Remote Wake Up Enable */
-+
-+#define AT91_UDP_FADDR 0x08 /* Function Address Register */
-+#define AT91_UDP_FADD (0x7f << 0) /* Function Address Value */
-+#define AT91_UDP_FEN (1 << 8) /* Function Enable */
-+
-+#define AT91_UDP_IER 0x10 /* Interrupt Enable Register */
-+#define AT91_UDP_IDR 0x14 /* Interrupt Disable Register */
-+#define AT91_UDP_IMR 0x18 /* Interrupt Mask Register */
-+
-+#define AT91_UDP_ISR 0x1c /* Interrupt Status Register */
-+#define AT91_UDP_EP(n) (1 << (n)) /* Endpoint Interrupt Status */
-+#define AT91_UDP_RXSUSP (1 << 8) /* USB Suspend Interrupt Status */
-+#define AT91_UDP_RXRSM (1 << 9) /* USB Resume Interrupt Status */
-+#define AT91_UDP_EXTRSM (1 << 10) /* External Resume Interrupt Status */
-+#define AT91_UDP_SOFINT (1 << 11) /* Start of Frame Interrupt Status */
-+#define AT91_UDP_ENDBUSRES (1 << 12) /* End of Bus Reset Interrpt Status */
-+#define AT91_UDP_WAKEUP (1 << 13) /* USB Wakeup Interrupt Status */
-+
-+#define AT91_UDP_ICR 0x20 /* Interrupt Clear Register */
-+#define AT91_UDP_RST_EP 0x28 /* Reset Endpoint Register */
-+
-+#define AT91_UDP_CSR(n) (0x30+((n)*4)) /* Endpoint Control/Status Registers 0-7 */
-+#define AT91_UDP_TXCOMP (1 << 0) /* Generates IN packet with data previously written in DPR */
-+#define AT91_UDP_RX_DATA_BK0 (1 << 1) /* Receive Data Bank 0 */
-+#define AT91_UDP_RXSETUP (1 << 2) /* Send STALL to the host */
-+#define AT91_UDP_STALLSENT (1 << 3) /* Stall Sent / Isochronous error (Isochronous endpoints) */
-+#define AT91_UDP_TXPKTRDY (1 << 4) /* Transmit Packet Ready */
-+#define AT91_UDP_FORCESTALL (1 << 5) /* Force Stall */
-+#define AT91_UDP_RX_DATA_BK1 (1 << 6) /* Receive Data Bank 1 */
-+#define AT91_UDP_DIR (1 << 7) /* Transfer Direction */
-+#define AT91_UDP_EPTYPE (7 << 8) /* Endpoint Type */
-+#define AT91_UDP_EPTYPE_CTRL (0 << 8)
-+#define AT91_UDP_EPTYPE_ISO_OUT (1 << 8)
-+#define AT91_UDP_EPTYPE_BULK_OUT (2 << 8)
-+#define AT91_UDP_EPTYPE_INT_OUT (3 << 8)
-+#define AT91_UDP_EPTYPE_ISO_IN (5 << 8)
-+#define AT91_UDP_EPTYPE_BULK_IN (6 << 8)
-+#define AT91_UDP_EPTYPE_INT_IN (7 << 8)
-+#define AT91_UDP_DTGLE (1 << 11) /* Data Toggle */
-+#define AT91_UDP_EPEDS (1 << 15) /* Endpoint Enable/Disable */
-+#define AT91_UDP_RXBYTECNT (0x7ff << 16) /* Number of bytes in FIFO */
-+
-+#define AT91_UDP_FDR(n) (0x50+((n)*4)) /* Endpoint FIFO Data Registers 0-7 */
-+
-+#define AT91_UDP_TXVC 0x74 /* Transceiver Control Register */
-+#define AT91_UDP_TXVC_TXVDIS (1 << 8) /* Transceiver Disable */
-+
-+
-+/*-------------------------------------------------------------------------*/
-+
-+/*
-+ * controller driver data structures
-+ */
-+
-+#define NUM_ENDPOINTS 6
-+
-+/*
-+ * hardware won't disable bus reset, or resume while the controller
-+ * is suspended ... watching suspend helps keep the logic symmetric.
-+ */
-+#define MINIMUS_INTERRUPTUS \
-+ (AT91_UDP_ENDBUSRES | AT91_UDP_RXRSM | AT91_UDP_RXSUSP)
-+
-+struct at91_ep {
-+ struct usb_ep ep;
-+ struct list_head queue;
-+ struct at91_udc *udc;
-+ void __iomem *creg;
-+
-+ unsigned maxpacket:16;
-+ u8 int_mask;
-+ unsigned is_pingpong:1;
-+
-+ unsigned stopped:1;
-+ unsigned is_in:1;
-+ unsigned is_iso:1;
-+ unsigned fifo_bank:1;
-+
-+ const struct usb_endpoint_descriptor
-+ *desc;
-+};
-+
-+/*
-+ * driver is non-SMP, and just blocks IRQs whenever it needs
-+ * access protection for chip registers or driver state
-+ */
-+struct at91_udc {
-+ struct usb_gadget gadget;
-+ struct at91_ep ep[NUM_ENDPOINTS];
-+ struct usb_gadget_driver *driver;
-+ unsigned vbus:1;
-+ unsigned enabled:1;
-+ unsigned clocked:1;
-+ unsigned suspended:1;
-+ unsigned req_pending:1;
-+ unsigned wait_for_addr_ack:1;
-+ unsigned wait_for_config_ack:1;
-+ unsigned selfpowered:1;
-+ u8 addr;
-+ struct at91_udc_data board;
-+ struct clk *iclk, *fclk;
-+ struct platform_device *pdev;
-+ struct proc_dir_entry *pde;
-+};
-+
-+static inline struct at91_udc *to_udc(struct usb_gadget *g)
-+{
-+ return container_of(g, struct at91_udc, gadget);
-+}
-+
-+struct at91_request {
-+ struct usb_request req;
-+ struct list_head queue;
-+};
-+
-+/*-------------------------------------------------------------------------*/
-+
-+#ifdef DEBUG
-+#define DBG(stuff...) printk(KERN_DEBUG "udc: " stuff)
-+#else
-+#define DBG(stuff...) do{}while(0)
-+#endif
-+
-+#ifdef VERBOSE
-+# define VDBG DBG
-+#else
-+# define VDBG(stuff...) do{}while(0)
-+#endif
-+
-+#ifdef PACKET_TRACE
-+# define PACKET VDBG
-+#else
-+# define PACKET(stuff...) do{}while(0)
-+#endif
-+
-+#define ERR(stuff...) printk(KERN_ERR "udc: " stuff)
-+#define WARN(stuff...) printk(KERN_WARNING "udc: " stuff)
-+#define INFO(stuff...) printk(KERN_INFO "udc: " stuff)
-+
-+#endif
-+
diff --git a/usb/usb-add-support-for-creativelabs-silvercrest-usb-keyboard.patch b/usb/usb-add-support-for-creativelabs-silvercrest-usb-keyboard.patch
deleted file mode 100644
index e1559fd6a8e64..0000000000000
--- a/usb/usb-add-support-for-creativelabs-silvercrest-usb-keyboard.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From linux-usb-devel-admin@lists.sourceforge.net Wed Mar 8 08:00:38 2006
-From: Wolfgang Rohdewald <wolfgang@rohdewald.de>
-Subject: USB: add support for Creativelabs Silvercrest USB keyboard
-Content-Disposition: inline
-Message-Id: <200603081659.51267.wolfgang@rohdewald.de>
-Date: Wed, 8 Mar 2006 16:59:44 +0100
-
-Signed-off-by: Wolfgang Rohdewald <wolfgang@rohdewald.de>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-
----
- drivers/usb/input/hid-core.c | 4 ++++
- 1 file changed, 4 insertions(+)
-
---- gregkh-2.6.orig/drivers/usb/input/hid-core.c
-+++ gregkh-2.6/drivers/usb/input/hid-core.c
-@@ -1552,6 +1552,9 @@ void hid_init_reports(struct hid_device
- #define USB_VENDOR_ID_HP 0x03f0
- #define USB_DEVICE_ID_HP_USBHUB_KB 0x020c
-
-+#define USB_VENDOR_ID_CREATIVELABS 0x062a
-+#define USB_DEVICE_ID_CREATIVELABS_SILVERCREST 0x0201
-+
- /*
- * Alphabetically sorted blacklist by quirk type.
- */
-@@ -1668,6 +1671,7 @@ static const struct hid_blacklist {
- { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVMC, HID_QUIRK_NOGET },
- { USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_KEYBOARD, HID_QUIRK_NOGET},
- { USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_USBHUB_KB, HID_QUIRK_NOGET},
-+ { USB_VENDOR_ID_CREATIVELABS, USB_DEVICE_ID_CREATIVELABS_SILVERCREST, HID_QUIRK_NOGET },
- { USB_VENDOR_ID_HP, USB_DEVICE_ID_HP_USBHUB_KB, HID_QUIRK_NOGET },
- { USB_VENDOR_ID_TANGTOP, USB_DEVICE_ID_TANGTOP_USBPS2, HID_QUIRK_NOGET },
- { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_DUAL_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT },
diff --git a/usb/usb-add-support-for-ochi-on-at91rm9200.patch b/usb/usb-add-support-for-ochi-on-at91rm9200.patch
deleted file mode 100644
index 14fc474e19004..0000000000000
--- a/usb/usb-add-support-for-ochi-on-at91rm9200.patch
+++ /dev/null
@@ -1,378 +0,0 @@
-From david-b@pacbell.net Sun Jan 22 11:29:00 2006
-From: David Brownell <david-b@pacbell.net>
-To: Greg KH <greg@kroah.com>
-Subject: USB: add support for OCHI on AT91rm9200
-Date: Sun, 22 Jan 2006 10:32:13 -0800
-Cc: Andrew Victor <andrew@sanpeople.com>
-Message-Id: <200601221032.13463.david-b@pacbell.net>
-
-From: Andrew Victor <andrew@sanpeople.com>
-
-This adds support for OHCI on AT91rm9200 based boards.
-
-Possibly of interest here is the way this uses <linux/clk.h> to
-gate clocks on/off during system pm state transitions. That's
-typical for non-PCI systems. Some can go further; Mini-A host
-side connectors enable ID-pin sensing.
-
-From: Andrew Victor <andrew@sanpeople.com>
-Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-
----
- drivers/usb/Kconfig | 1
- drivers/usb/Makefile | 1
- drivers/usb/host/ohci-at91.c | 306 +++++++++++++++++++++++++++++++++++++++++++
- drivers/usb/host/ohci-hcd.c | 5
- 4 files changed, 313 insertions(+)
-
---- gregkh-2.6.orig/drivers/usb/Kconfig
-+++ gregkh-2.6/drivers/usb/Kconfig
-@@ -23,6 +23,7 @@ config USB_ARCH_HAS_OHCI
- default y if ARCH_LH7A404
- default y if ARCH_S3C2410
- default y if PXA27x
-+ default y if ARCH_AT91RM9200
- # PPC:
- default y if STB03xxx
- default y if PPC_MPC52xx
---- gregkh-2.6.orig/drivers/usb/Makefile
-+++ gregkh-2.6/drivers/usb/Makefile
-@@ -15,6 +15,7 @@ obj-$(CONFIG_USB_OHCI_HCD) += host/
- obj-$(CONFIG_USB_UHCI_HCD) += host/
- obj-$(CONFIG_USB_SL811_HCD) += host/
- obj-$(CONFIG_ETRAX_USB_HOST) += host/
-+obj-$(CONFIG_USB_OHCI_AT91) += host/
-
- obj-$(CONFIG_USB_ACM) += class/
- obj-$(CONFIG_USB_PRINTER) += class/
---- /dev/null
-+++ gregkh-2.6/drivers/usb/host/ohci-at91.c
-@@ -0,0 +1,306 @@
-+/*
-+ * OHCI HCD (Host Controller Driver) for USB.
-+ *
-+ * Copyright (C) 2004 SAN People (Pty) Ltd.
-+ * Copyright (C) 2005 Thibaut VARENE <varenet@parisc-linux.org>
-+ *
-+ * AT91RM9200 Bus Glue
-+ *
-+ * Based on fragments of 2.4 driver by Rick Bronson.
-+ * Based on ohci-omap.c
-+ *
-+ * This file is licenced under the GPL.
-+ */
-+
-+#include <linux/clk.h>
-+#include <linux/platform_device.h>
-+
-+#include <asm/mach-types.h>
-+#include <asm/hardware.h>
-+#include <asm/arch/board.h>
-+
-+#ifndef CONFIG_ARCH_AT91RM9200
-+#error "This file is AT91RM9200 bus glue. CONFIG_ARCH_AT91RM9200 must be defined."
-+#endif
-+
-+/* interface and function clocks */
-+static struct clk *iclk, *fclk;
-+
-+extern int usb_disabled(void);
-+
-+/*-------------------------------------------------------------------------*/
-+
-+static void at91_start_hc(struct platform_device *pdev)
-+{
-+ struct usb_hcd *hcd = platform_get_drvdata(pdev);
-+ struct ohci_regs __iomem *regs = hcd->regs;
-+
-+ dev_dbg(&pdev->dev, "starting AT91RM9200 OHCI USB Controller\n");
-+
-+ /*
-+ * Start the USB clocks.
-+ */
-+ clk_enable(iclk);
-+ clk_enable(fclk);
-+
-+ /*
-+ * The USB host controller must remain in reset.
-+ */
-+ writel(0, &regs->control);
-+}
-+
-+static void at91_stop_hc(struct platform_device *pdev)
-+{
-+ struct usb_hcd *hcd = platform_get_drvdata(pdev);
-+ struct ohci_regs __iomem *regs = hcd->regs;
-+
-+ dev_dbg(&pdev->dev, "stopping AT91RM9200 OHCI USB Controller\n");
-+
-+ /*
-+ * Put the USB host controller into reset.
-+ */
-+ writel(0, &regs->control);
-+
-+ /*
-+ * Stop the USB clocks.
-+ */
-+ clk_disable(fclk);
-+ clk_disable(iclk);
-+}
-+
-+
-+/*-------------------------------------------------------------------------*/
-+
-+static int usb_hcd_at91_remove (struct usb_hcd *, struct platform_device *);
-+
-+/* configure so an HC device and id are always provided */
-+/* always called with process context; sleeping is OK */
-+
-+
-+/**
-+ * usb_hcd_at91_probe - initialize AT91RM9200-based HCDs
-+ * Context: !in_interrupt()
-+ *
-+ * Allocates basic resources for this USB host controller, and
-+ * then invokes the start() method for the HCD associated with it
-+ * through the hotplug entry's driver_data.
-+ *
-+ * Store this function in the HCD's struct pci_driver as probe().
-+ */
-+int usb_hcd_at91_probe (const struct hc_driver *driver, struct platform_device *pdev)
-+{
-+ int retval;
-+ struct usb_hcd *hcd = NULL;
-+
-+ if (pdev->num_resources != 2) {
-+ pr_debug("hcd probe: invalid num_resources");
-+ return -ENODEV;
-+ }
-+
-+ if ((pdev->resource[0].flags != IORESOURCE_MEM) || (pdev->resource[1].flags != IORESOURCE_IRQ)) {
-+ pr_debug("hcd probe: invalid resource type\n");
-+ return -ENODEV;
-+ }
-+
-+ hcd = usb_create_hcd(driver, &pdev->dev, "at91rm9200");
-+ if (!hcd)
-+ return -ENOMEM;
-+ hcd->rsrc_start = pdev->resource[0].start;
-+ hcd->rsrc_len = pdev->resource[0].end - pdev->resource[0].start + 1;
-+
-+ if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
-+ pr_debug("request_mem_region failed\n");
-+ retval = -EBUSY;
-+ goto err1;
-+ }
-+
-+ hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
-+ if (!hcd->regs) {
-+ pr_debug("ioremap failed\n");
-+ retval = -EIO;
-+ goto err2;
-+ }
-+
-+ iclk = clk_get(&pdev->dev, "ohci_clk");
-+ fclk = clk_get(&pdev->dev, "uhpck");
-+
-+ at91_start_hc(pdev);
-+ ohci_hcd_init(hcd_to_ohci(hcd));
-+
-+ retval = usb_add_hcd(hcd, pdev->resource[1].start, SA_INTERRUPT);
-+ if (retval == 0)
-+ return retval;
-+
-+ /* Error handling */
-+ at91_stop_hc(pdev);
-+
-+ clk_put(fclk);
-+ clk_put(iclk);
-+
-+ iounmap(hcd->regs);
-+
-+ err2:
-+ release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
-+
-+ err1:
-+ usb_put_hcd(hcd);
-+ return retval;
-+}
-+
-+
-+/* may be called without controller electrically present */
-+/* may be called with controller, bus, and devices active */
-+
-+/**
-+ * usb_hcd_at91_remove - shutdown processing for AT91RM9200-based HCDs
-+ * @dev: USB Host Controller being removed
-+ * Context: !in_interrupt()
-+ *
-+ * Reverses the effect of usb_hcd_at91_probe(), first invoking
-+ * the HCD's stop() method. It is always called from a thread
-+ * context, normally "rmmod", "apmd", or something similar.
-+ *
-+ */
-+static int usb_hcd_at91_remove (struct usb_hcd *hcd, struct platform_device *pdev)
-+{
-+ usb_remove_hcd(hcd);
-+ at91_stop_hc(pdev);
-+ iounmap(hcd->regs);
-+ release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
-+
-+ clk_put(fclk);
-+ clk_put(iclk);
-+ fclk = iclk = NULL;
-+
-+ dev_set_drvdata(&pdev->dev, NULL);
-+ return 0;
-+}
-+
-+/*-------------------------------------------------------------------------*/
-+
-+static int __devinit
-+ohci_at91_start (struct usb_hcd *hcd)
-+{
-+// struct at91_ohci_data *board = hcd->self.controller->platform_data;
-+ struct ohci_hcd *ohci = hcd_to_ohci (hcd);
-+ int ret;
-+
-+ if ((ret = ohci_init(ohci)) < 0)
-+ return ret;
-+
-+ if ((ret = ohci_run(ohci)) < 0) {
-+ err("can't start %s", hcd->self.bus_name);
-+ ohci_stop(hcd);
-+ return ret;
-+ }
-+// hcd->self.root_hub->maxchild = board->ports;
-+ return 0;
-+}
-+
-+/*-------------------------------------------------------------------------*/
-+
-+static const struct hc_driver ohci_at91_hc_driver = {
-+ .description = hcd_name,
-+ .product_desc = "AT91RM9200 OHCI",
-+ .hcd_priv_size = sizeof(struct ohci_hcd),
-+
-+ /*
-+ * generic hardware linkage
-+ */
-+ .irq = ohci_irq,
-+ .flags = HCD_USB11 | HCD_MEMORY,
-+
-+ /*
-+ * basic lifecycle operations
-+ */
-+ .start = ohci_at91_start,
-+ .stop = ohci_stop,
-+
-+ /*
-+ * managing i/o requests and associated device resources
-+ */
-+ .urb_enqueue = ohci_urb_enqueue,
-+ .urb_dequeue = ohci_urb_dequeue,
-+ .endpoint_disable = ohci_endpoint_disable,
-+
-+ /*
-+ * scheduling support
-+ */
-+ .get_frame_number = ohci_get_frame,
-+
-+ /*
-+ * root hub support
-+ */
-+ .hub_status_data = ohci_hub_status_data,
-+ .hub_control = ohci_hub_control,
-+
-+#ifdef CONFIG_PM
-+ .hub_suspend = ohci_hub_suspend,
-+ .hub_resume = ohci_hub_resume,
-+#endif
-+ .start_port_reset = ohci_start_port_reset,
-+};
-+
-+/*-------------------------------------------------------------------------*/
-+
-+static int ohci_hcd_at91_drv_probe(struct platform_device *dev)
-+{
-+ return usb_hcd_at91_probe(&ohci_at91_hc_driver, dev);
-+}
-+
-+static int ohci_hcd_at91_drv_remove(struct platform_device *dev)
-+{
-+ return usb_hcd_at91_remove(platform_get_drvdata(dev), dev);
-+}
-+
-+#ifdef CONFIG_PM
-+static int ohci_hcd_at91_drv_suspend(struct platform_device *dev, u32 state, u32 level)
-+{
-+ printk("%s(%s:%d): not implemented yet\n",
-+ __func__, __FILE__, __LINE__);
-+
-+ clk_disable(fclk);
-+
-+ return 0;
-+}
-+
-+static int ohci_hcd_at91_drv_resume(struct platform_device *dev, u32 state)
-+{
-+ printk("%s(%s:%d): not implemented yet\n",
-+ __func__, __FILE__, __LINE__);
-+
-+ clk_enable(fclk);
-+
-+ return 0;
-+}
-+#else
-+#define ohci_hcd_at91_drv_suspend NULL
-+#define ohci_hcd_at91_drv_resume NULL
-+#endif
-+
-+static struct platform_driver ohci_hcd_at91_driver = {
-+ .probe = ohci_hcd_at91_drv_probe,
-+ .remove = ohci_hcd_at91_drv_remove,
-+ .suspend = ohci_hcd_at91_drv_suspend,
-+ .resume = ohci_hcd_at91_drv_resume,
-+ .driver = {
-+ .name = "at91rm9200-ohci",
-+ .owner = THIS_MODULE,
-+ },
-+};
-+
-+static int __init ohci_hcd_at91_init (void)
-+{
-+ if (usb_disabled())
-+ return -ENODEV;
-+
-+ return platform_driver_register(&ohci_hcd_at91_driver);
-+}
-+
-+static void __exit ohci_hcd_at91_cleanup (void)
-+{
-+ platform_driver_unregister(&ohci_hcd_at91_driver);
-+}
-+
-+module_init (ohci_hcd_at91_init);
-+module_exit (ohci_hcd_at91_cleanup);
---- gregkh-2.6.orig/drivers/usb/host/ohci-hcd.c
-+++ gregkh-2.6/drivers/usb/host/ohci-hcd.c
-@@ -905,6 +905,10 @@ MODULE_LICENSE ("GPL");
- #include "ohci-ppc-soc.c"
- #endif
-
-+#ifdef CONFIG_ARCH_AT91RM9200
-+#include "ohci-at91.c"
-+#endif
-+
- #if !(defined(CONFIG_PCI) \
- || defined(CONFIG_SA1111) \
- || defined(CONFIG_ARCH_S3C2410) \
-@@ -913,6 +917,7 @@ MODULE_LICENSE ("GPL");
- || defined (CONFIG_PXA27x) \
- || defined (CONFIG_SOC_AU1X00) \
- || defined (CONFIG_USB_OHCI_HCD_PPC_SOC) \
-+ || defined (CONFIG_ARCH_AT91RM9200) \
- )
- #error "missing bus glue for ohci-hcd"
- #endif
diff --git a/usb/usb-add-zc0301-video4linux2-driver.patch b/usb/usb-add-zc0301-video4linux2-driver.patch
deleted file mode 100644
index 3e395f248ee79..0000000000000
--- a/usb/usb-add-zc0301-video4linux2-driver.patch
+++ /dev/null
@@ -1,3023 +0,0 @@
-From luca.risolia@studio.unibo.it Mon Feb 6 07:28:12 2006
-Date: Mon, 6 Feb 2006 16:29:35 +0000
-From: Luca Risolia <luca.risolia@studio.unibo.it>
-To: Greg Kroah-Hartman <gregkh@suse.de>
-Cc: Mauro Carvalho <mchehab@brturbo.com.br>
-Subject: USB: Add ZC0301 Video4Linux2 driver
-Message-ID: <20060206162935.GA10356@studio.unibo.it>
-Content-Disposition: inline
-
-This patch adds a Video4Linux2 driver for ZC0301
-Image Processor and Control Chip.
-
-Signed-off-by: Luca Risolia <luca.risolia@studio.unibo.it>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-
----
- Documentation/usb/zc0301.txt | 250 ++++
- MAINTAINERS | 8
- drivers/usb/Makefile | 1
- drivers/usb/media/Kconfig | 15
- drivers/usb/media/Makefile | 2
- drivers/usb/media/zc0301.h | 185 +++
- drivers/usb/media/zc0301_core.c | 2028 +++++++++++++++++++++++++++++++++++
- drivers/usb/media/zc0301_pas202bcb.c | 353 ++++++
- drivers/usb/media/zc0301_sensor.h | 98 +
- 9 files changed, 2940 insertions(+)
-
---- /dev/null
-+++ gregkh-2.6/Documentation/usb/zc0301.txt
-@@ -0,0 +1,250 @@
-+
-+ ZC0301 Image Processor and Control Chip
-+ Driver for Linux
-+ =======================================
-+
-+ - Documentation -
-+
-+
-+Index
-+=====
-+1. Copyright
-+2. Disclaimer
-+3. License
-+4. Overview and features
-+5. Module dependencies
-+6. Module loading
-+7. Module parameters
-+8. Supported devices
-+9. Notes for V4L2 application developers
-+10. Contact information
-+11. Credits
-+
-+
-+1. Copyright
-+============
-+Copyright (C) 2006 by Luca Risolia <luca.risolia@studio.unibo.it>
-+
-+
-+2. Disclaimer
-+=============
-+This software is not developed or sponsored by Z-Star Microelectronics Corp.
-+Trademarks are property of their respective owner.
-+
-+
-+3. License
-+==========
-+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.
-+
-+
-+4. Overview and features
-+========================
-+This driver supports the video interface of the devices mounting the ZC0301
-+Image Processor and Control Chip.
-+
-+The driver relies on the Video4Linux2 and USB core modules. It has been
-+designed to run properly on SMP systems as well.
-+
-+The latest version of the ZC0301 driver can be found at the following URL:
-+http://www.linux-projects.org/
-+
-+Some of the features of the driver are:
-+
-+- full compliance with the Video4Linux2 API (see also "Notes for V4L2
-+ application developers" paragraph);
-+- available mmap or read/poll methods for video streaming through isochronous
-+ data transfers;
-+- automatic detection of image sensor;
-+- video formats is standard JPEG in various compression qualities
-+ (see also "Notes for V4L2 application developers" paragraph);
-+- 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
-+ disconnected from the host many times without turning off the computer, if
-+ the system supports hotplugging;
-+
-+
-+5. Module dependencies
-+======================
-+For it to work properly, the driver needs kernel support for Video4Linux and
-+USB.
-+
-+The following options of the kernel configuration file must be enabled and
-+corresponding modules must be compiled:
-+
-+ # Multimedia devices
-+ #
-+ CONFIG_VIDEO_DEV=m
-+
-+ # USB support
-+ #
-+ CONFIG_USB=m
-+
-+In addition, depending on the hardware being used, the modules below are
-+necessary:
-+
-+ # USB Host Controller Drivers
-+ #
-+ CONFIG_USB_EHCI_HCD=m
-+ CONFIG_USB_UHCI_HCD=m
-+ CONFIG_USB_OHCI_HCD=m
-+
-+The ZC0301 controller also provides a built-in microphone interface. It is
-+supported by the USB Audio driver thanks to the ALSA API:
-+
-+ # Sound
-+ #
-+ CONFIG_SOUND=y
-+
-+ # Advanced Linux Sound Architecture
-+ #
-+ CONFIG_SND=m
-+
-+ # USB devices
-+ #
-+ CONFIG_SND_USB_AUDIO=m
-+
-+And finally:
-+
-+ # USB Multimedia devices
-+ #
-+ CONFIG_USB_ZC0301=m
-+
-+
-+6. Module loading
-+=================
-+To use the driver, it is necessary to load the "zc0301" module into memory
-+after every other module required: "videodev", "usbcore" and, depending on
-+the USB host controller you have, "ehci-hcd", "uhci-hcd" or "ohci-hcd".
-+
-+Loading can be done as shown below:
-+
-+ [root@localhost home]# modprobe zc0301
-+
-+At this point the devices should be recognized. You can invoke "dmesg" to
-+analyze kernel messages and verify that the loading process has gone well:
-+
-+ [user@localhost home]$ dmesg
-+
-+
-+7. Module parameters
-+====================
-+Module parameters are listed below:
-+-------------------------------------------------------------------------------
-+Name: video_nr
-+Type: short array (min = 0, max = 64)
-+Syntax: <-1|n[,...]>
-+Description: Specify V4L2 minor mode number:
-+ -1 = use next available
-+ n = use minor number n
-+ You can specify up to 64 cameras this way.
-+ For example:
-+ video_nr=-1,2,-1 would assign minor number 2 to the second
-+ registered camera and use auto for the first one and for every
-+ other camera.
-+Default: -1
-+-------------------------------------------------------------------------------
-+Name: force_munmap
-+Type: bool array (min = 0, max = 64)
-+Syntax: <0|1[,...]>
-+Description: Force the application to unmap previously mapped buffer memory
-+ before calling any VIDIOC_S_CROP or VIDIOC_S_FMT ioctl's. Not
-+ all the applications support this feature. This parameter is
-+ specific for each detected camera.
-+ 0 = do not force memory unmapping
-+ 1 = force memory unmapping (save memory)
-+Default: 0
-+-------------------------------------------------------------------------------
-+Name: debug
-+Type: ushort
-+Syntax: <n>
-+Description: Debugging information level, from 0 to 3:
-+ 0 = none (use carefully)
-+ 1 = critical errors
-+ 2 = significant informations
-+ 3 = more verbose messages
-+ Level 3 is useful for testing only, when only one device
-+ is used at the same time. It also shows some more informations
-+ about the hardware being detected. This module parameter can be
-+ changed at runtime thanks to the /sys filesystem interface.
-+Default: 2
-+-------------------------------------------------------------------------------
-+
-+
-+8. Supported devices
-+====================
-+None of the names of the companies as well as their products will be mentioned
-+here. They have never collaborated with the author, so no advertising.
-+
-+From the point of view of a driver, what unambiguously identify a device are
-+its vendor and product USB identifiers. Below is a list of known identifiers of
-+devices mounting the ZC0301 Image Processor and Control Chips:
-+
-+Vendor ID Product ID
-+--------- ----------
-+0x046d 0x08ae
-+
-+The following image sensors are supported:
-+
-+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
-+========================================
-+This driver follows the V4L2 API specifications. In particular, it enforces two
-+rules:
-+
-+- exactly one I/O method, either "mmap" or "read", is associated with each
-+file descriptor. Once it is selected, the application must close and reopen the
-+device to switch to the other I/O method;
-+
-+- although it is not mandatory, previously mapped buffer memory should always
-+be unmapped before calling any "VIDIOC_S_CROP" or "VIDIOC_S_FMT" ioctl's.
-+The same number of buffers as before will be allocated again to match the size
-+of the new video frames, so you have to map the buffers again before any I/O
-+attempts on them.
-+
-+This driver supports the standard JPEG video format. The current compression
-+quality may vary from 0 to 3 and can be selected or queried thanks to the
-+VIDIOC_S_JPEGCOMP and VIDIOC_G_JPEGCOMP V4L2 ioctl's.
-+
-+
-+10. Contact information
-+=======================
-+The author may be contacted by e-mail at <luca.risolia@studio.unibo.it>.
-+
-+GPG/PGP encrypted e-mail's are accepted. The GPG key ID of the author is
-+'FCE635A4'; the public 1024-bit key should be available at any keyserver;
-+the fingerprint is: '88E8 F32F 7244 68BA 3958 5D40 99DA 5D2A FCE6 35A4'.
-+
-+
-+11. Credits
-+===========
-+- Informations about the chip internals 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 connected to the PAS202BCB image sensor
-+ have been taken from the SPCA5XX driver maintained by
-+ Michel Xhaard <mxhaard@magic.fr>
---- gregkh-2.6.orig/MAINTAINERS
-+++ gregkh-2.6/MAINTAINERS
-@@ -2901,6 +2901,14 @@ L: video4linux-list@redhat.com
- W: http://www.linux-projects.org
- S: Maintained
-
-+USB ZC0301 DRIVER
-+P: Luca Risolia
-+M: luca.risolia@studio.unibo.it
-+L: linux-usb-devel@lists.sourceforge.net
-+L: video4linux-list@redhat.com
-+W: http://www.linux-projects.org
-+S: Maintained
-+
- USB ZD1201 DRIVER
- P: Jeroen Vreeken
- M: pe1rxq@amsat.org
---- gregkh-2.6.orig/drivers/usb/Makefile
-+++ gregkh-2.6/drivers/usb/Makefile
-@@ -48,6 +48,7 @@ obj-$(CONFIG_USB_SN9C102) += media/
- obj-$(CONFIG_USB_STV680) += media/
- obj-$(CONFIG_USB_VICAM) += media/
- obj-$(CONFIG_USB_W9968CF) += media/
-+obj-$(CONFIG_USB_ZC0301) += media/
-
- obj-$(CONFIG_USB_CATC) += net/
- obj-$(CONFIG_USB_KAWETH) += net/
---- gregkh-2.6.orig/drivers/usb/media/Kconfig
-+++ gregkh-2.6/drivers/usb/media/Kconfig
-@@ -191,6 +191,21 @@ config USB_W9968CF
- To compile this driver as a module, choose M here: the
- module will be called w9968cf.
-
-+config USB_ZC0301
-+ tristate "USB ZC0301 Image Processor and Control Chip support"
-+ depends on USB && VIDEO_DEV
-+ ---help---
-+ Say Y here if you want support for cameras based on the ZC0301
-+ Image Processor and Control Chip.
-+
-+ See <file:Documentation/usb/zc0301.txt> for more informations.
-+
-+ This driver uses the Video For Linux API. You must say Y or M to
-+ "Video For Linux" to use this driver.
-+
-+ To compile this driver as a module, choose M here: the
-+ module will be called zc0301.
-+
- config USB_PWC
- tristate "USB Philips Cameras"
- depends on USB && VIDEO_DEV
---- gregkh-2.6.orig/drivers/usb/media/Makefile
-+++ gregkh-2.6/drivers/usb/media/Makefile
-@@ -4,6 +4,7 @@
-
- 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
- et61x251-objs := et61x251_core.o et61x251_tas5130d1b.o
-+zc0301-objs := zc0301_core.o zc0301_pas202bcb.o
-
- obj-$(CONFIG_USB_DABUSB) += dabusb.o
- obj-$(CONFIG_USB_DSBR) += dsbr100.o
-@@ -16,4 +17,5 @@ obj-$(CONFIG_USB_SN9C102) += sn9c102.o
- obj-$(CONFIG_USB_STV680) += stv680.o
- obj-$(CONFIG_USB_VICAM) += vicam.o usbvideo.o
- obj-$(CONFIG_USB_W9968CF) += w9968cf.o
-+obj-$(CONFIG_USB_ZC0301) += zc0301.o
- obj-$(CONFIG_USB_PWC) += pwc/
---- /dev/null
-+++ gregkh-2.6/drivers/usb/media/zc0301.h
-@@ -0,0 +1,185 @@
-+/***************************************************************************
-+ * V4L2 driver for ZC0301 Image Processor and Control Chip *
-+ * *
-+ * 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. *
-+ ***************************************************************************/
-+
-+#ifndef _ZC0301_H_
-+#define _ZC0301_H_
-+
-+#include <linux/version.h>
-+#include <linux/usb.h>
-+#include <linux/videodev2.h>
-+#include <media/v4l2-common.h>
-+#include <linux/device.h>
-+#include <linux/list.h>
-+#include <linux/spinlock.h>
-+#include <linux/time.h>
-+#include <linux/wait.h>
-+#include <linux/types.h>
-+#include <linux/param.h>
-+#include <linux/mutex.h>
-+#include <linux/rwsem.h>
-+#include <asm/semaphore.h>
-+
-+#include "zc0301_sensor.h"
-+
-+/*****************************************************************************/
-+
-+#define ZC0301_DEBUG
-+#define ZC0301_DEBUG_LEVEL 2
-+#define ZC0301_MAX_DEVICES 64
-+#define ZC0301_FORCE_MUNMAP 0
-+#define ZC0301_MAX_FRAMES 32
-+#define ZC0301_COMPRESSION_QUALITY 2
-+#define ZC0301_URBS 2
-+#define ZC0301_ISO_PACKETS 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)
-+
-+/*****************************************************************************/
-+
-+ZC0301_ID_TABLE
-+ZC0301_SENSOR_TABLE
-+
-+enum zc0301_frame_state {
-+ F_UNUSED,
-+ F_QUEUED,
-+ F_GRABBING,
-+ F_DONE,
-+ F_ERROR,
-+};
-+
-+struct zc0301_frame_t {
-+ void* bufmem;
-+ struct v4l2_buffer buf;
-+ enum zc0301_frame_state state;
-+ struct list_head frame;
-+ unsigned long vma_use_count;
-+};
-+
-+enum zc0301_dev_state {
-+ DEV_INITIALIZED = 0x01,
-+ DEV_DISCONNECTED = 0x02,
-+ DEV_MISCONFIGURED = 0x04,
-+};
-+
-+enum zc0301_io_method {
-+ IO_NONE,
-+ IO_READ,
-+ IO_MMAP,
-+};
-+
-+enum zc0301_stream_state {
-+ STREAM_OFF,
-+ STREAM_INTERRUPT,
-+ STREAM_ON,
-+};
-+
-+struct zc0301_module_param {
-+ u8 force_munmap;
-+};
-+
-+static DECLARE_RWSEM(zc0301_disconnect);
-+
-+struct zc0301_device {
-+ struct video_device* v4ldev;
-+
-+ struct zc0301_sensor* sensor;
-+
-+ struct usb_device* usbdev;
-+ struct urb* urb[ZC0301_URBS];
-+ void* transfer_buffer[ZC0301_URBS];
-+ u8* control_buffer;
-+
-+ struct zc0301_frame_t *frame_current, frame[ZC0301_MAX_FRAMES];
-+ struct list_head inqueue, outqueue;
-+ u32 frame_count, nbuffers, nreadbuffers;
-+
-+ enum zc0301_io_method io;
-+ enum zc0301_stream_state stream;
-+
-+ struct v4l2_jpegcompression compression;
-+
-+ struct zc0301_module_param module_param;
-+
-+ enum zc0301_dev_state state;
-+ u8 users;
-+
-+ struct mutex dev_mutex, fileop_mutex;
-+ spinlock_t queue_lock;
-+ wait_queue_head_t open, wait_frame, wait_stream;
-+};
-+
-+/*****************************************************************************/
-+
-+void
-+zc0301_attach_sensor(struct zc0301_device* cam, struct zc0301_sensor* sensor)
-+{
-+ cam->sensor = sensor;
-+ cam->sensor->usbdev = cam->usbdev;
-+}
-+
-+/*****************************************************************************/
-+
-+#undef DBG
-+#undef KDBG
-+#ifdef ZC0301_DEBUG
-+# define DBG(level, fmt, args...) \
-+do { \
-+ if (debug >= (level)) { \
-+ if ((level) == 1) \
-+ dev_err(&cam->usbdev->dev, fmt "\n", ## args); \
-+ else if ((level) == 2) \
-+ dev_info(&cam->usbdev->dev, fmt "\n", ## args); \
-+ else if ((level) >= 3) \
-+ dev_info(&cam->usbdev->dev, "[%s:%d] " fmt "\n", \
-+ __FUNCTION__, __LINE__ , ## args); \
-+ } \
-+} while (0)
-+# define KDBG(level, fmt, args...) \
-+do { \
-+ if (debug >= (level)) { \
-+ if ((level) == 1 || (level) == 2) \
-+ pr_info("zc0301: " fmt "\n", ## args); \
-+ else if ((level) == 3) \
-+ pr_debug("zc0301: [%s:%d] " fmt "\n", __FUNCTION__, \
-+ __LINE__ , ## args); \
-+ } \
-+} while (0)
-+# define V4LDBG(level, name, cmd) \
-+do { \
-+ if (debug >= (level)) \
-+ v4l_print_ioctl(name, cmd); \
-+} while (0)
-+#else
-+# define DBG(level, fmt, args...) do {;} while(0)
-+# define KDBG(level, fmt, args...) do {;} while(0)
-+# define V4LDBG(level, name, cmd) do {;} while(0)
-+#endif
-+
-+#undef PDBG
-+#define PDBG(fmt, args...) \
-+dev_info(&cam->usbdev->dev, "[%s:%d] " fmt "\n", \
-+ __FUNCTION__, __LINE__ , ## args)
-+
-+#undef PDBGG
-+#define PDBGG(fmt, args...) do {;} while(0) /* placeholder */
-+
-+#endif /* _ZC0301_H_ */
---- /dev/null
-+++ gregkh-2.6/drivers/usb/media/zc0301_core.c
-@@ -0,0 +1,2028 @@
-+/***************************************************************************
-+ * Video4Linux2 driver for ZC0301 Image Processor and Control Chip *
-+ * *
-+ * Copyright (C) 2006 by Luca Risolia <luca.risolia@studio.unibo.it> *
-+ * *
-+ * Informations about the chip internals to enable the I2C protocol have *
-+ * been taken from the documentation of the ZC030x Video4Linux1 driver *
-+ * written by Andrew Birkett <andy@nobugs.org> *
-+ * *
-+ * 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/module.h>
-+#include <linux/init.h>
-+#include <linux/kernel.h>
-+#include <linux/param.h>
-+#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>
-+#include <linux/stat.h>
-+#include <linux/mm.h>
-+#include <linux/vmalloc.h>
-+#include <linux/page-flags.h>
-+#include <linux/byteorder/generic.h>
-+#include <asm/page.h>
-+#include <asm/uaccess.h>
-+
-+#include "zc0301.h"
-+
-+/*****************************************************************************/
-+
-+#define ZC0301_MODULE_NAME "V4L2 driver for ZC0301 " \
-+ "Image Processor and Control Chip"
-+#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.00"
-+#define ZC0301_MODULE_VERSION_CODE KERNEL_VERSION(1, 0, 0)
-+
-+/*****************************************************************************/
-+
-+MODULE_DEVICE_TABLE(usb, zc0301_id_table);
-+
-+MODULE_AUTHOR(ZC0301_MODULE_AUTHOR " " ZC0301_AUTHOR_EMAIL);
-+MODULE_DESCRIPTION(ZC0301_MODULE_NAME);
-+MODULE_VERSION(ZC0301_MODULE_VERSION);
-+MODULE_LICENSE(ZC0301_MODULE_LICENSE);
-+
-+static short video_nr[] = {[0 ... ZC0301_MAX_DEVICES-1] = -1};
-+module_param_array(video_nr, short, NULL, 0444);
-+MODULE_PARM_DESC(video_nr,
-+ "\n<-1|n[,...]> Specify V4L2 minor mode number."
-+ "\n -1 = use next available (default)"
-+ "\n n = use minor number n (integer >= 0)"
-+ "\nYou can specify up to "
-+ __MODULE_STRING(ZC0301_MAX_DEVICES) " cameras this way."
-+ "\nFor example:"
-+ "\nvideo_nr=-1,2,-1 would assign minor number 2 to"
-+ "\nthe second registered camera and use auto for the first"
-+ "\none and for every other camera."
-+ "\n");
-+
-+static short force_munmap[] = {[0 ... ZC0301_MAX_DEVICES-1] =
-+ ZC0301_FORCE_MUNMAP};
-+module_param_array(force_munmap, bool, NULL, 0444);
-+MODULE_PARM_DESC(force_munmap,
-+ "\n<0|1[,...]> Force the application to unmap previously"
-+ "\nmapped buffer memory before calling any VIDIOC_S_CROP or"
-+ "\nVIDIOC_S_FMT ioctl's. Not all the applications support"
-+ "\nthis feature. This parameter is specific for each"
-+ "\ndetected camera."
-+ "\n 0 = do not force memory unmapping"
-+ "\n 1 = force memory unmapping (save memory)"
-+ "\nDefault value is "__MODULE_STRING(SN9C102_FORCE_MUNMAP)"."
-+ "\n");
-+
-+#ifdef ZC0301_DEBUG
-+static unsigned short debug = ZC0301_DEBUG_LEVEL;
-+module_param(debug, ushort, 0644);
-+MODULE_PARM_DESC(debug,
-+ "\n<n> Debugging information level, from 0 to 3:"
-+ "\n0 = none (use carefully)"
-+ "\n1 = critical errors"
-+ "\n2 = significant informations"
-+ "\n3 = more verbose messages"
-+ "\nLevel 3 is useful for testing only, when only "
-+ "one device is used."
-+ "\nDefault value is "__MODULE_STRING(ZC0301_DEBUG_LEVEL)"."
-+ "\n");
-+#endif
-+
-+/*****************************************************************************/
-+
-+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);
-+ const size_t imagesize = cam->module_param.force_munmap ||
-+ io == IO_READ ?
-+ (p->width * p->height * p->priv) / 8 :
-+ (r->width * r->height * p->priv) / 8;
-+ void* buff = NULL;
-+ u32 i;
-+
-+ if (count > ZC0301_MAX_FRAMES)
-+ count = ZC0301_MAX_FRAMES;
-+
-+ cam->nbuffers = count;
-+ while (cam->nbuffers > 0) {
-+ if ((buff = vmalloc_32(cam->nbuffers * PAGE_ALIGN(imagesize))))
-+ break;
-+ cam->nbuffers--;
-+ }
-+
-+ for (i = 0; i < cam->nbuffers; i++) {
-+ cam->frame[i].bufmem = buff + i*PAGE_ALIGN(imagesize);
-+ cam->frame[i].buf.index = i;
-+ cam->frame[i].buf.m.offset = i*PAGE_ALIGN(imagesize);
-+ cam->frame[i].buf.length = imagesize;
-+ cam->frame[i].buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-+ cam->frame[i].buf.sequence = 0;
-+ cam->frame[i].buf.field = V4L2_FIELD_NONE;
-+ cam->frame[i].buf.memory = V4L2_MEMORY_MMAP;
-+ cam->frame[i].buf.flags = 0;
-+ }
-+
-+ return cam->nbuffers;
-+}
-+
-+
-+static void zc0301_release_buffers(struct zc0301_device* cam)
-+{
-+ if (cam->nbuffers) {
-+ vfree(cam->frame[0].bufmem);
-+ cam->nbuffers = 0;
-+ }
-+ cam->frame_current = NULL;
-+}
-+
-+
-+static void zc0301_empty_framequeues(struct zc0301_device* cam)
-+{
-+ u32 i;
-+
-+ INIT_LIST_HEAD(&cam->inqueue);
-+ INIT_LIST_HEAD(&cam->outqueue);
-+
-+ for (i = 0; i < ZC0301_MAX_FRAMES; i++) {
-+ cam->frame[i].state = F_UNUSED;
-+ cam->frame[i].buf.bytesused = 0;
-+ }
-+}
-+
-+
-+static void zc0301_requeue_outqueue(struct zc0301_device* cam)
-+{
-+ struct zc0301_frame_t *i;
-+
-+ list_for_each_entry(i, &cam->outqueue, frame) {
-+ i->state = F_QUEUED;
-+ list_add(&i->frame, &cam->inqueue);
-+ }
-+
-+ INIT_LIST_HEAD(&cam->outqueue);
-+}
-+
-+
-+static void zc0301_queue_unusedframes(struct zc0301_device* cam)
-+{
-+ unsigned long lock_flags;
-+ u32 i;
-+
-+ for (i = 0; i < cam->nbuffers; i++)
-+ if (cam->frame[i].state == F_UNUSED) {
-+ cam->frame[i].state = F_QUEUED;
-+ spin_lock_irqsave(&cam->queue_lock, lock_flags);
-+ list_add_tail(&cam->frame[i].frame, &cam->inqueue);
-+ spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
-+ }
-+}
-+
-+/*****************************************************************************/
-+
-+int zc0301_write_reg(struct zc0301_device* cam, u16 index, u16 value)
-+{
-+ struct usb_device* udev = cam->usbdev;
-+ int res;
-+
-+ res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0xa0, 0x40,
-+ value, index, NULL, 0, ZC0301_CTRL_TIMEOUT);
-+ if (res < 0) {
-+ DBG(3, "Failed to write a register (index 0x%04X, "
-+ "value 0x%02X, error %d)",index, value, res);
-+ return -1;
-+ }
-+
-+ return 0;
-+}
-+
-+
-+int zc0301_read_reg(struct zc0301_device* cam, u16 index)
-+{
-+ struct usb_device* udev = cam->usbdev;
-+ u8* buff = cam->control_buffer;
-+ int res;
-+
-+ res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0xa1, 0xc0,
-+ 0x0001, index, buff, 1, ZC0301_CTRL_TIMEOUT);
-+ if (res < 0)
-+ DBG(3, "Failed to read a register (index 0x%04X, error %d)",
-+ index, res);
-+
-+ PDBGG("Read: index 0x%04X, value: 0x%04X", index, (int)(*buff));
-+
-+ return (res >= 0) ? (int)(*buff) : -1;
-+}
-+
-+
-+int zc0301_i2c_read(struct zc0301_device* cam, u16 address, u8 length)
-+{
-+ int err = 0, res, r0, r1;
-+
-+ err += zc0301_write_reg(cam, 0x0092, address);
-+ err += zc0301_write_reg(cam, 0x0090, 0x02);
-+
-+ msleep(1);
-+
-+ res = zc0301_read_reg(cam, 0x0091);
-+ if (res < 0)
-+ err += res;
-+ r0 = zc0301_read_reg(cam, 0x0095);
-+ if (r0 < 0)
-+ err += r0;
-+ r1 = zc0301_read_reg(cam, 0x0096);
-+ if (r1 < 0)
-+ err += r1;
-+
-+ res = (length <= 1) ? r0 : r0 | (r1 << 8);
-+
-+ if (err)
-+ DBG(3, "I2C read failed at address 0x%04X, value: 0x%04X",
-+ address, res);
-+
-+
-+ PDBGG("I2C read: address 0x%04X, value: 0x%04X", address, res);
-+
-+ return err ? -1 : res;
-+}
-+
-+
-+int zc0301_i2c_write(struct zc0301_device* cam, u16 address, u16 value)
-+{
-+ int err = 0, res;
-+
-+ err += zc0301_write_reg(cam, 0x0092, address);
-+ err += zc0301_write_reg(cam, 0x0093, value & 0xff);
-+ err += zc0301_write_reg(cam, 0x0094, value >> 8);
-+ err += zc0301_write_reg(cam, 0x0090, 0x01);
-+
-+ msleep(1);
-+
-+ res = zc0301_read_reg(cam, 0x0091);
-+ if (res < 0)
-+ err += res;
-+
-+ if (err)
-+ DBG(3, "I2C write failed at address 0x%04X, value: 0x%04X",
-+ address, value);
-+
-+ PDBGG("I2C write: address 0x%04X, value: 0x%04X", address, value);
-+
-+ return err ? -1 : 0;
-+}
-+
-+/*****************************************************************************/
-+
-+static void zc0301_urb_complete(struct urb *urb, struct pt_regs* regs)
-+{
-+ struct zc0301_device* cam = urb->context;
-+ struct zc0301_frame_t** f;
-+ size_t imagesize;
-+ u8 i;
-+ int err = 0;
-+
-+ if (urb->status == -ENOENT)
-+ return;
-+
-+ f = &cam->frame_current;
-+
-+ if (cam->stream == STREAM_INTERRUPT) {
-+ cam->stream = STREAM_OFF;
-+ if ((*f))
-+ (*f)->state = F_QUEUED;
-+ DBG(3, "Stream interrupted");
-+ wake_up_interruptible(&cam->wait_stream);
-+ }
-+
-+ if (cam->state & DEV_DISCONNECTED)
-+ return;
-+
-+ if (cam->state & DEV_MISCONFIGURED) {
-+ wake_up_interruptible(&cam->wait_frame);
-+ return;
-+ }
-+
-+ if (cam->stream == STREAM_OFF || list_empty(&cam->inqueue))
-+ goto resubmit_urb;
-+
-+ if (!(*f))
-+ (*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;
-+
-+ for (i = 0; i < urb->number_of_packets; i++) {
-+ unsigned int len, status;
-+ void *pos;
-+ u16* soi;
-+ u8 sof;
-+
-+ len = urb->iso_frame_desc[i].actual_length;
-+ status = urb->iso_frame_desc[i].status;
-+ pos = urb->iso_frame_desc[i].offset + urb->transfer_buffer;
-+
-+ if (status) {
-+ DBG(3, "Error in isochronous frame");
-+ (*f)->state = F_ERROR;
-+ continue;
-+ }
-+
-+ sof = (*(soi = pos) == 0xd8ff);
-+
-+ PDBGG("Isochrnous frame: length %u, #%u i,", len, i);
-+
-+ if ((*f)->state == F_QUEUED || (*f)->state == F_ERROR)
-+start_of_frame:
-+ if (sof) {
-+ (*f)->state = F_GRABBING;
-+ (*f)->buf.bytesused = 0;
-+ do_gettimeofday(&(*f)->buf.timestamp);
-+ DBG(3, "SOF detected: new video frame");
-+ }
-+
-+ if ((*f)->state == F_GRABBING) {
-+ if (sof && (*f)->buf.bytesused)
-+ goto end_of_frame;
-+
-+ if ((*f)->buf.bytesused + len > imagesize) {
-+ DBG(3, "Video frame size exceeded");
-+ (*f)->state = F_ERROR;
-+ continue;
-+ }
-+
-+ memcpy((*f)->bufmem+(*f)->buf.bytesused, pos, len);
-+ (*f)->buf.bytesused += len;
-+
-+ if ((*f)->buf.bytesused == imagesize) {
-+ u32 b;
-+end_of_frame:
-+ b = (*f)->buf.bytesused;
-+ (*f)->state = F_DONE;
-+ (*f)->buf.sequence= ++cam->frame_count;
-+ spin_lock(&cam->queue_lock);
-+ list_move_tail(&(*f)->frame, &cam->outqueue);
-+ if (!list_empty(&cam->inqueue))
-+ (*f) = list_entry(cam->inqueue.next,
-+ struct zc0301_frame_t,
-+ frame);
-+ else
-+ (*f) = NULL;
-+ spin_unlock(&cam->queue_lock);
-+ DBG(3, "Video frame captured: : %lu bytes",
-+ (unsigned long)(b));
-+
-+ if (!(*f))
-+ goto resubmit_urb;
-+
-+ if (sof)
-+ goto start_of_frame;
-+ }
-+ }
-+ }
-+
-+resubmit_urb:
-+ urb->dev = cam->usbdev;
-+ err = usb_submit_urb(urb, GFP_ATOMIC);
-+ if (err < 0 && err != -EPERM) {
-+ cam->state |= DEV_MISCONFIGURED;
-+ DBG(1, "usb_submit_urb() failed");
-+ }
-+
-+ wake_up_interruptible(&cam->wait_frame);
-+}
-+
-+
-+static int zc0301_start_transfer(struct zc0301_device* cam)
-+{
-+ struct usb_device *udev = cam->usbdev;
-+ struct urb* urb;
-+ const unsigned int wMaxPacketSize[] = {0, 128, 192, 256, 384,
-+ 512, 768, 1023};
-+ const unsigned int psz = wMaxPacketSize[ZC0301_ALTERNATE_SETTING];
-+ s8 i, j;
-+ int err = 0;
-+
-+ for (i = 0; i < ZC0301_URBS; i++) {
-+ cam->transfer_buffer[i] = kzalloc(ZC0301_ISO_PACKETS * psz,
-+ GFP_KERNEL);
-+ if (!cam->transfer_buffer[i]) {
-+ err = -ENOMEM;
-+ DBG(1, "Not enough memory");
-+ goto free_buffers;
-+ }
-+ }
-+
-+ for (i = 0; i < ZC0301_URBS; i++) {
-+ urb = usb_alloc_urb(ZC0301_ISO_PACKETS, GFP_KERNEL);
-+ cam->urb[i] = urb;
-+ if (!urb) {
-+ err = -ENOMEM;
-+ DBG(1, "usb_alloc_urb() failed");
-+ goto free_urbs;
-+ }
-+ urb->dev = udev;
-+ urb->context = cam;
-+ urb->pipe = usb_rcvisocpipe(udev, 1);
-+ urb->transfer_flags = URB_ISO_ASAP;
-+ urb->number_of_packets = ZC0301_ISO_PACKETS;
-+ urb->complete = zc0301_urb_complete;
-+ urb->transfer_buffer = cam->transfer_buffer[i];
-+ urb->transfer_buffer_length = psz * ZC0301_ISO_PACKETS;
-+ urb->interval = 1;
-+ for (j = 0; j < ZC0301_ISO_PACKETS; j++) {
-+ urb->iso_frame_desc[j].offset = psz * j;
-+ urb->iso_frame_desc[j].length = psz;
-+ }
-+ }
-+
-+ err = usb_set_interface(udev, 0, ZC0301_ALTERNATE_SETTING);
-+ if (err) {
-+ DBG(1, "usb_set_interface() failed");
-+ goto free_urbs;
-+ }
-+
-+ cam->frame_current = NULL;
-+
-+ for (i = 0; i < ZC0301_URBS; i++) {
-+ err = usb_submit_urb(cam->urb[i], GFP_KERNEL);
-+ if (err) {
-+ for (j = i-1; j >= 0; j--)
-+ usb_kill_urb(cam->urb[j]);
-+ DBG(1, "usb_submit_urb() failed, error %d", err);
-+ goto free_urbs;
-+ }
-+ }
-+
-+ return 0;
-+
-+free_urbs:
-+ for (i = 0; (i < ZC0301_URBS) && cam->urb[i]; i++)
-+ usb_free_urb(cam->urb[i]);
-+
-+free_buffers:
-+ for (i = 0; (i < ZC0301_URBS) && cam->transfer_buffer[i]; i++)
-+ kfree(cam->transfer_buffer[i]);
-+
-+ return err;
-+}
-+
-+
-+static int zc0301_stop_transfer(struct zc0301_device* cam)
-+{
-+ struct usb_device *udev = cam->usbdev;
-+ s8 i;
-+ int err = 0;
-+
-+ if (cam->state & DEV_DISCONNECTED)
-+ return 0;
-+
-+ for (i = ZC0301_URBS-1; i >= 0; i--) {
-+ usb_kill_urb(cam->urb[i]);
-+ usb_free_urb(cam->urb[i]);
-+ kfree(cam->transfer_buffer[i]);
-+ }
-+
-+ err = usb_set_interface(udev, 0, 0); /* 0 Mb/s */
-+ if (err)
-+ DBG(3, "usb_set_interface() failed");
-+
-+ return err;
-+}
-+
-+
-+static int zc0301_stream_interrupt(struct zc0301_device* cam)
-+{
-+ long timeout;
-+
-+ cam->stream = STREAM_INTERRUPT;
-+ timeout = wait_event_timeout(cam->wait_stream,
-+ (cam->stream == STREAM_OFF) ||
-+ (cam->state & DEV_DISCONNECTED),
-+ ZC0301_URB_TIMEOUT);
-+ if (cam->state & DEV_DISCONNECTED)
-+ return -ENODEV;
-+ else if (!timeout) {
-+ 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 -EIO;
-+ }
-+
-+ return 0;
-+}
-+
-+/*****************************************************************************/
-+
-+static int
-+zc0301_set_compression(struct zc0301_device* cam,
-+ struct v4l2_jpegcompression* compression)
-+{
-+ int r, err = 0;
-+
-+ if ((r = zc0301_read_reg(cam, 0x0008)) < 0)
-+ err += r;
-+ err += zc0301_write_reg(cam, 0x0008,
-+ r | 0x11 | (compression->quality >> 1));
-+
-+ return err ? -EIO : 0;
-+}
-+
-+
-+static int zc0301_init(struct zc0301_device* cam)
-+{
-+ struct zc0301_sensor* s = cam->sensor;
-+ struct v4l2_control ctrl;
-+ struct v4l2_queryctrl *qctrl;
-+ struct v4l2_rect* rect;
-+ u8 i = 0;
-+ int err = 0;
-+
-+ if (!(cam->state & DEV_INITIALIZED)) {
-+ init_waitqueue_head(&cam->open);
-+ qctrl = s->qctrl;
-+ rect = &(s->cropcap.defrect);
-+ cam->compression.quality = ZC0301_COMPRESSION_QUALITY;
-+ } else { /* use current values */
-+ qctrl = s->_qctrl;
-+ rect = &(s->_rect);
-+ }
-+
-+ if (s->init) {
-+ err = s->init(cam);
-+ if (err) {
-+ DBG(3, "Sensor initialization failed");
-+ return err;
-+ }
-+ }
-+
-+ if ((err = zc0301_set_compression(cam, &cam->compression))) {
-+ DBG(3, "set_compression() failed");
-+ return err;
-+ }
-+
-+ if (s->set_crop)
-+ if ((err = s->set_crop(cam, rect))) {
-+ DBG(3, "set_crop() failed");
-+ return err;
-+ }
-+
-+ if (s->set_ctrl) {
-+ for (i = 0; i < ARRAY_SIZE(s->qctrl); i++)
-+ if (s->qctrl[i].id != 0 &&
-+ !(s->qctrl[i].flags & V4L2_CTRL_FLAG_DISABLED)) {
-+ ctrl.id = s->qctrl[i].id;
-+ ctrl.value = qctrl[i].default_value;
-+ err = s->set_ctrl(cam, &ctrl);
-+ if (err) {
-+ DBG(3, "Set %s control failed",
-+ s->qctrl[i].name);
-+ return err;
-+ }
-+ DBG(3, "Image sensor supports '%s' control",
-+ s->qctrl[i].name);
-+ }
-+ }
-+
-+ if (!(cam->state & DEV_INITIALIZED)) {
-+ mutex_init(&cam->fileop_mutex);
-+ spin_lock_init(&cam->queue_lock);
-+ init_waitqueue_head(&cam->wait_frame);
-+ init_waitqueue_head(&cam->wait_stream);
-+ cam->nreadbuffers = 2;
-+ memcpy(s->_qctrl, s->qctrl, sizeof(s->qctrl));
-+ memcpy(&(s->_rect), &(s->cropcap.defrect),
-+ sizeof(struct v4l2_rect));
-+ cam->state |= DEV_INITIALIZED;
-+ }
-+
-+ DBG(2, "Initialization succeeded");
-+ return 0;
-+}
-+
-+
-+static void zc0301_release_resources(struct zc0301_device* cam)
-+{
-+ DBG(2, "V4L2 device /dev/video%d deregistered", cam->v4ldev->minor);
-+ video_set_drvdata(cam->v4ldev, NULL);
-+ video_unregister_device(cam->v4ldev);
-+ kfree(cam->control_buffer);
-+}
-+
-+/*****************************************************************************/
-+
-+static int zc0301_open(struct inode* inode, struct file* filp)
-+{
-+ struct zc0301_device* cam;
-+ int err = 0;
-+
-+ /*
-+ This is the only safe way to prevent race conditions with
-+ disconnect
-+ */
-+ if (!down_read_trylock(&zc0301_disconnect))
-+ return -ERESTARTSYS;
-+
-+ cam = video_get_drvdata(video_devdata(filp));
-+
-+ if (mutex_lock_interruptible(&cam->dev_mutex)) {
-+ up_read(&zc0301_disconnect);
-+ return -ERESTARTSYS;
-+ }
-+
-+ if (cam->users) {
-+ DBG(2, "Device /dev/video%d is busy...", cam->v4ldev->minor);
-+ if ((filp->f_flags & O_NONBLOCK) ||
-+ (filp->f_flags & O_NDELAY)) {
-+ err = -EWOULDBLOCK;
-+ goto out;
-+ }
-+ mutex_unlock(&cam->dev_mutex);
-+ err = wait_event_interruptible_exclusive(cam->open,
-+ cam->state & DEV_DISCONNECTED
-+ || !cam->users);
-+ if (err) {
-+ up_read(&zc0301_disconnect);
-+ return err;
-+ }
-+ if (cam->state & DEV_DISCONNECTED) {
-+ up_read(&zc0301_disconnect);
-+ return -ENODEV;
-+ }
-+ mutex_lock(&cam->dev_mutex);
-+ }
-+
-+
-+ if (cam->state & DEV_MISCONFIGURED) {
-+ err = zc0301_init(cam);
-+ if (err) {
-+ DBG(1, "Initialization failed again. "
-+ "I will retry on next open().");
-+ goto out;
-+ }
-+ cam->state &= ~DEV_MISCONFIGURED;
-+ }
-+
-+ if ((err = zc0301_start_transfer(cam)))
-+ goto out;
-+
-+ filp->private_data = cam;
-+ cam->users++;
-+ cam->io = IO_NONE;
-+ cam->stream = STREAM_OFF;
-+ cam->nbuffers = 0;
-+ cam->frame_count = 0;
-+ zc0301_empty_framequeues(cam);
-+
-+ DBG(3, "Video device /dev/video%d is open", cam->v4ldev->minor);
-+
-+out:
-+ mutex_unlock(&cam->dev_mutex);
-+ up_read(&zc0301_disconnect);
-+ return err;
-+}
-+
-+
-+static int zc0301_release(struct inode* inode, struct file* filp)
-+{
-+ struct zc0301_device* cam = video_get_drvdata(video_devdata(filp));
-+
-+ mutex_lock(&cam->dev_mutex); /* prevent disconnect() to be called */
-+
-+ zc0301_stop_transfer(cam);
-+
-+ zc0301_release_buffers(cam);
-+
-+ if (cam->state & DEV_DISCONNECTED) {
-+ zc0301_release_resources(cam);
-+ mutex_unlock(&cam->dev_mutex);
-+ kfree(cam);
-+ return 0;
-+ }
-+
-+ cam->users--;
-+ wake_up_interruptible_nr(&cam->open, 1);
-+
-+ DBG(3, "Video device /dev/video%d closed", cam->v4ldev->minor);
-+
-+ mutex_unlock(&cam->dev_mutex);
-+
-+ return 0;
-+}
-+
-+
-+static ssize_t
-+zc0301_read(struct file* filp, char __user * buf,
-+ size_t count, loff_t* f_pos)
-+{
-+ struct zc0301_device* cam = video_get_drvdata(video_devdata(filp));
-+ struct zc0301_frame_t* f, * i;
-+ unsigned long lock_flags;
-+ long timeout;
-+ int err = 0;
-+
-+ if (mutex_lock_interruptible(&cam->fileop_mutex))
-+ return -ERESTARTSYS;
-+
-+ if (cam->state & DEV_DISCONNECTED) {
-+ DBG(1, "Device not present");
-+ mutex_unlock(&cam->fileop_mutex);
-+ return -ENODEV;
-+ }
-+
-+ if (cam->state & DEV_MISCONFIGURED) {
-+ DBG(1, "The camera is misconfigured. Close and open it "
-+ "again.");
-+ 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");
-+ mutex_unlock(&cam->fileop_mutex);
-+ return -EINVAL;
-+ }
-+
-+ if (cam->io == IO_NONE) {
-+ if (!zc0301_request_buffers(cam, cam->nreadbuffers, IO_READ)) {
-+ DBG(1, "read() failed, not enough memory");
-+ mutex_unlock(&cam->fileop_mutex);
-+ return -ENOMEM;
-+ }
-+ cam->io = IO_READ;
-+ cam->stream = STREAM_ON;
-+ }
-+
-+ if (list_empty(&cam->inqueue)) {
-+ if (!list_empty(&cam->outqueue))
-+ zc0301_empty_framequeues(cam);
-+ zc0301_queue_unusedframes(cam);
-+ }
-+
-+ if (!count) {
-+ mutex_unlock(&cam->fileop_mutex);
-+ return 0;
-+ }
-+
-+ if (list_empty(&cam->outqueue)) {
-+ if (filp->f_flags & O_NONBLOCK) {
-+ mutex_unlock(&cam->fileop_mutex);
-+ return -EAGAIN;
-+ }
-+ timeout = wait_event_interruptible_timeout
-+ ( cam->wait_frame,
-+ (!list_empty(&cam->outqueue)) ||
-+ (cam->state & DEV_DISCONNECTED) ||
-+ (cam->state & DEV_MISCONFIGURED),
-+ ZC0301_FRAME_TIMEOUT );
-+ if (timeout < 0) {
-+ mutex_unlock(&cam->fileop_mutex);
-+ return timeout;
-+ }
-+ if (cam->state & DEV_DISCONNECTED) {
-+ mutex_unlock(&cam->fileop_mutex);
-+ return -ENODEV;
-+ }
-+ if (!timeout || (cam->state & DEV_MISCONFIGURED)) {
-+ mutex_unlock(&cam->fileop_mutex);
-+ return -EIO;
-+ }
-+ }
-+
-+ f = list_entry(cam->outqueue.prev, struct zc0301_frame_t, frame);
-+
-+ if (count > f->buf.bytesused)
-+ count = f->buf.bytesused;
-+
-+ if (copy_to_user(buf, f->bufmem, count)) {
-+ err = -EFAULT;
-+ goto exit;
-+ }
-+ *f_pos += count;
-+
-+exit:
-+ spin_lock_irqsave(&cam->queue_lock, lock_flags);
-+ list_for_each_entry(i, &cam->outqueue, frame)
-+ i->state = F_UNUSED;
-+ INIT_LIST_HEAD(&cam->outqueue);
-+ spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
-+
-+ zc0301_queue_unusedframes(cam);
-+
-+ PDBGG("Frame #%lu, bytes read: %zu",
-+ (unsigned long)f->buf.index, count);
-+
-+ mutex_unlock(&cam->fileop_mutex);
-+
-+ return err ? err : count;
-+}
-+
-+
-+static unsigned int zc0301_poll(struct file *filp, poll_table *wait)
-+{
-+ struct zc0301_device* cam = video_get_drvdata(video_devdata(filp));
-+ struct zc0301_frame_t* f;
-+ unsigned long lock_flags;
-+ unsigned int mask = 0;
-+
-+ if (mutex_lock_interruptible(&cam->fileop_mutex))
-+ return POLLERR;
-+
-+ if (cam->state & DEV_DISCONNECTED) {
-+ DBG(1, "Device not present");
-+ goto error;
-+ }
-+
-+ if (cam->state & DEV_MISCONFIGURED) {
-+ DBG(1, "The camera is misconfigured. Close and open it "
-+ "again.");
-+ goto error;
-+ }
-+
-+ if (cam->io == IO_NONE) {
-+ if (!zc0301_request_buffers(cam, cam->nreadbuffers, IO_READ)) {
-+ DBG(1, "poll() failed, not enough memory");
-+ goto error;
-+ }
-+ cam->io = IO_READ;
-+ cam->stream = STREAM_ON;
-+ }
-+
-+ if (cam->io == IO_READ) {
-+ spin_lock_irqsave(&cam->queue_lock, lock_flags);
-+ list_for_each_entry(f, &cam->outqueue, frame)
-+ f->state = F_UNUSED;
-+ INIT_LIST_HEAD(&cam->outqueue);
-+ spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
-+ zc0301_queue_unusedframes(cam);
-+ }
-+
-+ poll_wait(filp, &cam->wait_frame, wait);
-+
-+ if (!list_empty(&cam->outqueue))
-+ mask |= POLLIN | POLLRDNORM;
-+
-+ mutex_unlock(&cam->fileop_mutex);
-+
-+ return mask;
-+
-+error:
-+ mutex_unlock(&cam->fileop_mutex);
-+ return POLLERR;
-+}
-+
-+
-+static void zc0301_vm_open(struct vm_area_struct* vma)
-+{
-+ struct zc0301_frame_t* f = vma->vm_private_data;
-+ f->vma_use_count++;
-+}
-+
-+
-+static void zc0301_vm_close(struct vm_area_struct* vma)
-+{
-+ /* NOTE: buffers are not freed here */
-+ struct zc0301_frame_t* f = vma->vm_private_data;
-+ f->vma_use_count--;
-+}
-+
-+
-+static struct vm_operations_struct zc0301_vm_ops = {
-+ .open = zc0301_vm_open,
-+ .close = zc0301_vm_close,
-+};
-+
-+
-+static int zc0301_mmap(struct file* filp, struct vm_area_struct *vma)
-+{
-+ struct zc0301_device* cam = video_get_drvdata(video_devdata(filp));
-+ unsigned long size = vma->vm_end - vma->vm_start,
-+ start = vma->vm_start;
-+ void *pos;
-+ u32 i;
-+
-+ if (mutex_lock_interruptible(&cam->fileop_mutex))
-+ return -ERESTARTSYS;
-+
-+ if (cam->state & DEV_DISCONNECTED) {
-+ DBG(1, "Device not present");
-+ mutex_unlock(&cam->fileop_mutex);
-+ return -ENODEV;
-+ }
-+
-+ if (cam->state & DEV_MISCONFIGURED) {
-+ DBG(1, "The camera is misconfigured. Close and open it "
-+ "again.");
-+ 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)) {
-+ mutex_unlock(&cam->fileop_mutex);
-+ return -EINVAL;
-+ }
-+
-+ for (i = 0; i < cam->nbuffers; i++) {
-+ if ((cam->frame[i].buf.m.offset>>PAGE_SHIFT) == vma->vm_pgoff)
-+ break;
-+ }
-+ if (i == cam->nbuffers) {
-+ mutex_unlock(&cam->fileop_mutex);
-+ return -EINVAL;
-+ }
-+
-+ vma->vm_flags |= VM_IO;
-+ vma->vm_flags |= VM_RESERVED;
-+
-+ pos = cam->frame[i].bufmem;
-+ while (size > 0) { /* size is page-aligned */
-+ if (vm_insert_page(vma, start, vmalloc_to_page(pos))) {
-+ mutex_unlock(&cam->fileop_mutex);
-+ return -EAGAIN;
-+ }
-+ start += PAGE_SIZE;
-+ pos += PAGE_SIZE;
-+ size -= PAGE_SIZE;
-+ }
-+
-+ vma->vm_ops = &zc0301_vm_ops;
-+ vma->vm_private_data = &cam->frame[i];
-+
-+ zc0301_vm_open(vma);
-+
-+ mutex_unlock(&cam->fileop_mutex);
-+
-+ return 0;
-+}
-+
-+/*****************************************************************************/
-+
-+static int
-+zc0301_vidioc_querycap(struct zc0301_device* cam, void __user * arg)
-+{
-+ struct v4l2_capability cap = {
-+ .driver = "zc0301",
-+ .version = ZC0301_MODULE_VERSION_CODE,
-+ .capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE |
-+ V4L2_CAP_STREAMING,
-+ };
-+
-+ strlcpy(cap.card, cam->v4ldev->name, sizeof(cap.card));
-+ if (usb_make_path(cam->usbdev, cap.bus_info, sizeof(cap.bus_info)) < 0)
-+ strlcpy(cap.bus_info, cam->usbdev->dev.bus_id,
-+ sizeof(cap.bus_info));
-+
-+ if (copy_to_user(arg, &cap, sizeof(cap)))
-+ return -EFAULT;
-+
-+ return 0;
-+}
-+
-+
-+static int
-+zc0301_vidioc_enuminput(struct zc0301_device* cam, void __user * arg)
-+{
-+ struct v4l2_input i;
-+
-+ if (copy_from_user(&i, arg, sizeof(i)))
-+ return -EFAULT;
-+
-+ if (i.index)
-+ return -EINVAL;
-+
-+ memset(&i, 0, sizeof(i));
-+ strcpy(i.name, "Camera");
-+
-+ if (copy_to_user(arg, &i, sizeof(i)))
-+ return -EFAULT;
-+
-+ return 0;
-+}
-+
-+
-+static int
-+zc0301_vidioc_gs_input(struct zc0301_device* cam, void __user * arg)
-+{
-+ int index;
-+
-+ if (copy_from_user(&index, arg, sizeof(index)))
-+ return -EFAULT;
-+
-+ if (index != 0)
-+ return -EINVAL;
-+
-+ return 0;
-+}
-+
-+
-+static int
-+zc0301_vidioc_query_ctrl(struct zc0301_device* cam, void __user * arg)
-+{
-+ struct zc0301_sensor* s = cam->sensor;
-+ struct v4l2_queryctrl qc;
-+ u8 i;
-+
-+ if (copy_from_user(&qc, arg, sizeof(qc)))
-+ return -EFAULT;
-+
-+ for (i = 0; i < ARRAY_SIZE(s->qctrl); i++)
-+ if (qc.id && qc.id == s->qctrl[i].id) {
-+ memcpy(&qc, &(s->qctrl[i]), sizeof(qc));
-+ if (copy_to_user(arg, &qc, sizeof(qc)))
-+ return -EFAULT;
-+ return 0;
-+ }
-+
-+ return -EINVAL;
-+}
-+
-+
-+static int
-+zc0301_vidioc_g_ctrl(struct zc0301_device* cam, void __user * arg)
-+{
-+ struct zc0301_sensor* s = cam->sensor;
-+ struct v4l2_control ctrl;
-+ int err = 0;
-+ u8 i;
-+
-+ if (!s->get_ctrl && !s->set_ctrl)
-+ return -EINVAL;
-+
-+ if (copy_from_user(&ctrl, arg, sizeof(ctrl)))
-+ return -EFAULT;
-+
-+ if (!s->get_ctrl) {
-+ for (i = 0; i < ARRAY_SIZE(s->qctrl); i++)
-+ if (ctrl.id == s->qctrl[i].id) {
-+ ctrl.value = s->_qctrl[i].default_value;
-+ goto exit;
-+ }
-+ return -EINVAL;
-+ } else
-+ err = s->get_ctrl(cam, &ctrl);
-+
-+exit:
-+ if (copy_to_user(arg, &ctrl, sizeof(ctrl)))
-+ return -EFAULT;
-+
-+ return err;
-+}
-+
-+
-+static int
-+zc0301_vidioc_s_ctrl(struct zc0301_device* cam, void __user * arg)
-+{
-+ struct zc0301_sensor* s = cam->sensor;
-+ struct v4l2_control ctrl;
-+ u8 i;
-+ int err = 0;
-+
-+ if (!s->set_ctrl)
-+ return -EINVAL;
-+
-+ if (copy_from_user(&ctrl, arg, sizeof(ctrl)))
-+ return -EFAULT;
-+
-+ for (i = 0; i < ARRAY_SIZE(s->qctrl); i++)
-+ if (ctrl.id == s->qctrl[i].id) {
-+ if (ctrl.value < s->qctrl[i].minimum ||
-+ ctrl.value > s->qctrl[i].maximum)
-+ return -ERANGE;
-+ ctrl.value -= ctrl.value % s->qctrl[i].step;
-+ break;
-+ }
-+
-+ if ((err = s->set_ctrl(cam, &ctrl)))
-+ return err;
-+
-+ s->_qctrl[i].default_value = ctrl.value;
-+
-+ return 0;
-+}
-+
-+
-+static int
-+zc0301_vidioc_cropcap(struct zc0301_device* cam, void __user * arg)
-+{
-+ struct v4l2_cropcap* cc = &(cam->sensor->cropcap);
-+
-+ cc->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-+ cc->pixelaspect.numerator = 1;
-+ cc->pixelaspect.denominator = 1;
-+
-+ if (copy_to_user(arg, cc, sizeof(*cc)))
-+ return -EFAULT;
-+
-+ return 0;
-+}
-+
-+
-+static int
-+zc0301_vidioc_g_crop(struct zc0301_device* cam, void __user * arg)
-+{
-+ struct zc0301_sensor* s = cam->sensor;
-+ struct v4l2_crop crop = {
-+ .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
-+ };
-+
-+ memcpy(&(crop.c), &(s->_rect), sizeof(struct v4l2_rect));
-+
-+ if (copy_to_user(arg, &crop, sizeof(crop)))
-+ return -EFAULT;
-+
-+ return 0;
-+}
-+
-+
-+static int
-+zc0301_vidioc_s_crop(struct zc0301_device* cam, void __user * arg)
-+{
-+ struct zc0301_sensor* s = cam->sensor;
-+ struct v4l2_crop crop;
-+ struct v4l2_rect* rect;
-+ struct v4l2_rect* bounds = &(s->cropcap.bounds);
-+ const enum zc0301_stream_state stream = cam->stream;
-+ const u32 nbuffers = cam->nbuffers;
-+ u32 i;
-+ int err = 0;
-+
-+ if (copy_from_user(&crop, arg, sizeof(crop)))
-+ return -EFAULT;
-+
-+ rect = &(crop.c);
-+
-+ if (crop.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
-+ return -EINVAL;
-+
-+ if (cam->module_param.force_munmap)
-+ for (i = 0; i < cam->nbuffers; i++)
-+ if (cam->frame[i].vma_use_count) {
-+ DBG(3, "VIDIOC_S_CROP failed. "
-+ "Unmap the buffers first.");
-+ return -EINVAL;
-+ }
-+
-+ if (!s->set_crop) {
-+ memcpy(rect, &(s->_rect), sizeof(*rect));
-+ if (copy_to_user(arg, &crop, sizeof(crop)))
-+ return -EFAULT;
-+ return 0;
-+ }
-+
-+ rect->left &= ~7L;
-+ rect->top &= ~7L;
-+ if (rect->width < 8)
-+ rect->width = 8;
-+ if (rect->height < 8)
-+ rect->height = 8;
-+ if (rect->width > bounds->width)
-+ rect->width = bounds->width;
-+ if (rect->height > bounds->height)
-+ rect->height = bounds->height;
-+ if (rect->left < bounds->left)
-+ rect->left = bounds->left;
-+ if (rect->top < bounds->top)
-+ rect->top = bounds->top;
-+ if (rect->left + rect->width > bounds->left + bounds->width)
-+ rect->left = bounds->left+bounds->width - rect->width;
-+ if (rect->top + rect->height > bounds->top + bounds->height)
-+ rect->top = bounds->top+bounds->height - rect->height;
-+ rect->width &= ~7L;
-+ rect->height &= ~7L;
-+
-+ if (cam->stream == STREAM_ON)
-+ if ((err = zc0301_stream_interrupt(cam)))
-+ return err;
-+
-+ if (copy_to_user(arg, &crop, sizeof(crop))) {
-+ cam->stream = stream;
-+ return -EFAULT;
-+ }
-+
-+ if (cam->module_param.force_munmap || cam->io == IO_READ)
-+ zc0301_release_buffers(cam);
-+
-+ if (s->set_crop)
-+ err += s->set_crop(cam, rect);
-+
-+ if (err) { /* atomic, no rollback in ioctl() */
-+ cam->state |= DEV_MISCONFIGURED;
-+ DBG(1, "VIDIOC_S_CROP failed because of hardware problems. To "
-+ "use the camera, close and open /dev/video%d again.",
-+ cam->v4ldev->minor);
-+ return -EIO;
-+ }
-+
-+ s->pix_format.width = rect->width;
-+ s->pix_format.height = rect->height;
-+ memcpy(&(s->_rect), rect, sizeof(*rect));
-+
-+ if ((cam->module_param.force_munmap || cam->io == IO_READ) &&
-+ nbuffers != zc0301_request_buffers(cam, nbuffers, cam->io)) {
-+ cam->state |= DEV_MISCONFIGURED;
-+ DBG(1, "VIDIOC_S_CROP failed because of not enough memory. To "
-+ "use the camera, close and open /dev/video%d again.",
-+ cam->v4ldev->minor);
-+ return -ENOMEM;
-+ }
-+
-+ if (cam->io == IO_READ)
-+ zc0301_empty_framequeues(cam);
-+ else if (cam->module_param.force_munmap)
-+ zc0301_requeue_outqueue(cam);
-+
-+ cam->stream = stream;
-+
-+ return 0;
-+}
-+
-+
-+static int
-+zc0301_vidioc_enum_fmt(struct zc0301_device* cam, void __user * arg)
-+{
-+ struct v4l2_fmtdesc fmtd;
-+
-+ if (copy_from_user(&fmtd, arg, sizeof(fmtd)))
-+ return -EFAULT;
-+
-+ if (fmtd.index == 0) {
-+ strcpy(fmtd.description, "JPEG");
-+ fmtd.pixelformat = V4L2_PIX_FMT_JPEG;
-+ fmtd.flags = V4L2_FMT_FLAG_COMPRESSED;
-+ } else
-+ return -EINVAL;
-+
-+ fmtd.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-+ memset(&fmtd.reserved, 0, sizeof(fmtd.reserved));
-+
-+ if (copy_to_user(arg, &fmtd, sizeof(fmtd)))
-+ return -EFAULT;
-+
-+ return 0;
-+}
-+
-+
-+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);
-+
-+ if (copy_from_user(&format, arg, sizeof(format)))
-+ return -EFAULT;
-+
-+ if (format.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
-+ return -EINVAL;
-+
-+ pfmt->bytesperline = 0;
-+ pfmt->sizeimage = pfmt->height * ((pfmt->width*pfmt->priv)/8);
-+ pfmt->field = V4L2_FIELD_NONE;
-+ memcpy(&(format.fmt.pix), pfmt, sizeof(*pfmt));
-+
-+ if (copy_to_user(arg, &format, sizeof(format)))
-+ return -EFAULT;
-+
-+ return 0;
-+}
-+
-+
-+static int
-+zc0301_vidioc_try_s_fmt(struct zc0301_device* cam, unsigned int cmd,
-+ void __user * arg)
-+{
-+ struct zc0301_sensor* s = cam->sensor;
-+ struct v4l2_format format;
-+ struct v4l2_pix_format* pix;
-+ struct v4l2_pix_format* pfmt = &(s->pix_format);
-+ struct v4l2_rect* bounds = &(s->cropcap.bounds);
-+ struct v4l2_rect rect;
-+ const enum zc0301_stream_state stream = cam->stream;
-+ const u32 nbuffers = cam->nbuffers;
-+ u32 i;
-+ int err = 0;
-+
-+ if (copy_from_user(&format, arg, sizeof(format)))
-+ return -EFAULT;
-+
-+ pix = &(format.fmt.pix);
-+
-+ if (format.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
-+ return -EINVAL;
-+
-+ memcpy(&rect, &(s->_rect), sizeof(rect));
-+
-+ if (!s->set_crop) {
-+ pix->width = rect.width;
-+ pix->height = rect.height;
-+ } else {
-+ rect.width = pix->width;
-+ rect.height = pix->height;
-+ }
-+
-+ if (rect.width < 8)
-+ rect.width = 8;
-+ if (rect.height < 8)
-+ rect.height = 8;
-+ if (rect.width > bounds->left + bounds->width - rect.left)
-+ rect.width = bounds->left + bounds->width - rect.left;
-+ if (rect.height > bounds->top + bounds->height - rect.top)
-+ rect.height = bounds->top + bounds->height - rect.top;
-+ rect.width &= ~7L;
-+ rect.height &= ~7L;
-+
-+ pix->width = rect.width;
-+ pix->height = rect.height;
-+ pix->pixelformat = pfmt->pixelformat;
-+ pix->priv = pfmt->priv;
-+ pix->colorspace = pfmt->colorspace;
-+ pix->bytesperline = 0;
-+ pix->sizeimage = pix->height * ((pix->width * pix->priv) / 8);
-+ pix->field = V4L2_FIELD_NONE;
-+
-+ if (cmd == VIDIOC_TRY_FMT) {
-+ if (copy_to_user(arg, &format, sizeof(format)))
-+ return -EFAULT;
-+ return 0;
-+ }
-+
-+ if (cam->module_param.force_munmap)
-+ for (i = 0; i < cam->nbuffers; i++)
-+ if (cam->frame[i].vma_use_count) {
-+ DBG(3, "VIDIOC_S_FMT failed. "
-+ "Unmap the buffers first.");
-+ return -EINVAL;
-+ }
-+
-+ if (cam->stream == STREAM_ON)
-+ if ((err = zc0301_stream_interrupt(cam)))
-+ return err;
-+
-+ if (copy_to_user(arg, &format, sizeof(format))) {
-+ cam->stream = stream;
-+ return -EFAULT;
-+ }
-+
-+ if (cam->module_param.force_munmap || cam->io == IO_READ)
-+ zc0301_release_buffers(cam);
-+
-+ if (s->set_crop)
-+ err += s->set_crop(cam, &rect);
-+
-+ if (err) { /* atomic, no rollback in ioctl() */
-+ cam->state |= DEV_MISCONFIGURED;
-+ DBG(1, "VIDIOC_S_FMT failed because of hardware problems. To "
-+ "use the camera, close and open /dev/video%d again.",
-+ cam->v4ldev->minor);
-+ return -EIO;
-+ }
-+
-+ memcpy(pfmt, pix, sizeof(*pix));
-+ memcpy(&(s->_rect), &rect, sizeof(rect));
-+
-+ if ((cam->module_param.force_munmap || cam->io == IO_READ) &&
-+ nbuffers != zc0301_request_buffers(cam, nbuffers, cam->io)) {
-+ cam->state |= DEV_MISCONFIGURED;
-+ DBG(1, "VIDIOC_S_FMT failed because of not enough memory. To "
-+ "use the camera, close and open /dev/video%d again.",
-+ cam->v4ldev->minor);
-+ return -ENOMEM;
-+ }
-+
-+ if (cam->io == IO_READ)
-+ zc0301_empty_framequeues(cam);
-+ else if (cam->module_param.force_munmap)
-+ zc0301_requeue_outqueue(cam);
-+
-+ cam->stream = stream;
-+
-+ return 0;
-+}
-+
-+
-+static int
-+zc0301_vidioc_g_jpegcomp(struct zc0301_device* cam, void __user * arg)
-+{
-+ if (copy_to_user(arg, &cam->compression, sizeof(cam->compression)))
-+ return -EFAULT;
-+
-+ return 0;
-+}
-+
-+
-+static int
-+zc0301_vidioc_s_jpegcomp(struct zc0301_device* cam, void __user * arg)
-+{
-+ struct v4l2_jpegcompression jc;
-+ const enum zc0301_stream_state stream = cam->stream;
-+ int err = 0;
-+
-+ if (copy_from_user(&jc, arg, sizeof(jc)))
-+ return -EFAULT;
-+
-+ if (jc.quality < 0 || jc.quality > 3)
-+ return -EINVAL;
-+
-+ if (cam->stream == STREAM_ON)
-+ if ((err = zc0301_stream_interrupt(cam)))
-+ return err;
-+
-+ err += zc0301_set_compression(cam, &jc);
-+ if (err) { /* atomic, no rollback in ioctl() */
-+ cam->state |= DEV_MISCONFIGURED;
-+ DBG(1, "VIDIOC_S_JPEGCOMP failed because of hardware "
-+ "problems. To use the camera, close and open "
-+ "/dev/video%d again.", cam->v4ldev->minor);
-+ return -EIO;
-+ }
-+
-+ cam->compression.quality = jc.quality;
-+
-+ cam->stream = stream;
-+
-+ return 0;
-+}
-+
-+
-+static int
-+zc0301_vidioc_reqbufs(struct zc0301_device* cam, void __user * arg)
-+{
-+ struct v4l2_requestbuffers rb;
-+ u32 i;
-+ int err;
-+
-+ if (copy_from_user(&rb, arg, sizeof(rb)))
-+ return -EFAULT;
-+
-+ if (rb.type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
-+ rb.memory != V4L2_MEMORY_MMAP)
-+ return -EINVAL;
-+
-+ if (cam->io == IO_READ) {
-+ DBG(3, "Close and open the device again to choose the mmap "
-+ "I/O method");
-+ return -EINVAL;
-+ }
-+
-+ for (i = 0; i < cam->nbuffers; i++)
-+ if (cam->frame[i].vma_use_count) {
-+ DBG(3, "VIDIOC_REQBUFS failed. "
-+ "Previous buffers are still mapped.");
-+ return -EINVAL;
-+ }
-+
-+ if (cam->stream == STREAM_ON)
-+ if ((err = zc0301_stream_interrupt(cam)))
-+ return err;
-+
-+ zc0301_empty_framequeues(cam);
-+
-+ zc0301_release_buffers(cam);
-+ if (rb.count)
-+ rb.count = zc0301_request_buffers(cam, rb.count, IO_MMAP);
-+
-+ if (copy_to_user(arg, &rb, sizeof(rb))) {
-+ zc0301_release_buffers(cam);
-+ cam->io = IO_NONE;
-+ return -EFAULT;
-+ }
-+
-+ cam->io = rb.count ? IO_MMAP : IO_NONE;
-+
-+ return 0;
-+}
-+
-+
-+static int
-+zc0301_vidioc_querybuf(struct zc0301_device* cam, void __user * arg)
-+{
-+ struct v4l2_buffer b;
-+
-+ if (copy_from_user(&b, arg, sizeof(b)))
-+ return -EFAULT;
-+
-+ if (b.type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
-+ b.index >= cam->nbuffers || cam->io != IO_MMAP)
-+ return -EINVAL;
-+
-+ memcpy(&b, &cam->frame[b.index].buf, sizeof(b));
-+
-+ if (cam->frame[b.index].vma_use_count)
-+ b.flags |= V4L2_BUF_FLAG_MAPPED;
-+
-+ if (cam->frame[b.index].state == F_DONE)
-+ b.flags |= V4L2_BUF_FLAG_DONE;
-+ else if (cam->frame[b.index].state != F_UNUSED)
-+ b.flags |= V4L2_BUF_FLAG_QUEUED;
-+
-+ if (copy_to_user(arg, &b, sizeof(b)))
-+ return -EFAULT;
-+
-+ return 0;
-+}
-+
-+
-+static int
-+zc0301_vidioc_qbuf(struct zc0301_device* cam, void __user * arg)
-+{
-+ struct v4l2_buffer b;
-+ unsigned long lock_flags;
-+
-+ if (copy_from_user(&b, arg, sizeof(b)))
-+ return -EFAULT;
-+
-+ if (b.type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
-+ b.index >= cam->nbuffers || cam->io != IO_MMAP)
-+ return -EINVAL;
-+
-+ if (cam->frame[b.index].state != F_UNUSED)
-+ return -EINVAL;
-+
-+ cam->frame[b.index].state = F_QUEUED;
-+
-+ spin_lock_irqsave(&cam->queue_lock, lock_flags);
-+ list_add_tail(&cam->frame[b.index].frame, &cam->inqueue);
-+ spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
-+
-+ PDBGG("Frame #%lu queued", (unsigned long)b.index);
-+
-+ return 0;
-+}
-+
-+
-+static int
-+zc0301_vidioc_dqbuf(struct zc0301_device* cam, struct file* filp,
-+ void __user * arg)
-+{
-+ struct v4l2_buffer b;
-+ struct zc0301_frame_t *f;
-+ unsigned long lock_flags;
-+ long timeout;
-+
-+ if (copy_from_user(&b, arg, sizeof(b)))
-+ return -EFAULT;
-+
-+ if (b.type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io!= IO_MMAP)
-+ return -EINVAL;
-+
-+ if (list_empty(&cam->outqueue)) {
-+ if (cam->stream == STREAM_OFF)
-+ return -EINVAL;
-+ if (filp->f_flags & O_NONBLOCK)
-+ return -EAGAIN;
-+ timeout = wait_event_interruptible_timeout
-+ ( cam->wait_frame,
-+ (!list_empty(&cam->outqueue)) ||
-+ (cam->state & DEV_DISCONNECTED) ||
-+ (cam->state & DEV_MISCONFIGURED),
-+ ZC0301_FRAME_TIMEOUT );
-+ if (timeout < 0)
-+ return timeout;
-+ if (cam->state & DEV_DISCONNECTED)
-+ return -ENODEV;
-+ if (!timeout || (cam->state & DEV_MISCONFIGURED))
-+ return -EIO;
-+ }
-+
-+ spin_lock_irqsave(&cam->queue_lock, lock_flags);
-+ f = list_entry(cam->outqueue.next, struct zc0301_frame_t, frame);
-+ list_del(cam->outqueue.next);
-+ spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
-+
-+ f->state = F_UNUSED;
-+
-+ memcpy(&b, &f->buf, sizeof(b));
-+ if (f->vma_use_count)
-+ b.flags |= V4L2_BUF_FLAG_MAPPED;
-+
-+ if (copy_to_user(arg, &b, sizeof(b)))
-+ return -EFAULT;
-+
-+ PDBGG("Frame #%lu dequeued", (unsigned long)f->buf.index);
-+
-+ return 0;
-+}
-+
-+
-+static int
-+zc0301_vidioc_streamon(struct zc0301_device* cam, void __user * arg)
-+{
-+ int type;
-+
-+ if (copy_from_user(&type, arg, sizeof(type)))
-+ return -EFAULT;
-+
-+ if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io != IO_MMAP)
-+ return -EINVAL;
-+
-+ if (list_empty(&cam->inqueue))
-+ return -EINVAL;
-+
-+ cam->stream = STREAM_ON;
-+
-+ DBG(3, "Stream on");
-+
-+ return 0;
-+}
-+
-+
-+static int
-+zc0301_vidioc_streamoff(struct zc0301_device* cam, void __user * arg)
-+{
-+ int type, err;
-+
-+ if (copy_from_user(&type, arg, sizeof(type)))
-+ return -EFAULT;
-+
-+ if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io != IO_MMAP)
-+ return -EINVAL;
-+
-+ if (cam->stream == STREAM_ON)
-+ if ((err = zc0301_stream_interrupt(cam)))
-+ return err;
-+
-+ zc0301_empty_framequeues(cam);
-+
-+ DBG(3, "Stream off");
-+
-+ return 0;
-+}
-+
-+
-+static int
-+zc0301_vidioc_g_parm(struct zc0301_device* cam, void __user * arg)
-+{
-+ struct v4l2_streamparm sp;
-+
-+ if (copy_from_user(&sp, arg, sizeof(sp)))
-+ return -EFAULT;
-+
-+ if (sp.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
-+ return -EINVAL;
-+
-+ sp.parm.capture.extendedmode = 0;
-+ sp.parm.capture.readbuffers = cam->nreadbuffers;
-+
-+ if (copy_to_user(arg, &sp, sizeof(sp)))
-+ return -EFAULT;
-+
-+ return 0;
-+}
-+
-+
-+static int
-+zc0301_vidioc_s_parm(struct zc0301_device* cam, void __user * arg)
-+{
-+ struct v4l2_streamparm sp;
-+
-+ if (copy_from_user(&sp, arg, sizeof(sp)))
-+ return -EFAULT;
-+
-+ if (sp.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
-+ return -EINVAL;
-+
-+ sp.parm.capture.extendedmode = 0;
-+
-+ if (sp.parm.capture.readbuffers == 0)
-+ sp.parm.capture.readbuffers = cam->nreadbuffers;
-+
-+ if (sp.parm.capture.readbuffers > ZC0301_MAX_FRAMES)
-+ sp.parm.capture.readbuffers = ZC0301_MAX_FRAMES;
-+
-+ if (copy_to_user(arg, &sp, sizeof(sp)))
-+ return -EFAULT;
-+
-+ cam->nreadbuffers = sp.parm.capture.readbuffers;
-+
-+ return 0;
-+}
-+
-+
-+static int zc0301_ioctl_v4l2(struct inode* inode, struct file* filp,
-+ unsigned int cmd, void __user * arg)
-+{
-+ struct zc0301_device* cam = video_get_drvdata(video_devdata(filp));
-+
-+ switch (cmd) {
-+
-+ case VIDIOC_QUERYCAP:
-+ return zc0301_vidioc_querycap(cam, arg);
-+
-+ case VIDIOC_ENUMINPUT:
-+ return zc0301_vidioc_enuminput(cam, arg);
-+
-+ case VIDIOC_G_INPUT:
-+ case VIDIOC_S_INPUT:
-+ return zc0301_vidioc_gs_input(cam, arg);
-+
-+ case VIDIOC_QUERYCTRL:
-+ return zc0301_vidioc_query_ctrl(cam, arg);
-+
-+ case VIDIOC_G_CTRL:
-+ return zc0301_vidioc_g_ctrl(cam, arg);
-+
-+ case VIDIOC_S_CTRL_OLD:
-+ case VIDIOC_S_CTRL:
-+ return zc0301_vidioc_s_ctrl(cam, arg);
-+
-+ case VIDIOC_CROPCAP_OLD:
-+ case VIDIOC_CROPCAP:
-+ return zc0301_vidioc_cropcap(cam, arg);
-+
-+ case VIDIOC_G_CROP:
-+ return zc0301_vidioc_g_crop(cam, arg);
-+
-+ case VIDIOC_S_CROP:
-+ return zc0301_vidioc_s_crop(cam, arg);
-+
-+ case VIDIOC_ENUM_FMT:
-+ return zc0301_vidioc_enum_fmt(cam, arg);
-+
-+ case VIDIOC_G_FMT:
-+ return zc0301_vidioc_g_fmt(cam, arg);
-+
-+ case VIDIOC_TRY_FMT:
-+ case VIDIOC_S_FMT:
-+ return zc0301_vidioc_try_s_fmt(cam, cmd, arg);
-+
-+ case VIDIOC_G_JPEGCOMP:
-+ return zc0301_vidioc_g_jpegcomp(cam, arg);
-+
-+ case VIDIOC_S_JPEGCOMP:
-+ return zc0301_vidioc_s_jpegcomp(cam, arg);
-+
-+ case VIDIOC_REQBUFS:
-+ return zc0301_vidioc_reqbufs(cam, arg);
-+
-+ case VIDIOC_QUERYBUF:
-+ return zc0301_vidioc_querybuf(cam, arg);
-+
-+ case VIDIOC_QBUF:
-+ return zc0301_vidioc_qbuf(cam, arg);
-+
-+ case VIDIOC_DQBUF:
-+ return zc0301_vidioc_dqbuf(cam, filp, arg);
-+
-+ case VIDIOC_STREAMON:
-+ return zc0301_vidioc_streamon(cam, arg);
-+
-+ case VIDIOC_STREAMOFF:
-+ return zc0301_vidioc_streamoff(cam, arg);
-+
-+ case VIDIOC_G_PARM:
-+ return zc0301_vidioc_g_parm(cam, arg);
-+
-+ case VIDIOC_S_PARM_OLD:
-+ case VIDIOC_S_PARM:
-+ return zc0301_vidioc_s_parm(cam, arg);
-+
-+ case VIDIOC_G_STD:
-+ case VIDIOC_S_STD:
-+ case VIDIOC_QUERYSTD:
-+ case VIDIOC_ENUMSTD:
-+ case VIDIOC_QUERYMENU:
-+ return -EINVAL;
-+
-+ default:
-+ return -EINVAL;
-+
-+ }
-+}
-+
-+
-+static int zc0301_ioctl(struct inode* inode, struct file* filp,
-+ unsigned int cmd, unsigned long arg)
-+{
-+ struct zc0301_device* cam = video_get_drvdata(video_devdata(filp));
-+ int err = 0;
-+
-+ if (mutex_lock_interruptible(&cam->fileop_mutex))
-+ return -ERESTARTSYS;
-+
-+ if (cam->state & DEV_DISCONNECTED) {
-+ DBG(1, "Device not present");
-+ mutex_unlock(&cam->fileop_mutex);
-+ return -ENODEV;
-+ }
-+
-+ if (cam->state & DEV_MISCONFIGURED) {
-+ DBG(1, "The camera is misconfigured. Close and open it "
-+ "again.");
-+ mutex_unlock(&cam->fileop_mutex);
-+ return -EIO;
-+ }
-+
-+ V4LDBG(3, "zc0301", cmd);
-+
-+ err = zc0301_ioctl_v4l2(inode, filp, cmd, (void __user *)arg);
-+
-+ mutex_unlock(&cam->fileop_mutex);
-+
-+ return err;
-+}
-+
-+
-+static struct file_operations zc0301_fops = {
-+ .owner = THIS_MODULE,
-+ .open = zc0301_open,
-+ .release = zc0301_release,
-+ .ioctl = zc0301_ioctl,
-+ .read = zc0301_read,
-+ .poll = zc0301_poll,
-+ .mmap = zc0301_mmap,
-+ .llseek = no_llseek,
-+};
-+
-+/*****************************************************************************/
-+
-+static int
-+zc0301_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
-+{
-+ struct usb_device *udev = interface_to_usbdev(intf);
-+ struct zc0301_device* cam;
-+ static unsigned int dev_nr = 0;
-+ unsigned int i;
-+ int err = 0;
-+
-+ if (!(cam = kzalloc(sizeof(struct zc0301_device), GFP_KERNEL)))
-+ return -ENOMEM;
-+
-+ cam->usbdev = udev;
-+
-+ if (!(cam->control_buffer = kzalloc(4, GFP_KERNEL))) {
-+ DBG(1, "kmalloc() failed");
-+ err = -ENOMEM;
-+ goto fail;
-+ }
-+
-+ if (!(cam->v4ldev = video_device_alloc())) {
-+ DBG(1, "video_device_alloc() failed");
-+ err = -ENOMEM;
-+ goto fail;
-+ }
-+
-+ mutex_init(&cam->dev_mutex);
-+
-+ DBG(2, "ZC0301 Image Processor and Control Chip detected "
-+ "(vid/pid 0x%04X/0x%04X)",id->idVendor, id->idProduct);
-+
-+ for (i = 0; zc0301_sensor_table[i]; i++) {
-+ err = zc0301_sensor_table[i](cam);
-+ if (!err)
-+ break;
-+ }
-+
-+ if (!err && cam->sensor)
-+ DBG(2, "%s image sensor detected", cam->sensor->name);
-+ else {
-+ DBG(1, "No supported image sensor detected");
-+ err = -ENODEV;
-+ goto fail;
-+ }
-+
-+ if (zc0301_init(cam)) {
-+ DBG(1, "Initialization failed. I will retry on open().");
-+ cam->state |= DEV_MISCONFIGURED;
-+ }
-+
-+ strcpy(cam->v4ldev->name, "ZC0301 PC Camera");
-+ cam->v4ldev->owner = THIS_MODULE;
-+ cam->v4ldev->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES;
-+ cam->v4ldev->hardware = 0;
-+ cam->v4ldev->fops = &zc0301_fops;
-+ cam->v4ldev->minor = video_nr[dev_nr];
-+ cam->v4ldev->release = video_device_release;
-+ video_set_drvdata(cam->v4ldev, cam);
-+
-+ mutex_lock(&cam->dev_mutex);
-+
-+ err = video_register_device(cam->v4ldev, VFL_TYPE_GRABBER,
-+ video_nr[dev_nr]);
-+ if (err) {
-+ DBG(1, "V4L2 device registration failed");
-+ if (err == -ENFILE && video_nr[dev_nr] == -1)
-+ DBG(1, "Free /dev/videoX node not found");
-+ video_nr[dev_nr] = -1;
-+ dev_nr = (dev_nr < ZC0301_MAX_DEVICES-1) ? dev_nr+1 : 0;
-+ 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];
-+
-+ dev_nr = (dev_nr < ZC0301_MAX_DEVICES-1) ? dev_nr+1 : 0;
-+
-+ usb_set_intfdata(intf, cam);
-+
-+ mutex_unlock(&cam->dev_mutex);
-+
-+ return 0;
-+
-+fail:
-+ if (cam) {
-+ kfree(cam->control_buffer);
-+ if (cam->v4ldev)
-+ video_device_release(cam->v4ldev);
-+ kfree(cam);
-+ }
-+ return err;
-+}
-+
-+
-+static void zc0301_usb_disconnect(struct usb_interface* intf)
-+{
-+ struct zc0301_device* cam = usb_get_intfdata(intf);
-+
-+ if (!cam)
-+ return;
-+
-+ down_write(&zc0301_disconnect);
-+
-+ mutex_lock(&cam->dev_mutex);
-+
-+ DBG(2, "Disconnecting %s...", cam->v4ldev->name);
-+
-+ wake_up_interruptible_all(&cam->open);
-+
-+ if (cam->users) {
-+ DBG(2, "Device /dev/video%d is open! Deregistration and "
-+ "memory deallocation are deferred on close.",
-+ cam->v4ldev->minor);
-+ cam->state |= DEV_MISCONFIGURED;
-+ zc0301_stop_transfer(cam);
-+ cam->state |= DEV_DISCONNECTED;
-+ wake_up_interruptible(&cam->wait_frame);
-+ wake_up_interruptible(&cam->wait_stream);
-+ } else {
-+ cam->state |= DEV_DISCONNECTED;
-+ zc0301_release_resources(cam);
-+ }
-+
-+ mutex_unlock(&cam->dev_mutex);
-+
-+ if (!cam->users)
-+ kfree(cam);
-+
-+ up_write(&zc0301_disconnect);
-+}
-+
-+
-+static struct usb_driver zc0301_usb_driver = {
-+ .name = "zc0301",
-+ .id_table = zc0301_id_table,
-+ .probe = zc0301_usb_probe,
-+ .disconnect = zc0301_usb_disconnect,
-+};
-+
-+/*****************************************************************************/
-+
-+static int __init zc0301_module_init(void)
-+{
-+ int err = 0;
-+
-+ KDBG(2, ZC0301_MODULE_NAME " v" ZC0301_MODULE_VERSION);
-+ KDBG(3, ZC0301_MODULE_AUTHOR);
-+
-+ if ((err = usb_register(&zc0301_usb_driver)))
-+ KDBG(1, "usb_register() failed");
-+
-+ return err;
-+}
-+
-+
-+static void __exit zc0301_module_exit(void)
-+{
-+ usb_deregister(&zc0301_usb_driver);
-+}
-+
-+
-+module_init(zc0301_module_init);
-+module_exit(zc0301_module_exit);
---- /dev/null
-+++ gregkh-2.6/drivers/usb/media/zc0301_pas202bcb.c
-@@ -0,0 +1,353 @@
-+/***************************************************************************
-+ * Plug-in for PAS202BCB image sensor connected to the ZC030! Image *
-+ * Processor and Control Chip *
-+ * *
-+ * Copyright (C) 2006 by Luca Risolia <luca.risolia@studio.unibo.it> *
-+ * *
-+ * Initialization values of the ZC0301 have been taken from the SPCA5XX *
-+ * driver maintained by Michel Xhaard <mxhaard@magic.fr> *
-+ * *
-+ * 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 "zc0301_sensor.h"
-+
-+
-+static struct zc0301_sensor pas202bcb;
-+
-+
-+static int pas202bcb_init(struct zc0301_device* cam)
-+{
-+ int err = 0;
-+
-+ err += zc0301_write_reg(cam, 0x0002, 0x00);
-+ err += zc0301_write_reg(cam, 0x0003, 0x02);
-+ err += zc0301_write_reg(cam, 0x0004, 0x80);
-+ err += zc0301_write_reg(cam, 0x0005, 0x01);
-+ err += zc0301_write_reg(cam, 0x0006, 0xE0);
-+ err += zc0301_write_reg(cam, 0x0098, 0x00);
-+ err += zc0301_write_reg(cam, 0x009A, 0x03);
-+ err += zc0301_write_reg(cam, 0x011A, 0x00);
-+ err += zc0301_write_reg(cam, 0x011C, 0x03);
-+ err += zc0301_write_reg(cam, 0x009B, 0x01);
-+ err += zc0301_write_reg(cam, 0x009C, 0xE6);
-+ err += zc0301_write_reg(cam, 0x009D, 0x02);
-+ err += zc0301_write_reg(cam, 0x009E, 0x86);
-+
-+ err += zc0301_i2c_write(cam, 0x02, 0x02);
-+ err += zc0301_i2c_write(cam, 0x0A, 0x01);
-+ err += zc0301_i2c_write(cam, 0x0B, 0x01);
-+ err += zc0301_i2c_write(cam, 0x0D, 0x00);
-+ err += zc0301_i2c_write(cam, 0x12, 0x05);
-+ err += zc0301_i2c_write(cam, 0x13, 0x63);
-+ err += zc0301_i2c_write(cam, 0x15, 0x70);
-+
-+ err += zc0301_write_reg(cam, 0x0101, 0xB7);
-+ err += zc0301_write_reg(cam, 0x0100, 0x0D);
-+ err += zc0301_write_reg(cam, 0x0189, 0x06);
-+ err += zc0301_write_reg(cam, 0x01AD, 0x00);
-+ err += zc0301_write_reg(cam, 0x01C5, 0x03);
-+ err += zc0301_write_reg(cam, 0x01CB, 0x13);
-+ err += zc0301_write_reg(cam, 0x0250, 0x08);
-+ err += zc0301_write_reg(cam, 0x0301, 0x08);
-+ err += zc0301_write_reg(cam, 0x018D, 0x70);
-+ err += zc0301_write_reg(cam, 0x0008, 0x03);
-+ err += zc0301_write_reg(cam, 0x01C6, 0x04);
-+ err += zc0301_write_reg(cam, 0x01CB, 0x07);
-+ err += zc0301_write_reg(cam, 0x0120, 0x11);
-+ err += zc0301_write_reg(cam, 0x0121, 0x37);
-+ err += zc0301_write_reg(cam, 0x0122, 0x58);
-+ err += zc0301_write_reg(cam, 0x0123, 0x79);
-+ err += zc0301_write_reg(cam, 0x0124, 0x91);
-+ err += zc0301_write_reg(cam, 0x0125, 0xA6);
-+ err += zc0301_write_reg(cam, 0x0126, 0xB8);
-+ err += zc0301_write_reg(cam, 0x0127, 0xC7);
-+ err += zc0301_write_reg(cam, 0x0128, 0xD3);
-+ err += zc0301_write_reg(cam, 0x0129, 0xDE);
-+ err += zc0301_write_reg(cam, 0x012A, 0xE6);
-+ err += zc0301_write_reg(cam, 0x012B, 0xED);
-+ err += zc0301_write_reg(cam, 0x012C, 0xF3);
-+ err += zc0301_write_reg(cam, 0x012D, 0xF8);
-+ err += zc0301_write_reg(cam, 0x012E, 0xFB);
-+ err += zc0301_write_reg(cam, 0x012F, 0xFF);
-+ err += zc0301_write_reg(cam, 0x0130, 0x26);
-+ err += zc0301_write_reg(cam, 0x0131, 0x23);
-+ err += zc0301_write_reg(cam, 0x0132, 0x20);
-+ err += zc0301_write_reg(cam, 0x0133, 0x1C);
-+ err += zc0301_write_reg(cam, 0x0134, 0x16);
-+ err += zc0301_write_reg(cam, 0x0135, 0x13);
-+ err += zc0301_write_reg(cam, 0x0136, 0x10);
-+ err += zc0301_write_reg(cam, 0x0137, 0x0D);
-+ err += zc0301_write_reg(cam, 0x0138, 0x0B);
-+ err += zc0301_write_reg(cam, 0x0139, 0x09);
-+ err += zc0301_write_reg(cam, 0x013A, 0x07);
-+ err += zc0301_write_reg(cam, 0x013B, 0x06);
-+ err += zc0301_write_reg(cam, 0x013C, 0x05);
-+ err += zc0301_write_reg(cam, 0x013D, 0x04);
-+ err += zc0301_write_reg(cam, 0x013E, 0x03);
-+ err += zc0301_write_reg(cam, 0x013F, 0x02);
-+ err += zc0301_write_reg(cam, 0x010A, 0x4C);
-+ err += zc0301_write_reg(cam, 0x010B, 0xF5);
-+ err += zc0301_write_reg(cam, 0x010C, 0xFF);
-+ err += zc0301_write_reg(cam, 0x010D, 0xF9);
-+ err += zc0301_write_reg(cam, 0x010E, 0x51);
-+ err += zc0301_write_reg(cam, 0x010F, 0xF5);
-+ err += zc0301_write_reg(cam, 0x0110, 0xFB);
-+ err += zc0301_write_reg(cam, 0x0111, 0xED);
-+ err += zc0301_write_reg(cam, 0x0112, 0x5F);
-+ err += zc0301_write_reg(cam, 0x0180, 0x00);
-+ err += zc0301_write_reg(cam, 0x0019, 0x00);
-+ err += zc0301_write_reg(cam, 0x0087, 0x20);
-+ err += zc0301_write_reg(cam, 0x0088, 0x21);
-+
-+ err += zc0301_i2c_write(cam, 0x20, 0x02);
-+ err += zc0301_i2c_write(cam, 0x21, 0x1B);
-+ err += zc0301_i2c_write(cam, 0x03, 0x44);
-+ err += zc0301_i2c_write(cam, 0x0E, 0x01);
-+ err += zc0301_i2c_write(cam, 0x0F, 0x00);
-+
-+ err += zc0301_write_reg(cam, 0x01A9, 0x14);
-+ err += zc0301_write_reg(cam, 0x01AA, 0x24);
-+ err += zc0301_write_reg(cam, 0x0190, 0x00);
-+ err += zc0301_write_reg(cam, 0x0191, 0x02);
-+ err += zc0301_write_reg(cam, 0x0192, 0x1B);
-+ err += zc0301_write_reg(cam, 0x0195, 0x00);
-+ err += zc0301_write_reg(cam, 0x0196, 0x00);
-+ err += zc0301_write_reg(cam, 0x0197, 0x4D);
-+ err += zc0301_write_reg(cam, 0x018C, 0x10);
-+ err += zc0301_write_reg(cam, 0x018F, 0x20);
-+ err += zc0301_write_reg(cam, 0x001D, 0x44);
-+ err += zc0301_write_reg(cam, 0x001E, 0x6F);
-+ err += zc0301_write_reg(cam, 0x001F, 0xAD);
-+ err += zc0301_write_reg(cam, 0x0020, 0xEB);
-+ err += zc0301_write_reg(cam, 0x0087, 0x0F);
-+ err += zc0301_write_reg(cam, 0x0088, 0x0E);
-+ err += zc0301_write_reg(cam, 0x0180, 0x40);
-+ err += zc0301_write_reg(cam, 0x0192, 0x1B);
-+ err += zc0301_write_reg(cam, 0x0191, 0x02);
-+ err += zc0301_write_reg(cam, 0x0190, 0x00);
-+ err += zc0301_write_reg(cam, 0x0116, 0x1D);
-+ err += zc0301_write_reg(cam, 0x0117, 0x40);
-+ err += zc0301_write_reg(cam, 0x0118, 0x99);
-+ err += zc0301_write_reg(cam, 0x0180, 0x42);
-+ err += zc0301_write_reg(cam, 0x0116, 0x1D);
-+ err += zc0301_write_reg(cam, 0x0117, 0x40);
-+ err += zc0301_write_reg(cam, 0x0118, 0x99);
-+ err += zc0301_write_reg(cam, 0x0007, 0x00);
-+
-+ err += zc0301_i2c_write(cam, 0x11, 0x01);
-+
-+ msleep(100);
-+
-+ return err;
-+}
-+
-+
-+static int pas202bcb_get_ctrl(struct zc0301_device* cam,
-+ struct v4l2_control* ctrl)
-+{
-+ switch (ctrl->id) {
-+ case V4L2_CID_EXPOSURE:
-+ {
-+ int r1 = zc0301_i2c_read(cam, 0x04, 1),
-+ r2 = zc0301_i2c_read(cam, 0x05, 1);
-+ if (r1 < 0 || r2 < 0)
-+ return -EIO;
-+ ctrl->value = (r1 << 6) | (r2 & 0x3f);
-+ }
-+ return 0;
-+ case V4L2_CID_RED_BALANCE:
-+ if ((ctrl->value = zc0301_i2c_read(cam, 0x09, 1)) < 0)
-+ return -EIO;
-+ ctrl->value &= 0x0f;
-+ return 0;
-+ case V4L2_CID_BLUE_BALANCE:
-+ if ((ctrl->value = zc0301_i2c_read(cam, 0x07, 1)) < 0)
-+ return -EIO;
-+ ctrl->value &= 0x0f;
-+ return 0;
-+ case V4L2_CID_GAIN:
-+ if ((ctrl->value = zc0301_i2c_read(cam, 0x10, 1)) < 0)
-+ return -EIO;
-+ ctrl->value &= 0x1f;
-+ return 0;
-+ case ZC0301_V4L2_CID_GREEN_BALANCE:
-+ if ((ctrl->value = zc0301_i2c_read(cam, 0x08, 1)) < 0)
-+ return -EIO;
-+ ctrl->value &= 0x0f;
-+ return 0;
-+ case ZC0301_V4L2_CID_DAC_MAGNITUDE:
-+ if ((ctrl->value = zc0301_i2c_read(cam, 0x0c, 1)) < 0)
-+ return -EIO;
-+ return 0;
-+ default:
-+ return -EINVAL;
-+ }
-+}
-+
-+
-+static int pas202bcb_set_ctrl(struct zc0301_device* cam,
-+ const struct v4l2_control* ctrl)
-+{
-+ int err = 0;
-+
-+ switch (ctrl->id) {
-+ case V4L2_CID_EXPOSURE:
-+ err += zc0301_i2c_write(cam, 0x04, ctrl->value >> 6);
-+ err += zc0301_i2c_write(cam, 0x05, ctrl->value & 0x3f);
-+ break;
-+ case V4L2_CID_RED_BALANCE:
-+ err += zc0301_i2c_write(cam, 0x09, ctrl->value);
-+ break;
-+ case V4L2_CID_BLUE_BALANCE:
-+ err += zc0301_i2c_write(cam, 0x07, ctrl->value);
-+ break;
-+ case V4L2_CID_GAIN:
-+ err += zc0301_i2c_write(cam, 0x10, ctrl->value);
-+ break;
-+ case ZC0301_V4L2_CID_GREEN_BALANCE:
-+ err += zc0301_i2c_write(cam, 0x08, ctrl->value);
-+ break;
-+ case ZC0301_V4L2_CID_DAC_MAGNITUDE:
-+ err += zc0301_i2c_write(cam, 0x0c, ctrl->value);
-+ break;
-+ default:
-+ return -EINVAL;
-+ }
-+ err += zc0301_i2c_write(cam, 0x11, 0x01);
-+
-+ return err ? -EIO : 0;
-+}
-+
-+
-+static struct zc0301_sensor pas202bcb = {
-+ .name = "PAS202BCB",
-+ .init = &pas202bcb_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 = ZC0301_V4L2_CID_GREEN_BALANCE,
-+ .type = V4L2_CTRL_TYPE_INTEGER,
-+ .name = "green balance",
-+ .minimum = 0x00,
-+ .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,
-+ },
-+ },
-+ .get_ctrl = &pas202bcb_get_ctrl,
-+ .set_ctrl = &pas202bcb_set_ctrl,
-+ .cropcap = {
-+ .bounds = {
-+ .left = 0,
-+ .top = 0,
-+ .width = 640,
-+ .height = 480,
-+ },
-+ .defrect = {
-+ .left = 0,
-+ .top = 0,
-+ .width = 640,
-+ .height = 480,
-+ },
-+ },
-+ .pix_format = {
-+ .width = 640,
-+ .height = 480,
-+ .pixelformat = V4L2_PIX_FMT_JPEG,
-+ .priv = 16,
-+ },
-+};
-+
-+
-+int zc0301_probe_pas202bcb(struct zc0301_device* cam)
-+{
-+ int r0 = 0, r1 = 0, err = 0;
-+ unsigned int pid = 0;
-+
-+ err += zc0301_write_reg(cam, 0x0000, 0x01);
-+ err += zc0301_write_reg(cam, 0x0010, 0x0e);
-+ err += zc0301_write_reg(cam, 0x0001, 0x01);
-+ err += zc0301_write_reg(cam, 0x0012, 0x03);
-+ err += zc0301_write_reg(cam, 0x0012, 0x01);
-+ err += zc0301_write_reg(cam, 0x008d, 0x08);
-+
-+ msleep(10);
-+
-+ r0 = zc0301_i2c_read(cam, 0x00, 1);
-+ r1 = zc0301_i2c_read(cam, 0x01, 1);
-+
-+ if (r0 < 0 || r1 < 0 || err)
-+ return -EIO;
-+
-+ pid = (r0 << 4) | ((r1 & 0xf0) >> 4);
-+ if (pid != 0x017)
-+ return -ENODEV;
-+
-+ zc0301_attach_sensor(cam, &pas202bcb);
-+
-+ return 0;
-+}
---- /dev/null
-+++ gregkh-2.6/drivers/usb/media/zc0301_sensor.h
-@@ -0,0 +1,98 @@
-+/***************************************************************************
-+ * API for image sensors connected to the ZC030! Image Processor and *
-+ * Control Chip *
-+ * *
-+ * 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. *
-+ ***************************************************************************/
-+
-+#ifndef _ZC0301_SENSOR_H_
-+#define _ZC0301_SENSOR_H_
-+
-+#include <linux/usb.h>
-+#include <linux/videodev.h>
-+#include <linux/device.h>
-+#include <linux/stddef.h>
-+#include <linux/errno.h>
-+#include <asm/types.h>
-+
-+struct zc0301_device;
-+struct zc0301_sensor;
-+
-+/*****************************************************************************/
-+
-+extern int zc0301_probe_pas202bcb(struct zc0301_device* cam);
-+
-+#define ZC0301_SENSOR_TABLE \
-+/* Weak detections must go at the end of the list */ \
-+static int (*zc0301_sensor_table[])(struct zc0301_device*) = { \
-+ &zc0301_probe_pas202bcb, \
-+ NULL, \
-+};
-+
-+extern void
-+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 | \
-+ USB_DEVICE_ID_MATCH_INT_CLASS, \
-+ .idVendor = (vend), \
-+ .idProduct = (prod), \
-+ .bInterfaceClass = (intclass)
-+
-+#define ZC0301_ID_TABLE \
-+static const struct usb_device_id zc0301_id_table[] = { \
-+ { ZC0301_USB_DEVICE(0x046d, 0x08ae, 0xff), }, /* PAS202BCB */ \
-+ { } \
-+};
-+
-+/*****************************************************************************/
-+
-+extern int zc0301_write_reg(struct zc0301_device*, u16 index, u16 value);
-+extern int zc0301_read_reg(struct zc0301_device*, u16 index);
-+extern int zc0301_i2c_write(struct zc0301_device*, u16 address, u16 value);
-+extern int zc0301_i2c_read(struct zc0301_device*, u16 address, u8 length);
-+
-+/*****************************************************************************/
-+
-+#define ZC0301_MAX_CTRLS V4L2_CID_LASTP1-V4L2_CID_BASE+10
-+#define ZC0301_V4L2_CID_DAC_MAGNITUDE V4L2_CID_PRIVATE_BASE
-+#define ZC0301_V4L2_CID_GREEN_BALANCE V4L2_CID_PRIVATE_BASE + 1
-+
-+struct zc0301_sensor {
-+ char name[32];
-+
-+ struct v4l2_queryctrl qctrl[ZC0301_MAX_CTRLS];
-+ 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,
-+ const struct v4l2_control* ctrl);
-+ int (*set_crop)(struct zc0301_device* cam,
-+ const struct v4l2_rect* rect);
-+
-+ const struct usb_device* usbdev;
-+
-+ /* Private */
-+ struct v4l2_queryctrl _qctrl[ZC0301_MAX_CTRLS];
-+ struct v4l2_rect _rect;
-+};
-+
-+#endif /* _ZC0301_SENSOR_H_ */
diff --git a/usb/usb-convert-a-bunch-of-usb-semaphores-to-mutexes.patch b/usb/usb-convert-a-bunch-of-usb-semaphores-to-mutexes.patch
deleted file mode 100644
index 2df571a82b2fa..0000000000000
--- a/usb/usb-convert-a-bunch-of-usb-semaphores-to-mutexes.patch
+++ /dev/null
@@ -1,3199 +0,0 @@
-From SRS0+792853cd028d39ab690f+871+infradead.org+arjan@pentafluge.srs.infradead.org Wed Jan 11 13:33:30 2006
-From: Arjan van de Ven <arjan@infradead.org>
-Subject: USB: convert a bunch of USB semaphores to mutexes
-To: <greg@kroah.com>
-Cc: <mingo@elte.hu>
-Date: Wed, 11 Jan 2006 15:55:29 +0100
-Message-Id: <1136991329.2929.57.camel@laptopd505.fenrus.org>
-
-the patch below converts a bunch of semaphores-used-as-mutex in the USB
-code to mutexes
-
-
-Signed-off-by: Arjan van de Ven <arjan@infradead.org>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-
----
- drivers/usb/class/cdc-acm.c | 23 +++--
- drivers/usb/class/usblp.c | 15 ++-
- drivers/usb/core/devices.c | 7 +
- drivers/usb/core/hcd.c | 25 +++---
- drivers/usb/core/hcd.h | 2
- drivers/usb/core/hub.c | 7 +
- drivers/usb/core/notify.c | 15 ++-
- drivers/usb/core/usb.c | 5 -
- drivers/usb/image/mdc800.c | 63 ++++++++-------
- drivers/usb/input/ati_remote.c | 2
- drivers/usb/media/dabusb.c | 31 ++++---
- drivers/usb/media/dabusb.h | 2
- drivers/usb/media/ov511.c | 91 +++++++++++-----------
- drivers/usb/media/ov511.h | 11 +-
- drivers/usb/media/se401.c | 12 +--
- drivers/usb/media/se401.h | 3
- drivers/usb/media/sn9c102.h | 5 -
- drivers/usb/media/sn9c102_core.c | 156 +++++++++++++++++++--------------------
- drivers/usb/media/stv680.c | 13 +--
- drivers/usb/media/stv680.h | 2
- drivers/usb/media/usbvideo.c | 28 +++----
- drivers/usb/media/usbvideo.h | 5 -
- drivers/usb/media/vicam.c | 21 ++---
- drivers/usb/media/w9968cf.c | 75 ++++++++++--------
- drivers/usb/media/w9968cf.h | 14 ---
- drivers/usb/misc/idmouse.c | 25 +++---
- drivers/usb/misc/ldusb.c | 11 +-
- drivers/usb/misc/legousbtower.c | 11 +-
- drivers/usb/mon/mon_main.c | 19 ++--
- drivers/usb/mon/mon_text.c | 21 ++---
- drivers/usb/mon/usb_mon.h | 2
- drivers/usb/storage/scsiglue.c | 9 +-
- drivers/usb/storage/usb.c | 25 +++---
- drivers/usb/storage/usb.h | 5 -
- 34 files changed, 389 insertions(+), 372 deletions(-)
-
---- gregkh-2.6.orig/drivers/usb/class/cdc-acm.c
-+++ gregkh-2.6/drivers/usb/class/cdc-acm.c
-@@ -60,6 +60,7 @@
- #include <linux/tty_flip.h>
- #include <linux/module.h>
- #include <linux/smp_lock.h>
-+#include <linux/mutex.h>
- #include <asm/uaccess.h>
- #include <linux/usb.h>
- #include <linux/usb_cdc.h>
-@@ -80,7 +81,7 @@ static struct usb_driver acm_driver;
- static struct tty_driver *acm_tty_driver;
- static struct acm *acm_table[ACM_TTY_MINORS];
-
--static DECLARE_MUTEX(open_sem);
-+static DEFINE_MUTEX(open_mutex);
-
- #define ACM_READY(acm) (acm && acm->dev && acm->used)
-
-@@ -431,8 +432,8 @@ static int acm_tty_open(struct tty_struc
- int rv = -EINVAL;
- int i;
- dbg("Entering acm_tty_open.\n");
--
-- down(&open_sem);
-+
-+ mutex_lock(&open_mutex);
-
- acm = acm_table[tty->index];
- if (!acm || !acm->dev)
-@@ -474,14 +475,14 @@ static int acm_tty_open(struct tty_struc
-
- done:
- err_out:
-- up(&open_sem);
-+ mutex_unlock(&open_mutex);
- return rv;
-
- full_bailout:
- usb_kill_urb(acm->ctrlurb);
- bail_out:
- acm->used--;
-- up(&open_sem);
-+ mutex_unlock(&open_mutex);
- return -EIO;
- }
-
-@@ -507,7 +508,7 @@ static void acm_tty_close(struct tty_str
- if (!acm || !acm->used)
- return;
-
-- down(&open_sem);
-+ mutex_lock(&open_mutex);
- if (!--acm->used) {
- if (acm->dev) {
- acm_set_control(acm, acm->ctrlout = 0);
-@@ -518,7 +519,7 @@ static void acm_tty_close(struct tty_str
- } else
- acm_tty_unregister(acm);
- }
-- up(&open_sem);
-+ mutex_unlock(&open_mutex);
- }
-
- static int acm_tty_write(struct tty_struct *tty, const unsigned char *buf, int count)
-@@ -1013,9 +1014,9 @@ static void acm_disconnect(struct usb_in
- return;
- }
-
-- down(&open_sem);
-+ mutex_lock(&open_mutex);
- if (!usb_get_intfdata(intf)) {
-- up(&open_sem);
-+ mutex_unlock(&open_mutex);
- return;
- }
- acm->dev = NULL;
-@@ -1045,11 +1046,11 @@ static void acm_disconnect(struct usb_in
-
- if (!acm->used) {
- acm_tty_unregister(acm);
-- up(&open_sem);
-+ mutex_unlock(&open_mutex);
- return;
- }
-
-- up(&open_sem);
-+ mutex_unlock(&open_mutex);
-
- if (acm->tty)
- tty_hangup(acm->tty);
---- gregkh-2.6.orig/drivers/usb/class/usblp.c
-+++ gregkh-2.6/drivers/usb/class/usblp.c
-@@ -55,6 +55,7 @@
- #include <linux/init.h>
- #include <linux/slab.h>
- #include <linux/lp.h>
-+#include <linux/mutex.h>
- #undef DEBUG
- #include <linux/usb.h>
-
-@@ -223,7 +224,7 @@ static int usblp_cache_device_id_string(
-
- /* forward reference to make our lives easier */
- static struct usb_driver usblp_driver;
--static DECLARE_MUTEX(usblp_sem); /* locks the existence of usblp's */
-+static DEFINE_MUTEX(usblp_mutex); /* locks the existence of usblp's */
-
- /*
- * Functions for usblp control messages.
-@@ -351,7 +352,7 @@ static int usblp_open(struct inode *inod
- if (minor < 0)
- return -ENODEV;
-
-- down (&usblp_sem);
-+ mutex_lock (&usblp_mutex);
-
- retval = -ENODEV;
- intf = usb_find_interface(&usblp_driver, minor);
-@@ -399,7 +400,7 @@ static int usblp_open(struct inode *inod
- }
- }
- out:
-- up (&usblp_sem);
-+ mutex_unlock (&usblp_mutex);
- return retval;
- }
-
-@@ -425,13 +426,13 @@ static int usblp_release(struct inode *i
- {
- struct usblp *usblp = file->private_data;
-
-- down (&usblp_sem);
-+ mutex_lock (&usblp_mutex);
- usblp->used = 0;
- if (usblp->present) {
- usblp_unlink_urbs(usblp);
- } else /* finish cleanup from disconnect */
- usblp_cleanup (usblp);
-- up (&usblp_sem);
-+ mutex_unlock (&usblp_mutex);
- return 0;
- }
-
-@@ -1152,7 +1153,7 @@ static void usblp_disconnect(struct usb_
-
- device_remove_file(&intf->dev, &dev_attr_ieee1284_id);
-
-- down (&usblp_sem);
-+ mutex_lock (&usblp_mutex);
- down (&usblp->sem);
- usblp->present = 0;
- usb_set_intfdata (intf, NULL);
-@@ -1166,7 +1167,7 @@ static void usblp_disconnect(struct usb_
-
- if (!usblp->used)
- usblp_cleanup (usblp);
-- up (&usblp_sem);
-+ mutex_unlock (&usblp_mutex);
- }
-
- static struct usb_device_id usblp_ids [] = {
---- gregkh-2.6.orig/drivers/usb/core/devices.c
-+++ gregkh-2.6/drivers/usb/core/devices.c
-@@ -57,6 +57,7 @@
- #include <linux/usb.h>
- #include <linux/smp_lock.h>
- #include <linux/usbdevice_fs.h>
-+#include <linux/mutex.h>
- #include <asm/uaccess.h>
-
- #include "usb.h"
-@@ -570,7 +571,7 @@ static ssize_t usb_device_read(struct fi
- if (!access_ok(VERIFY_WRITE, buf, nbytes))
- return -EFAULT;
-
-- down (&usb_bus_list_lock);
-+ mutex_lock(&usb_bus_list_lock);
- /* print devices for all busses */
- list_for_each_entry(bus, &usb_bus_list, bus_list) {
- /* recurse through all children of the root hub */
-@@ -580,12 +581,12 @@ static ssize_t usb_device_read(struct fi
- ret = usb_device_dump(&buf, &nbytes, &skip_bytes, ppos, bus->root_hub, bus, 0, 0, 0);
- usb_unlock_device(bus->root_hub);
- if (ret < 0) {
-- up(&usb_bus_list_lock);
-+ mutex_unlock(&usb_bus_list_lock);
- return ret;
- }
- total_written += ret;
- }
-- up (&usb_bus_list_lock);
-+ mutex_unlock(&usb_bus_list_lock);
- return total_written;
- }
-
---- gregkh-2.6.orig/drivers/usb/core/hcd.c
-+++ gregkh-2.6/drivers/usb/core/hcd.c
-@@ -34,6 +34,7 @@
- #include <asm/scatterlist.h>
- #include <linux/device.h>
- #include <linux/dma-mapping.h>
-+#include <linux/mutex.h>
- #include <asm/irq.h>
- #include <asm/byteorder.h>
-
-@@ -93,7 +94,7 @@ struct usb_busmap {
- static struct usb_busmap busmap;
-
- /* used when updating list of hcds */
--DECLARE_MUTEX (usb_bus_list_lock); /* exported only for usbfs */
-+DEFINE_MUTEX(usb_bus_list_lock); /* exported only for usbfs */
- EXPORT_SYMBOL_GPL (usb_bus_list_lock);
-
- /* used for controlling access to virtual root hubs */
-@@ -761,14 +762,14 @@ static int usb_register_bus(struct usb_b
- {
- int busnum;
-
-- down (&usb_bus_list_lock);
-+ mutex_lock(&usb_bus_list_lock);
- busnum = find_next_zero_bit (busmap.busmap, USB_MAXBUS, 1);
- if (busnum < USB_MAXBUS) {
- set_bit (busnum, busmap.busmap);
- bus->busnum = busnum;
- } else {
- printk (KERN_ERR "%s: too many buses\n", usbcore_name);
-- up(&usb_bus_list_lock);
-+ mutex_unlock(&usb_bus_list_lock);
- return -E2BIG;
- }
-
-@@ -776,7 +777,7 @@ static int usb_register_bus(struct usb_b
- bus->controller, "usb_host%d", busnum);
- if (IS_ERR(bus->class_dev)) {
- clear_bit(busnum, busmap.busmap);
-- up(&usb_bus_list_lock);
-+ mutex_unlock(&usb_bus_list_lock);
- return PTR_ERR(bus->class_dev);
- }
-
-@@ -784,7 +785,7 @@ static int usb_register_bus(struct usb_b
-
- /* Add it to the local list of buses */
- list_add (&bus->bus_list, &usb_bus_list);
-- up (&usb_bus_list_lock);
-+ mutex_unlock(&usb_bus_list_lock);
-
- usb_notify_add_bus(bus);
-
-@@ -809,9 +810,9 @@ static void usb_deregister_bus (struct u
- * controller code, as well as having it call this when cleaning
- * itself up
- */
-- down (&usb_bus_list_lock);
-+ mutex_lock(&usb_bus_list_lock);
- list_del (&bus->bus_list);
-- up (&usb_bus_list_lock);
-+ mutex_unlock(&usb_bus_list_lock);
-
- usb_notify_remove_bus(bus);
-
-@@ -844,14 +845,14 @@ static int register_root_hub (struct usb
- set_bit (devnum, usb_dev->bus->devmap.devicemap);
- usb_set_device_state(usb_dev, USB_STATE_ADDRESS);
-
-- down (&usb_bus_list_lock);
-+ mutex_lock(&usb_bus_list_lock);
- usb_dev->bus->root_hub = usb_dev;
-
- usb_dev->ep0.desc.wMaxPacketSize = __constant_cpu_to_le16(64);
- retval = usb_get_device_descriptor(usb_dev, USB_DT_DEVICE_SIZE);
- if (retval != sizeof usb_dev->descriptor) {
- usb_dev->bus->root_hub = NULL;
-- up (&usb_bus_list_lock);
-+ mutex_unlock(&usb_bus_list_lock);
- dev_dbg (parent_dev, "can't read %s device descriptor %d\n",
- usb_dev->dev.bus_id, retval);
- return (retval < 0) ? retval : -EMSGSIZE;
-@@ -863,7 +864,7 @@ static int register_root_hub (struct usb
- dev_err (parent_dev, "can't register root hub for %s, %d\n",
- usb_dev->dev.bus_id, retval);
- }
-- up (&usb_bus_list_lock);
-+ mutex_unlock(&usb_bus_list_lock);
-
- if (retval == 0) {
- spin_lock_irq (&hcd_root_hub_lock);
-@@ -1891,9 +1892,9 @@ void usb_remove_hcd(struct usb_hcd *hcd)
- hcd->rh_registered = 0;
- spin_unlock_irq (&hcd_root_hub_lock);
-
-- down(&usb_bus_list_lock);
-+ mutex_lock(&usb_bus_list_lock);
- usb_disconnect(&hcd->self.root_hub);
-- up(&usb_bus_list_lock);
-+ mutex_unlock(&usb_bus_list_lock);
-
- hcd->poll_rh = 0;
- del_timer_sync(&hcd->rh_timer);
---- gregkh-2.6.orig/drivers/usb/core/hcd.h
-+++ gregkh-2.6/drivers/usb/core/hcd.h
-@@ -364,7 +364,7 @@ extern void usb_set_device_state(struct
- /* exported only within usbcore */
-
- extern struct list_head usb_bus_list;
--extern struct semaphore usb_bus_list_lock;
-+extern struct mutex usb_bus_list_lock;
- extern wait_queue_head_t usb_kill_urb_queue;
-
- extern struct usb_bus *usb_bus_get (struct usb_bus *bus);
---- gregkh-2.6.orig/drivers/usb/core/hub.c
-+++ gregkh-2.6/drivers/usb/core/hub.c
-@@ -22,6 +22,7 @@
- #include <linux/usb.h>
- #include <linux/usbdevice_fs.h>
- #include <linux/kthread.h>
-+#include <linux/mutex.h>
-
- #include <asm/semaphore.h>
- #include <asm/uaccess.h>
-@@ -2162,7 +2163,7 @@ static int
- hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,
- int retry_counter)
- {
-- static DECLARE_MUTEX(usb_address0_sem);
-+ static DEFINE_MUTEX(usb_address0_mutex);
-
- struct usb_device *hdev = hub->hdev;
- int i, j, retval;
-@@ -2183,7 +2184,7 @@ hub_port_init (struct usb_hub *hub, stru
- if (oldspeed == USB_SPEED_LOW)
- delay = HUB_LONG_RESET_TIME;
-
-- down(&usb_address0_sem);
-+ mutex_lock(&usb_address0_mutex);
-
- /* Reset the device; full speed may morph to high speed */
- retval = hub_port_reset(hub, port1, udev, delay);
-@@ -2381,7 +2382,7 @@ hub_port_init (struct usb_hub *hub, stru
- fail:
- if (retval)
- hub_port_disable(hub, port1, 0);
-- up(&usb_address0_sem);
-+ mutex_unlock(&usb_address0_mutex);
- return retval;
- }
-
---- gregkh-2.6.orig/drivers/usb/core/notify.c
-+++ gregkh-2.6/drivers/usb/core/notify.c
-@@ -13,16 +13,17 @@
- #include <linux/kernel.h>
- #include <linux/notifier.h>
- #include <linux/usb.h>
-+#include <linux/mutex.h>
- #include "usb.h"
-
-
- static struct notifier_block *usb_notifier_list;
--static DECLARE_MUTEX(usb_notifier_lock);
-+static DEFINE_MUTEX(usb_notifier_lock);
-
- static void usb_notifier_chain_register(struct notifier_block **list,
- struct notifier_block *n)
- {
-- down(&usb_notifier_lock);
-+ mutex_lock(&usb_notifier_lock);
- while (*list) {
- if (n->priority > (*list)->priority)
- break;
-@@ -30,13 +31,13 @@ static void usb_notifier_chain_register(
- }
- n->next = *list;
- *list = n;
-- up(&usb_notifier_lock);
-+ mutex_unlock(&usb_notifier_lock);
- }
-
- static void usb_notifier_chain_unregister(struct notifier_block **nl,
- struct notifier_block *n)
- {
-- down(&usb_notifier_lock);
-+ mutex_lock(&usb_notifier_lock);
- while ((*nl)!=NULL) {
- if ((*nl)==n) {
- *nl = n->next;
-@@ -45,7 +46,7 @@ static void usb_notifier_chain_unregiste
- nl=&((*nl)->next);
- }
- exit:
-- up(&usb_notifier_lock);
-+ mutex_unlock(&usb_notifier_lock);
- }
-
- static int usb_notifier_call_chain(struct notifier_block **n,
-@@ -54,7 +55,7 @@ static int usb_notifier_call_chain(struc
- int ret=NOTIFY_DONE;
- struct notifier_block *nb = *n;
-
-- down(&usb_notifier_lock);
-+ mutex_lock(&usb_notifier_lock);
- while (nb) {
- ret = nb->notifier_call(nb,val,v);
- if (ret&NOTIFY_STOP_MASK) {
-@@ -63,7 +64,7 @@ static int usb_notifier_call_chain(struc
- nb = nb->next;
- }
- exit:
-- up(&usb_notifier_lock);
-+ mutex_unlock(&usb_notifier_lock);
- return ret;
- }
-
---- gregkh-2.6.orig/drivers/usb/core/usb.c
-+++ gregkh-2.6/drivers/usb/core/usb.c
-@@ -33,6 +33,7 @@
- #include <linux/errno.h>
- #include <linux/smp_lock.h>
- #include <linux/usb.h>
-+#include <linux/mutex.h>
-
- #include <asm/io.h>
- #include <asm/scatterlist.h>
-@@ -639,7 +640,7 @@ struct usb_device *usb_find_device(u16 v
- struct usb_bus *bus;
- struct usb_device *dev = NULL;
-
-- down(&usb_bus_list_lock);
-+ mutex_lock(&usb_bus_list_lock);
- for (buslist = usb_bus_list.next;
- buslist != &usb_bus_list;
- buslist = buslist->next) {
-@@ -653,7 +654,7 @@ struct usb_device *usb_find_device(u16 v
- goto exit;
- }
- exit:
-- up(&usb_bus_list_lock);
-+ mutex_unlock(&usb_bus_list_lock);
- return dev;
- }
-
---- gregkh-2.6.orig/drivers/usb/image/mdc800.c
-+++ gregkh-2.6/drivers/usb/image/mdc800.c
-@@ -96,6 +96,7 @@
- #include <linux/module.h>
- #include <linux/smp_lock.h>
- #include <linux/wait.h>
-+#include <linux/mutex.h>
-
- #include <linux/usb.h>
- #include <linux/fs.h>
-@@ -169,7 +170,7 @@ struct mdc800_data
- int out_count; // Bytes in the buffer
-
- int open; // Camera device open ?
-- struct semaphore io_lock; // IO -lock
-+ struct mutex io_lock; // IO -lock
-
- char in [8]; // Command Input Buffer
- int in_count;
-@@ -497,7 +498,7 @@ static int mdc800_usb_probe (struct usb_
-
- info ("Found Mustek MDC800 on USB.");
-
-- down (&mdc800->io_lock);
-+ mutex_lock(&mdc800->io_lock);
-
- retval = usb_register_dev(intf, &mdc800_class);
- if (retval) {
-@@ -542,7 +543,7 @@ static int mdc800_usb_probe (struct usb_
-
- mdc800->state=READY;
-
-- up (&mdc800->io_lock);
-+ mutex_unlock(&mdc800->io_lock);
-
- usb_set_intfdata(intf, mdc800);
- return 0;
-@@ -620,7 +621,7 @@ static int mdc800_device_open (struct in
- int retval=0;
- int errn=0;
-
-- down (&mdc800->io_lock);
-+ mutex_lock(&mdc800->io_lock);
-
- if (mdc800->state == NOT_CONNECTED)
- {
-@@ -656,7 +657,7 @@ static int mdc800_device_open (struct in
- dbg ("Mustek MDC800 device opened.");
-
- error_out:
-- up (&mdc800->io_lock);
-+ mutex_unlock(&mdc800->io_lock);
- return errn;
- }
-
-@@ -669,7 +670,7 @@ static int mdc800_device_release (struct
- int retval=0;
- dbg ("Mustek MDC800 device closed.");
-
-- down (&mdc800->io_lock);
-+ mutex_lock(&mdc800->io_lock);
- if (mdc800->open && (mdc800->state != NOT_CONNECTED))
- {
- usb_kill_urb(mdc800->irq_urb);
-@@ -682,7 +683,7 @@ static int mdc800_device_release (struct
- retval=-EIO;
- }
-
-- up(&mdc800->io_lock);
-+ mutex_unlock(&mdc800->io_lock);
- return retval;
- }
-
-@@ -695,21 +696,21 @@ static ssize_t mdc800_device_read (struc
- size_t left=len, sts=len; /* single transfer size */
- char __user *ptr = buf;
-
-- down (&mdc800->io_lock);
-+ mutex_lock(&mdc800->io_lock);
- if (mdc800->state == NOT_CONNECTED)
- {
-- up (&mdc800->io_lock);
-+ mutex_unlock(&mdc800->io_lock);
- return -EBUSY;
- }
- if (mdc800->state == WORKING)
- {
- warn ("Illegal State \"working\" reached during read ?!");
-- up (&mdc800->io_lock);
-+ mutex_unlock(&mdc800->io_lock);
- return -EBUSY;
- }
- if (!mdc800->open)
- {
-- up (&mdc800->io_lock);
-+ mutex_unlock(&mdc800->io_lock);
- return -EBUSY;
- }
-
-@@ -717,7 +718,7 @@ static ssize_t mdc800_device_read (struc
- {
- if (signal_pending (current))
- {
-- up (&mdc800->io_lock);
-+ mutex_unlock(&mdc800->io_lock);
- return -EINTR;
- }
-
-@@ -736,7 +737,7 @@ static ssize_t mdc800_device_read (struc
- if (usb_submit_urb (mdc800->download_urb, GFP_KERNEL))
- {
- err ("Can't submit download urb (status=%i)",mdc800->download_urb->status);
-- up (&mdc800->io_lock);
-+ mutex_unlock(&mdc800->io_lock);
- return len-left;
- }
- wait_event_timeout(mdc800->download_wait, mdc800->downloaded,
-@@ -745,14 +746,14 @@ static ssize_t mdc800_device_read (struc
- if (mdc800->download_urb->status != 0)
- {
- err ("request download-bytes fails (status=%i)",mdc800->download_urb->status);
-- up (&mdc800->io_lock);
-+ mutex_unlock(&mdc800->io_lock);
- return len-left;
- }
- }
- else
- {
- /* No more bytes -> that's an error*/
-- up (&mdc800->io_lock);
-+ mutex_unlock(&mdc800->io_lock);
- return -EIO;
- }
- }
-@@ -761,7 +762,7 @@ static ssize_t mdc800_device_read (struc
- /* Copy Bytes */
- if (copy_to_user(ptr, &mdc800->out [mdc800->out_ptr],
- sts)) {
-- up(&mdc800->io_lock);
-+ mutex_unlock(&mdc800->io_lock);
- return -EFAULT;
- }
- ptr+=sts;
-@@ -770,7 +771,7 @@ static ssize_t mdc800_device_read (struc
- }
- }
-
-- up (&mdc800->io_lock);
-+ mutex_unlock(&mdc800->io_lock);
- return len-left;
- }
-
-@@ -785,15 +786,15 @@ static ssize_t mdc800_device_write (stru
- {
- size_t i=0;
-
-- down (&mdc800->io_lock);
-+ mutex_lock(&mdc800->io_lock);
- if (mdc800->state != READY)
- {
-- up (&mdc800->io_lock);
-+ mutex_unlock(&mdc800->io_lock);
- return -EBUSY;
- }
- if (!mdc800->open )
- {
-- up (&mdc800->io_lock);
-+ mutex_unlock(&mdc800->io_lock);
- return -EBUSY;
- }
-
-@@ -802,13 +803,13 @@ static ssize_t mdc800_device_write (stru
- unsigned char c;
- if (signal_pending (current))
- {
-- up (&mdc800->io_lock);
-+ mutex_unlock(&mdc800->io_lock);
- return -EINTR;
- }
-
- if(get_user(c, buf+i))
- {
-- up(&mdc800->io_lock);
-+ mutex_unlock(&mdc800->io_lock);
- return -EFAULT;
- }
-
-@@ -829,7 +830,7 @@ static ssize_t mdc800_device_write (stru
- }
- else
- {
-- up (&mdc800->io_lock);
-+ mutex_unlock(&mdc800->io_lock);
- return -EIO;
- }
-
-@@ -841,7 +842,7 @@ static ssize_t mdc800_device_write (stru
- if (mdc800_usb_waitForIRQ (0,TO_GET_READY))
- {
- err ("Camera didn't get ready.\n");
-- up (&mdc800->io_lock);
-+ mutex_unlock(&mdc800->io_lock);
- return -EIO;
- }
-
-@@ -853,7 +854,7 @@ static ssize_t mdc800_device_write (stru
- if (usb_submit_urb (mdc800->write_urb, GFP_KERNEL))
- {
- err ("submitting write urb fails (status=%i)", mdc800->write_urb->status);
-- up (&mdc800->io_lock);
-+ mutex_unlock(&mdc800->io_lock);
- return -EIO;
- }
- wait_event_timeout(mdc800->write_wait, mdc800->written, TO_WRITE_GET_READY*HZ/1000);
-@@ -861,7 +862,7 @@ static ssize_t mdc800_device_write (stru
- if (mdc800->state == WORKING)
- {
- usb_kill_urb(mdc800->write_urb);
-- up (&mdc800->io_lock);
-+ mutex_unlock(&mdc800->io_lock);
- return -EIO;
- }
-
-@@ -873,7 +874,7 @@ static ssize_t mdc800_device_write (stru
- {
- err ("call 0x07 before 0x05,0x3e");
- mdc800->state=READY;
-- up (&mdc800->io_lock);
-+ mutex_unlock(&mdc800->io_lock);
- return -EIO;
- }
- mdc800->pic_len=-1;
-@@ -892,7 +893,7 @@ static ssize_t mdc800_device_write (stru
- if (mdc800_usb_waitForIRQ (1,TO_READ_FROM_IRQ))
- {
- err ("requesting answer from irq fails");
-- up (&mdc800->io_lock);
-+ mutex_unlock(&mdc800->io_lock);
- return -EIO;
- }
-
-@@ -920,7 +921,7 @@ static ssize_t mdc800_device_write (stru
- if (mdc800_usb_waitForIRQ (0,TO_DEFAULT_COMMAND))
- {
- err ("Command Timeout.");
-- up (&mdc800->io_lock);
-+ mutex_unlock(&mdc800->io_lock);
- return -EIO;
- }
- }
-@@ -930,7 +931,7 @@ static ssize_t mdc800_device_write (stru
- }
- i++;
- }
-- up (&mdc800->io_lock);
-+ mutex_unlock(&mdc800->io_lock);
- return i;
- }
-
-@@ -984,7 +985,7 @@ static int __init usb_mdc800_init (void)
-
- mdc800->dev = NULL;
- mdc800->state=NOT_CONNECTED;
-- init_MUTEX (&mdc800->io_lock);
-+ mutex_init (&mdc800->io_lock);
-
- init_waitqueue_head (&mdc800->irq_wait);
- init_waitqueue_head (&mdc800->write_wait);
---- gregkh-2.6.orig/drivers/usb/input/ati_remote.c
-+++ gregkh-2.6/drivers/usb/input/ati_remote.c
-@@ -159,8 +159,6 @@ static const char accel[] = { 1, 2, 4, 6
- */
- #define FILTER_TIME (HZ / 20)
-
--static DECLARE_MUTEX(disconnect_sem);
--
- struct ati_remote {
- struct input_dev *idev;
- struct usb_device *udev;
---- gregkh-2.6.orig/drivers/usb/media/dabusb.c
-+++ gregkh-2.6/drivers/usb/media/dabusb.c
-@@ -38,6 +38,7 @@
- #include <linux/delay.h>
- #include <linux/usb.h>
- #include <linux/smp_lock.h>
-+#include <linux/mutex.h>
-
- #include "dabusb.h"
- #include "dabfirmware.h"
-@@ -570,7 +571,7 @@ static ssize_t dabusb_read (struct file
- s->readptr = 0;
- }
- }
-- err: //up(&s->mutex);
-+ err: //mutex_unlock(&s->mutex);
- return ret;
- }
-
-@@ -585,10 +586,10 @@ static int dabusb_open (struct inode *in
- s = &dabusb[devnum - DABUSB_MINOR];
-
- dbg("dabusb_open");
-- down (&s->mutex);
-+ mutex_lock(&s->mutex);
-
- while (!s->usbdev || s->opened) {
-- up (&s->mutex);
-+ mutex_unlock(&s->mutex);
-
- if (file->f_flags & O_NONBLOCK) {
- return -EBUSY;
-@@ -598,15 +599,15 @@ static int dabusb_open (struct inode *in
- if (signal_pending (current)) {
- return -EAGAIN;
- }
-- down (&s->mutex);
-+ mutex_lock(&s->mutex);
- }
- if (usb_set_interface (s->usbdev, _DABUSB_IF, 1) < 0) {
-- up(&s->mutex);
-+ mutex_unlock(&s->mutex);
- err("set_interface failed");
- return -EINVAL;
- }
- s->opened = 1;
-- up (&s->mutex);
-+ mutex_unlock(&s->mutex);
-
- file->f_pos = 0;
- file->private_data = s;
-@@ -620,10 +621,10 @@ static int dabusb_release (struct inode
-
- dbg("dabusb_release");
-
-- down (&s->mutex);
-+ mutex_lock(&s->mutex);
- dabusb_stop (s);
- dabusb_free_buffers (s);
-- up (&s->mutex);
-+ mutex_unlock(&s->mutex);
-
- if (!s->remove_pending) {
- if (usb_set_interface (s->usbdev, _DABUSB_IF, 0) < 0)
-@@ -648,10 +649,10 @@ static int dabusb_ioctl (struct inode *i
- if (s->remove_pending)
- return -EIO;
-
-- down (&s->mutex);
-+ mutex_lock(&s->mutex);
-
- if (!s->usbdev) {
-- up (&s->mutex);
-+ mutex_unlock(&s->mutex);
- return -EIO;
- }
-
-@@ -691,7 +692,7 @@ static int dabusb_ioctl (struct inode *i
- ret = -ENOIOCTLCMD;
- break;
- }
-- up (&s->mutex);
-+ mutex_unlock(&s->mutex);
- return ret;
- }
-
-@@ -737,7 +738,7 @@ static int dabusb_probe (struct usb_inte
-
- s = &dabusb[intf->minor];
-
-- down (&s->mutex);
-+ mutex_lock(&s->mutex);
- s->remove_pending = 0;
- s->usbdev = usbdev;
- s->devnum = intf->minor;
-@@ -760,7 +761,7 @@ static int dabusb_probe (struct usb_inte
- }
- dbg("bound to interface: %d", intf->altsetting->desc.bInterfaceNumber);
- usb_set_intfdata (intf, s);
-- up (&s->mutex);
-+ mutex_unlock(&s->mutex);
-
- retval = usb_register_dev(intf, &dabusb_class);
- if (retval) {
-@@ -771,7 +772,7 @@ static int dabusb_probe (struct usb_inte
- return 0;
-
- reject:
-- up (&s->mutex);
-+ mutex_unlock(&s->mutex);
- s->usbdev = NULL;
- return -ENODEV;
- }
-@@ -828,7 +829,7 @@ static int __init dabusb_init (void)
- for (u = 0; u < NRDABUSB; u++) {
- pdabusb_t s = &dabusb[u];
- memset (s, 0, sizeof (dabusb_t));
-- init_MUTEX (&s->mutex);
-+ mutex_init (&s->mutex);
- s->usbdev = NULL;
- s->total_buffer_size = buffers;
- init_waitqueue_head (&s->wait);
---- gregkh-2.6.orig/drivers/usb/media/dabusb.h
-+++ gregkh-2.6/drivers/usb/media/dabusb.h
-@@ -18,7 +18,7 @@ typedef enum { _stopped=0, _started } dr
-
- typedef struct
- {
-- struct semaphore mutex;
-+ struct mutex mutex;
- struct usb_device *usbdev;
- wait_queue_head_t wait;
- wait_queue_head_t remove_ok;
---- gregkh-2.6.orig/drivers/usb/media/ov511.c
-+++ gregkh-2.6/drivers/usb/media/ov511.c
-@@ -365,14 +365,14 @@ reg_w(struct usb_ov511 *ov, unsigned cha
-
- PDEBUG(5, "0x%02X:0x%02X", reg, value);
-
-- down(&ov->cbuf_lock);
-+ mutex_lock(&ov->cbuf_lock);
- ov->cbuf[0] = value;
- rc = usb_control_msg(ov->dev,
- usb_sndctrlpipe(ov->dev, 0),
- (ov->bclass == BCL_OV518)?1:2 /* REG_IO */,
- USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 0, (__u16)reg, &ov->cbuf[0], 1, 1000);
-- up(&ov->cbuf_lock);
-+ mutex_unlock(&ov->cbuf_lock);
-
- if (rc < 0)
- err("reg write: error %d: %s", rc, symbolic(urb_errlist, rc));
-@@ -387,7 +387,7 @@ reg_r(struct usb_ov511 *ov, unsigned cha
- {
- int rc;
-
-- down(&ov->cbuf_lock);
-+ mutex_lock(&ov->cbuf_lock);
- rc = usb_control_msg(ov->dev,
- usb_rcvctrlpipe(ov->dev, 0),
- (ov->bclass == BCL_OV518)?1:3 /* REG_IO */,
-@@ -401,7 +401,7 @@ reg_r(struct usb_ov511 *ov, unsigned cha
- PDEBUG(5, "0x%02X:0x%02X", reg, ov->cbuf[0]);
- }
-
-- up(&ov->cbuf_lock);
-+ mutex_unlock(&ov->cbuf_lock);
-
- return rc;
- }
-@@ -444,7 +444,7 @@ ov518_reg_w32(struct usb_ov511 *ov, unsi
-
- PDEBUG(5, "0x%02X:%7d, n=%d", reg, val, n);
-
-- down(&ov->cbuf_lock);
-+ mutex_lock(&ov->cbuf_lock);
-
- *((__le32 *)ov->cbuf) = __cpu_to_le32(val);
-
-@@ -453,7 +453,7 @@ ov518_reg_w32(struct usb_ov511 *ov, unsi
- 1 /* REG_IO */,
- USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 0, (__u16)reg, ov->cbuf, n, 1000);
-- up(&ov->cbuf_lock);
-+ mutex_unlock(&ov->cbuf_lock);
-
- if (rc < 0)
- err("reg write multiple: error %d: %s", rc,
-@@ -768,14 +768,14 @@ i2c_r(struct usb_ov511 *ov, unsigned cha
- {
- int rc;
-
-- down(&ov->i2c_lock);
-+ mutex_lock(&ov->i2c_lock);
-
- if (ov->bclass == BCL_OV518)
- rc = ov518_i2c_read_internal(ov, reg);
- else
- rc = ov511_i2c_read_internal(ov, reg);
-
-- up(&ov->i2c_lock);
-+ mutex_unlock(&ov->i2c_lock);
-
- return rc;
- }
-@@ -785,14 +785,14 @@ i2c_w(struct usb_ov511 *ov, unsigned cha
- {
- int rc;
-
-- down(&ov->i2c_lock);
-+ mutex_lock(&ov->i2c_lock);
-
- if (ov->bclass == BCL_OV518)
- rc = ov518_i2c_write_internal(ov, reg, value);
- else
- rc = ov511_i2c_write_internal(ov, reg, value);
-
-- up(&ov->i2c_lock);
-+ mutex_unlock(&ov->i2c_lock);
-
- return rc;
- }
-@@ -842,9 +842,9 @@ i2c_w_mask(struct usb_ov511 *ov,
- {
- int rc;
-
-- down(&ov->i2c_lock);
-+ mutex_lock(&ov->i2c_lock);
- rc = ov51x_i2c_write_mask_internal(ov, reg, value, mask);
-- up(&ov->i2c_lock);
-+ mutex_unlock(&ov->i2c_lock);
-
- return rc;
- }
-@@ -880,7 +880,7 @@ i2c_w_slave(struct usb_ov511 *ov,
- {
- int rc = 0;
-
-- down(&ov->i2c_lock);
-+ mutex_lock(&ov->i2c_lock);
-
- /* Set new slave IDs */
- rc = i2c_set_slave_internal(ov, slave);
-@@ -894,7 +894,7 @@ out:
- if (i2c_set_slave_internal(ov, ov->primary_i2c_slave) < 0)
- err("Couldn't restore primary I2C slave");
-
-- up(&ov->i2c_lock);
-+ mutex_unlock(&ov->i2c_lock);
- return rc;
- }
-
-@@ -906,7 +906,7 @@ i2c_r_slave(struct usb_ov511 *ov,
- {
- int rc;
-
-- down(&ov->i2c_lock);
-+ mutex_lock(&ov->i2c_lock);
-
- /* Set new slave IDs */
- rc = i2c_set_slave_internal(ov, slave);
-@@ -923,7 +923,7 @@ out:
- if (i2c_set_slave_internal(ov, ov->primary_i2c_slave) < 0)
- err("Couldn't restore primary I2C slave");
-
-- up(&ov->i2c_lock);
-+ mutex_unlock(&ov->i2c_lock);
- return rc;
- }
-
-@@ -933,7 +933,7 @@ ov51x_set_slave_ids(struct usb_ov511 *ov
- {
- int rc;
-
-- down(&ov->i2c_lock);
-+ mutex_lock(&ov->i2c_lock);
-
- rc = i2c_set_slave_internal(ov, sid);
- if (rc < 0)
-@@ -942,7 +942,7 @@ ov51x_set_slave_ids(struct usb_ov511 *ov
- // FIXME: Is this actually necessary?
- rc = ov51x_reset(ov, OV511_RESET_NOREGS);
- out:
-- up(&ov->i2c_lock);
-+ mutex_unlock(&ov->i2c_lock);
- return rc;
- }
-
-@@ -3832,7 +3832,7 @@ ov51x_alloc(struct usb_ov511 *ov)
- const int raw_bufsize = OV511_NUMFRAMES * MAX_RAW_DATA_SIZE(w, h);
-
- PDEBUG(4, "entered");
-- down(&ov->buf_lock);
-+ mutex_lock(&ov->buf_lock);
-
- if (ov->buf_state == BUF_ALLOCATED)
- goto out;
-@@ -3879,12 +3879,12 @@ ov51x_alloc(struct usb_ov511 *ov)
-
- ov->buf_state = BUF_ALLOCATED;
- out:
-- up(&ov->buf_lock);
-+ mutex_unlock(&ov->buf_lock);
- PDEBUG(4, "leaving");
- return 0;
- error:
- ov51x_do_dealloc(ov);
-- up(&ov->buf_lock);
-+ mutex_unlock(&ov->buf_lock);
- PDEBUG(4, "errored");
- return -ENOMEM;
- }
-@@ -3893,9 +3893,9 @@ static void
- ov51x_dealloc(struct usb_ov511 *ov)
- {
- PDEBUG(4, "entered");
-- down(&ov->buf_lock);
-+ mutex_lock(&ov->buf_lock);
- ov51x_do_dealloc(ov);
-- up(&ov->buf_lock);
-+ mutex_unlock(&ov->buf_lock);
- PDEBUG(4, "leaving");
- }
-
-@@ -3914,7 +3914,7 @@ ov51x_v4l1_open(struct inode *inode, str
-
- PDEBUG(4, "opening");
-
-- down(&ov->lock);
-+ mutex_lock(&ov->lock);
-
- err = -EBUSY;
- if (ov->user)
-@@ -3958,7 +3958,7 @@ ov51x_v4l1_open(struct inode *inode, str
- ov51x_led_control(ov, 1);
-
- out:
-- up(&ov->lock);
-+ mutex_unlock(&ov->lock);
- return err;
- }
-
-@@ -3970,7 +3970,7 @@ ov51x_v4l1_close(struct inode *inode, st
-
- PDEBUG(4, "ov511_close");
-
-- down(&ov->lock);
-+ mutex_lock(&ov->lock);
-
- ov->user--;
- ov51x_stop_isoc(ov);
-@@ -3981,15 +3981,15 @@ ov51x_v4l1_close(struct inode *inode, st
- if (ov->dev)
- ov51x_dealloc(ov);
-
-- up(&ov->lock);
-+ mutex_unlock(&ov->lock);
-
- /* Device unplugged while open. Only a minimum of unregistration is done
- * here; the disconnect callback already did the rest. */
- if (!ov->dev) {
-- down(&ov->cbuf_lock);
-+ mutex_lock(&ov->cbuf_lock);
- kfree(ov->cbuf);
- ov->cbuf = NULL;
-- up(&ov->cbuf_lock);
-+ mutex_unlock(&ov->cbuf_lock);
-
- ov51x_dealloc(ov);
- kfree(ov);
-@@ -4449,12 +4449,12 @@ ov51x_v4l1_ioctl(struct inode *inode, st
- struct usb_ov511 *ov = video_get_drvdata(vdev);
- int rc;
-
-- if (down_interruptible(&ov->lock))
-+ if (mutex_lock_interruptible(&ov->lock))
- return -EINTR;
-
- rc = video_usercopy(inode, file, cmd, arg, ov51x_v4l1_ioctl_internal);
-
-- up(&ov->lock);
-+ mutex_unlock(&ov->lock);
- return rc;
- }
-
-@@ -4468,7 +4468,7 @@ ov51x_v4l1_read(struct file *file, char
- int i, rc = 0, frmx = -1;
- struct ov511_frame *frame;
-
-- if (down_interruptible(&ov->lock))
-+ if (mutex_lock_interruptible(&ov->lock))
- return -EINTR;
-
- PDEBUG(4, "%ld bytes, noblock=%d", count, noblock);
-@@ -4604,11 +4604,11 @@ restart:
-
- PDEBUG(4, "read finished, returning %ld (sweet)", count);
-
-- up(&ov->lock);
-+ mutex_unlock(&ov->lock);
- return count;
-
- error:
-- up(&ov->lock);
-+ mutex_unlock(&ov->lock);
- return rc;
- }
-
-@@ -4631,14 +4631,14 @@ ov51x_v4l1_mmap(struct file *file, struc
- + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1))))
- return -EINVAL;
-
-- if (down_interruptible(&ov->lock))
-+ if (mutex_lock_interruptible(&ov->lock))
- return -EINTR;
-
- pos = (unsigned long)ov->fbuf;
- while (size > 0) {
- page = vmalloc_to_pfn((void *)pos);
- if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) {
-- up(&ov->lock);
-+ mutex_unlock(&ov->lock);
- return -EAGAIN;
- }
- start += PAGE_SIZE;
-@@ -4649,7 +4649,7 @@ ov51x_v4l1_mmap(struct file *file, struc
- size = 0;
- }
-
-- up(&ov->lock);
-+ mutex_unlock(&ov->lock);
- return 0;
- }
-
-@@ -5738,11 +5738,10 @@ ov51x_probe(struct usb_interface *intf,
-
- init_waitqueue_head(&ov->wq);
-
-- init_MUTEX(&ov->lock); /* to 1 == available */
-- init_MUTEX(&ov->buf_lock);
-- init_MUTEX(&ov->param_lock);
-- init_MUTEX(&ov->i2c_lock);
-- init_MUTEX(&ov->cbuf_lock);
-+ mutex_init(&ov->lock); /* to 1 == available */
-+ mutex_init(&ov->buf_lock);
-+ mutex_init(&ov->i2c_lock);
-+ mutex_init(&ov->cbuf_lock);
-
- ov->buf_state = BUF_NOT_ALLOCATED;
-
-@@ -5833,10 +5832,10 @@ error:
- }
-
- if (ov->cbuf) {
-- down(&ov->cbuf_lock);
-+ mutex_lock(&ov->cbuf_lock);
- kfree(ov->cbuf);
- ov->cbuf = NULL;
-- up(&ov->cbuf_lock);
-+ mutex_unlock(&ov->cbuf_lock);
- }
-
- kfree(ov);
-@@ -5881,10 +5880,10 @@ ov51x_disconnect(struct usb_interface *i
-
- /* Free the memory */
- if (ov && !ov->user) {
-- down(&ov->cbuf_lock);
-+ mutex_lock(&ov->cbuf_lock);
- kfree(ov->cbuf);
- ov->cbuf = NULL;
-- up(&ov->cbuf_lock);
-+ mutex_unlock(&ov->cbuf_lock);
-
- ov51x_dealloc(ov);
- kfree(ov);
---- gregkh-2.6.orig/drivers/usb/media/ov511.h
-+++ gregkh-2.6/drivers/usb/media/ov511.h
-@@ -5,6 +5,7 @@
- #include <linux/videodev.h>
- #include <linux/smp_lock.h>
- #include <linux/usb.h>
-+#include <linux/mutex.h>
-
- #define OV511_DEBUG /* Turn on debug messages */
-
-@@ -435,7 +436,7 @@ struct usb_ov511 {
-
- int led_policy; /* LED: off|on|auto; OV511+ only */
-
-- struct semaphore lock; /* Serializes user-accessible operations */
-+ struct mutex lock; /* Serializes user-accessible operations */
- int user; /* user count for exclusive use */
-
- int streaming; /* Are we streaming Isochronous? */
-@@ -473,11 +474,9 @@ struct usb_ov511 {
- int packet_size; /* Frame size per isoc desc */
- int packet_numbering; /* Is ISO frame numbering enabled? */
-
-- struct semaphore param_lock; /* params lock for this camera */
--
- /* Framebuffer/sbuf management */
- int buf_state;
-- struct semaphore buf_lock;
-+ struct mutex buf_lock;
-
- struct ov51x_decomp_ops *decomp_ops;
-
-@@ -494,12 +493,12 @@ struct usb_ov511 {
- int pal; /* Device is designed for PAL resolution */
-
- /* I2C interface */
-- struct semaphore i2c_lock; /* Protect I2C controller regs */
-+ struct mutex i2c_lock; /* Protect I2C controller regs */
- unsigned char primary_i2c_slave; /* I2C write id of sensor */
-
- /* Control transaction stuff */
- unsigned char *cbuf; /* Buffer for payload */
-- struct semaphore cbuf_lock;
-+ struct mutex cbuf_lock;
- };
-
- /* Used to represent a list of values and their respective symbolic names */
---- gregkh-2.6.orig/drivers/usb/media/se401.c
-+++ gregkh-2.6/drivers/usb/media/se401.c
-@@ -1157,21 +1157,21 @@ static int se401_mmap(struct file *file,
- unsigned long size = vma->vm_end-vma->vm_start;
- unsigned long page, pos;
-
-- down(&se401->lock);
-+ mutex_lock(&se401->lock);
-
- if (se401->dev == NULL) {
-- up(&se401->lock);
-+ mutex_unlock(&se401->lock);
- return -EIO;
- }
- if (size > (((SE401_NUMFRAMES * se401->maxframesize) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1))) {
-- up(&se401->lock);
-+ mutex_unlock(&se401->lock);
- return -EINVAL;
- }
- pos = (unsigned long)se401->fbuf;
- while (size > 0) {
- page = vmalloc_to_pfn((void *)pos);
- if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) {
-- up(&se401->lock);
-+ mutex_unlock(&se401->lock);
- return -EAGAIN;
- }
- start += PAGE_SIZE;
-@@ -1181,7 +1181,7 @@ static int se401_mmap(struct file *file,
- else
- size = 0;
- }
-- up(&se401->lock);
-+ mutex_unlock(&se401->lock);
-
- return 0;
- }
-@@ -1366,7 +1366,7 @@ static int se401_probe(struct usb_interf
- memcpy(&se401->vdev, &se401_template, sizeof(se401_template));
- memcpy(se401->vdev.name, se401->camera_name, strlen(se401->camera_name));
- init_waitqueue_head(&se401->wq);
-- init_MUTEX(&se401->lock);
-+ mutex_init(&se401->lock);
- wmb();
-
- if (video_register_device(&se401->vdev, VFL_TYPE_GRABBER, video_nr) == -1) {
---- gregkh-2.6.orig/drivers/usb/media/se401.h
-+++ gregkh-2.6/drivers/usb/media/se401.h
-@@ -5,6 +5,7 @@
- #include <asm/uaccess.h>
- #include <linux/videodev.h>
- #include <linux/smp_lock.h>
-+#include <linux/mutex.h>
-
- #define se401_DEBUG /* Turn on debug messages */
-
-@@ -189,7 +190,7 @@ struct usb_se401 {
- int maxframesize;
- int cframesize; /* current framesize */
-
-- struct semaphore lock;
-+ struct mutex lock;
- int user; /* user count for exclusive use */
- int removed; /* device disconnected */
-
---- gregkh-2.6.orig/drivers/usb/media/sn9c102.h
-+++ gregkh-2.6/drivers/usb/media/sn9c102.h
-@@ -33,6 +33,7 @@
- #include <linux/types.h>
- #include <linux/param.h>
- #include <linux/rwsem.h>
-+#include <linux/mutex.h>
- #include <asm/semaphore.h>
-
- #include "sn9c102_sensor.h"
-@@ -109,7 +110,7 @@ struct sn9c102_module_param {
- u8 force_munmap;
- };
-
--static DECLARE_MUTEX(sn9c102_sysfs_lock);
-+static DEFINE_MUTEX(sn9c102_sysfs_lock);
- static DECLARE_RWSEM(sn9c102_disconnect);
-
- struct sn9c102_device {
-@@ -141,7 +142,7 @@ struct sn9c102_device {
- enum sn9c102_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;
- };
---- gregkh-2.6.orig/drivers/usb/media/sn9c102_core.c
-+++ gregkh-2.6/drivers/usb/media/sn9c102_core.c
-@@ -866,18 +866,18 @@ static ssize_t sn9c102_show_reg(struct c
- struct sn9c102_device* cam;
- ssize_t count;
-
-- if (down_interruptible(&sn9c102_sysfs_lock))
-+ if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
- return -ERESTARTSYS;
-
- cam = video_get_drvdata(to_video_device(cd));
- if (!cam) {
-- up(&sn9c102_sysfs_lock);
-+ mutex_unlock(&sn9c102_sysfs_lock);
- return -ENODEV;
- }
-
- count = sprintf(buf, "%u\n", cam->sysfs.reg);
-
-- up(&sn9c102_sysfs_lock);
-+ mutex_unlock(&sn9c102_sysfs_lock);
-
- return count;
- }
-@@ -890,18 +890,18 @@ sn9c102_store_reg(struct class_device* c
- u8 index;
- ssize_t count;
-
-- if (down_interruptible(&sn9c102_sysfs_lock))
-+ if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
- return -ERESTARTSYS;
-
- cam = video_get_drvdata(to_video_device(cd));
- if (!cam) {
-- up(&sn9c102_sysfs_lock);
-+ mutex_unlock(&sn9c102_sysfs_lock);
- return -ENODEV;
- }
-
- index = sn9c102_strtou8(buf, len, &count);
- if (index > 0x1f || !count) {
-- up(&sn9c102_sysfs_lock);
-+ mutex_unlock(&sn9c102_sysfs_lock);
- return -EINVAL;
- }
-
-@@ -910,7 +910,7 @@ sn9c102_store_reg(struct class_device* c
- DBG(2, "Moved SN9C10X register index to 0x%02X", cam->sysfs.reg);
- DBG(3, "Written bytes: %zd", count);
-
-- up(&sn9c102_sysfs_lock);
-+ mutex_unlock(&sn9c102_sysfs_lock);
-
- return count;
- }
-@@ -922,17 +922,17 @@ static ssize_t sn9c102_show_val(struct c
- ssize_t count;
- int val;
-
-- if (down_interruptible(&sn9c102_sysfs_lock))
-+ if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
- return -ERESTARTSYS;
-
- cam = video_get_drvdata(to_video_device(cd));
- if (!cam) {
-- up(&sn9c102_sysfs_lock);
-+ mutex_unlock(&sn9c102_sysfs_lock);
- return -ENODEV;
- }
-
- if ((val = sn9c102_read_reg(cam, cam->sysfs.reg)) < 0) {
-- up(&sn9c102_sysfs_lock);
-+ mutex_unlock(&sn9c102_sysfs_lock);
- return -EIO;
- }
-
-@@ -940,7 +940,7 @@ static ssize_t sn9c102_show_val(struct c
-
- DBG(3, "Read bytes: %zd", count);
-
-- up(&sn9c102_sysfs_lock);
-+ mutex_unlock(&sn9c102_sysfs_lock);
-
- return count;
- }
-@@ -954,24 +954,24 @@ sn9c102_store_val(struct class_device* c
- ssize_t count;
- int err;
-
-- if (down_interruptible(&sn9c102_sysfs_lock))
-+ if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
- return -ERESTARTSYS;
-
- cam = video_get_drvdata(to_video_device(cd));
- if (!cam) {
-- up(&sn9c102_sysfs_lock);
-+ mutex_unlock(&sn9c102_sysfs_lock);
- return -ENODEV;
- }
-
- value = sn9c102_strtou8(buf, len, &count);
- if (!count) {
-- up(&sn9c102_sysfs_lock);
-+ mutex_unlock(&sn9c102_sysfs_lock);
- return -EINVAL;
- }
-
- err = sn9c102_write_reg(cam, value, cam->sysfs.reg);
- if (err) {
-- up(&sn9c102_sysfs_lock);
-+ mutex_unlock(&sn9c102_sysfs_lock);
- return -EIO;
- }
-
-@@ -979,7 +979,7 @@ sn9c102_store_val(struct class_device* c
- cam->sysfs.reg, value);
- DBG(3, "Written bytes: %zd", count);
-
-- up(&sn9c102_sysfs_lock);
-+ mutex_unlock(&sn9c102_sysfs_lock);
-
- return count;
- }
-@@ -990,12 +990,12 @@ static ssize_t sn9c102_show_i2c_reg(stru
- struct sn9c102_device* cam;
- ssize_t count;
-
-- if (down_interruptible(&sn9c102_sysfs_lock))
-+ if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
- return -ERESTARTSYS;
-
- cam = video_get_drvdata(to_video_device(cd));
- if (!cam) {
-- up(&sn9c102_sysfs_lock);
-+ mutex_unlock(&sn9c102_sysfs_lock);
- return -ENODEV;
- }
-
-@@ -1003,7 +1003,7 @@ static ssize_t sn9c102_show_i2c_reg(stru
-
- DBG(3, "Read bytes: %zd", count);
-
-- up(&sn9c102_sysfs_lock);
-+ mutex_unlock(&sn9c102_sysfs_lock);
-
- return count;
- }
-@@ -1016,18 +1016,18 @@ sn9c102_store_i2c_reg(struct class_devic
- u8 index;
- ssize_t count;
-
-- if (down_interruptible(&sn9c102_sysfs_lock))
-+ if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
- return -ERESTARTSYS;
-
- cam = video_get_drvdata(to_video_device(cd));
- if (!cam) {
-- up(&sn9c102_sysfs_lock);
-+ mutex_unlock(&sn9c102_sysfs_lock);
- return -ENODEV;
- }
-
- index = sn9c102_strtou8(buf, len, &count);
- if (!count) {
-- up(&sn9c102_sysfs_lock);
-+ mutex_unlock(&sn9c102_sysfs_lock);
- return -EINVAL;
- }
-
-@@ -1036,7 +1036,7 @@ sn9c102_store_i2c_reg(struct class_devic
- DBG(2, "Moved sensor register index to 0x%02X", cam->sysfs.i2c_reg);
- DBG(3, "Written bytes: %zd", count);
-
-- up(&sn9c102_sysfs_lock);
-+ mutex_unlock(&sn9c102_sysfs_lock);
-
- return count;
- }
-@@ -1048,22 +1048,22 @@ static ssize_t sn9c102_show_i2c_val(stru
- ssize_t count;
- int val;
-
-- if (down_interruptible(&sn9c102_sysfs_lock))
-+ if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
- return -ERESTARTSYS;
-
- cam = video_get_drvdata(to_video_device(cd));
- if (!cam) {
-- up(&sn9c102_sysfs_lock);
-+ mutex_unlock(&sn9c102_sysfs_lock);
- return -ENODEV;
- }
-
- if (!(cam->sensor->sysfs_ops & SN9C102_I2C_READ)) {
-- up(&sn9c102_sysfs_lock);
-+ mutex_unlock(&sn9c102_sysfs_lock);
- return -ENOSYS;
- }
-
- if ((val = sn9c102_i2c_read(cam, cam->sysfs.i2c_reg)) < 0) {
-- up(&sn9c102_sysfs_lock);
-+ mutex_unlock(&sn9c102_sysfs_lock);
- return -EIO;
- }
-
-@@ -1071,7 +1071,7 @@ static ssize_t sn9c102_show_i2c_val(stru
-
- DBG(3, "Read bytes: %zd", count);
-
-- up(&sn9c102_sysfs_lock);
-+ mutex_unlock(&sn9c102_sysfs_lock);
-
- return count;
- }
-@@ -1085,29 +1085,29 @@ sn9c102_store_i2c_val(struct class_devic
- ssize_t count;
- int err;
-
-- if (down_interruptible(&sn9c102_sysfs_lock))
-+ if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
- return -ERESTARTSYS;
-
- cam = video_get_drvdata(to_video_device(cd));
- if (!cam) {
-- up(&sn9c102_sysfs_lock);
-+ mutex_unlock(&sn9c102_sysfs_lock);
- return -ENODEV;
- }
-
- if (!(cam->sensor->sysfs_ops & SN9C102_I2C_WRITE)) {
-- up(&sn9c102_sysfs_lock);
-+ mutex_unlock(&sn9c102_sysfs_lock);
- return -ENOSYS;
- }
-
- value = sn9c102_strtou8(buf, len, &count);
- if (!count) {
-- up(&sn9c102_sysfs_lock);
-+ mutex_unlock(&sn9c102_sysfs_lock);
- return -EINVAL;
- }
-
- err = sn9c102_i2c_write(cam, cam->sysfs.i2c_reg, value);
- if (err) {
-- up(&sn9c102_sysfs_lock);
-+ mutex_unlock(&sn9c102_sysfs_lock);
- return -EIO;
- }
-
-@@ -1115,7 +1115,7 @@ sn9c102_store_i2c_val(struct class_devic
- cam->sysfs.i2c_reg, value);
- DBG(3, "Written bytes: %zd", count);
-
-- up(&sn9c102_sysfs_lock);
-+ mutex_unlock(&sn9c102_sysfs_lock);
-
- return count;
- }
-@@ -1130,18 +1130,18 @@ sn9c102_store_green(struct class_device*
- u8 value;
- ssize_t count;
-
-- if (down_interruptible(&sn9c102_sysfs_lock))
-+ if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
- return -ERESTARTSYS;
-
- cam = video_get_drvdata(to_video_device(cd));
- if (!cam) {
-- up(&sn9c102_sysfs_lock);
-+ mutex_unlock(&sn9c102_sysfs_lock);
- return -ENODEV;
- }
-
- bridge = cam->bridge;
-
-- up(&sn9c102_sysfs_lock);
-+ mutex_unlock(&sn9c102_sysfs_lock);
-
- value = sn9c102_strtou8(buf, len, &count);
- if (!count)
-@@ -1404,7 +1404,7 @@ static int sn9c102_init(struct sn9c102_d
- }
-
- 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);
-@@ -1422,13 +1422,13 @@ static int sn9c102_init(struct sn9c102_d
-
- static void sn9c102_release_resources(struct sn9c102_device* cam)
- {
-- down(&sn9c102_sysfs_lock);
-+ mutex_lock(&sn9c102_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(&sn9c102_sysfs_lock);
-+ mutex_unlock(&sn9c102_sysfs_lock);
-
- kfree(cam->control_buffer);
- }
-@@ -1449,7 +1449,7 @@ static int sn9c102_open(struct inode* in
-
- cam = video_get_drvdata(video_devdata(filp));
-
-- if (down_interruptible(&cam->dev_sem)) {
-+ if (mutex_lock_interruptible(&cam->dev_mutex)) {
- up_read(&sn9c102_disconnect);
- return -ERESTARTSYS;
- }
-@@ -1461,7 +1461,7 @@ static int sn9c102_open(struct inode* in
- 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);
-@@ -1473,7 +1473,7 @@ static int sn9c102_open(struct inode* in
- up_read(&sn9c102_disconnect);
- return -ENODEV;
- }
-- down(&cam->dev_sem);
-+ mutex_lock(&cam->dev_mutex);
- }
-
-
-@@ -1501,7 +1501,7 @@ static int sn9c102_open(struct inode* in
- DBG(3, "Video device /dev/video%d is open", cam->v4ldev->minor);
-
- out:
-- up(&cam->dev_sem);
-+ mutex_unlock(&cam->dev_mutex);
- up_read(&sn9c102_disconnect);
- return err;
- }
-@@ -1511,7 +1511,7 @@ static int sn9c102_release(struct inode*
- {
- struct sn9c102_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 */
-
- sn9c102_stop_transfer(cam);
-
-@@ -1519,7 +1519,7 @@ static int sn9c102_release(struct inode*
-
- if (cam->state & DEV_DISCONNECTED) {
- sn9c102_release_resources(cam);
-- up(&cam->dev_sem);
-+ mutex_unlock(&cam->dev_mutex);
- kfree(cam);
- return 0;
- }
-@@ -1529,7 +1529,7 @@ static int sn9c102_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;
- }
-@@ -1543,33 +1543,33 @@ sn9c102_read(struct file* filp, char __u
- unsigned long lock_flags;
- 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;
- }
-
- if (cam->io == IO_NONE) {
- if (!sn9c102_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;
-@@ -1583,13 +1583,13 @@ sn9c102_read(struct file* filp, char __u
- }
-
- 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
-@@ -1598,15 +1598,15 @@ sn9c102_read(struct file* filp, char __u
- (cam->state & DEV_DISCONNECTED) ||
- (cam->state & DEV_MISCONFIGURED) );
- if (err) {
-- up(&cam->fileop_sem);
-+ mutex_unlock(&cam->fileop_mutex);
- return err;
- }
- 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);
-+ mutex_unlock(&cam->fileop_mutex);
- return -EIO;
- }
- }
-@@ -1634,7 +1634,7 @@ exit:
- PDBGG("Frame #%lu, bytes read: %zu",
- (unsigned long)f->buf.index, count);
-
-- up(&cam->fileop_sem);
-+ mutex_unlock(&cam->fileop_mutex);
-
- return count;
- }
-@@ -1647,7 +1647,7 @@ static unsigned int sn9c102_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) {
-@@ -1685,12 +1685,12 @@ static unsigned int sn9c102_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;
- }
-
-@@ -1724,25 +1724,25 @@ static int sn9c102_mmap(struct file* fil
- 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;
- }
-
-@@ -1751,7 +1751,7 @@ static int sn9c102_mmap(struct file* fil
- break;
- }
- if (i == cam->nbuffers) {
-- up(&cam->fileop_sem);
-+ mutex_unlock(&cam->fileop_mutex);
- return -EINVAL;
- }
-
-@@ -1761,7 +1761,7 @@ static int sn9c102_mmap(struct file* fil
- 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;
-@@ -1774,7 +1774,7 @@ static int sn9c102_mmap(struct file* fil
-
- sn9c102_vm_open(vma);
-
-- up(&cam->fileop_sem);
-+ mutex_unlock(&cam->fileop_mutex);
-
- return 0;
- }
-@@ -2655,19 +2655,19 @@ static int sn9c102_ioctl(struct inode* i
- struct sn9c102_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;
- }
-
-@@ -2675,7 +2675,7 @@ static int sn9c102_ioctl(struct inode* i
-
- err = sn9c102_ioctl_v4l2(inode, filp, cmd, (void __user *)arg);
-
-- up(&cam->fileop_sem);
-+ mutex_unlock(&cam->fileop_mutex);
-
- return err;
- }
-@@ -2722,7 +2722,7 @@ sn9c102_usb_probe(struct usb_interface*
- goto fail;
- }
-
-- init_MUTEX(&cam->dev_sem);
-+ mutex_init(&cam->dev_mutex);
-
- r = sn9c102_read_reg(cam, 0x00);
- if (r < 0 || r != 0x10) {
-@@ -2776,7 +2776,7 @@ sn9c102_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]);
-@@ -2786,7 +2786,7 @@ sn9c102_usb_probe(struct usb_interface*
- DBG(1, "Free /dev/videoX node not found");
- video_nr[dev_nr] = -1;
- dev_nr = (dev_nr < SN9C102_MAX_DEVICES-1) ? dev_nr+1 : 0;
-- up(&cam->dev_sem);
-+ mutex_unlock(&cam->dev_mutex);
- goto fail;
- }
-
-@@ -2803,7 +2803,7 @@ sn9c102_usb_probe(struct usb_interface*
-
- usb_set_intfdata(intf, cam);
-
-- up(&cam->dev_sem);
-+ mutex_unlock(&cam->dev_mutex);
-
- return 0;
-
-@@ -2827,7 +2827,7 @@ static void sn9c102_usb_disconnect(struc
-
- down_write(&sn9c102_disconnect);
-
-- down(&cam->dev_sem);
-+ mutex_lock(&cam->dev_mutex);
-
- DBG(2, "Disconnecting %s...", cam->v4ldev->name);
-
-@@ -2847,7 +2847,7 @@ static void sn9c102_usb_disconnect(struc
- sn9c102_release_resources(cam);
- }
-
-- up(&cam->dev_sem);
-+ mutex_unlock(&cam->dev_mutex);
-
- if (!cam->users)
- kfree(cam);
---- gregkh-2.6.orig/drivers/usb/media/stv680.c
-+++ gregkh-2.6/drivers/usb/media/stv680.c
-@@ -67,6 +67,7 @@
- #include <linux/errno.h>
- #include <linux/videodev.h>
- #include <linux/usb.h>
-+#include <linux/mutex.h>
-
- #include "stv680.h"
-
-@@ -1258,22 +1259,22 @@ static int stv680_mmap (struct file *fil
- unsigned long size = vma->vm_end-vma->vm_start;
- unsigned long page, pos;
-
-- down (&stv680->lock);
-+ mutex_lock(&stv680->lock);
-
- if (stv680->udev == NULL) {
-- up (&stv680->lock);
-+ mutex_unlock(&stv680->lock);
- return -EIO;
- }
- if (size > (((STV680_NUMFRAMES * stv680->maxframesize) + PAGE_SIZE - 1)
- & ~(PAGE_SIZE - 1))) {
-- up (&stv680->lock);
-+ mutex_unlock(&stv680->lock);
- return -EINVAL;
- }
- pos = (unsigned long) stv680->fbuf;
- while (size > 0) {
- page = vmalloc_to_pfn((void *)pos);
- if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) {
-- up (&stv680->lock);
-+ mutex_unlock(&stv680->lock);
- return -EAGAIN;
- }
- start += PAGE_SIZE;
-@@ -1283,7 +1284,7 @@ static int stv680_mmap (struct file *fil
- else
- size = 0;
- }
-- up (&stv680->lock);
-+ mutex_unlock(&stv680->lock);
-
- return 0;
- }
-@@ -1409,7 +1410,7 @@ static int stv680_probe (struct usb_inte
-
- memcpy (stv680->vdev->name, stv680->camera_name, strlen (stv680->camera_name));
- init_waitqueue_head (&stv680->wq);
-- init_MUTEX (&stv680->lock);
-+ mutex_init (&stv680->lock);
- wmb ();
-
- if (video_register_device (stv680->vdev, VFL_TYPE_GRABBER, video_nr) == -1) {
---- gregkh-2.6.orig/drivers/usb/media/stv680.h
-+++ gregkh-2.6/drivers/usb/media/stv680.h
-@@ -118,7 +118,7 @@ struct usb_stv {
- int origGain;
- int origMode; /* original camera mode */
-
-- struct semaphore lock; /* to lock the structure */
-+ struct mutex lock; /* to lock the structure */
- int user; /* user count for exclusive use */
- int removed; /* device disconnected */
- int streaming; /* Are we streaming video? */
---- gregkh-2.6.orig/drivers/usb/media/usbvideo.c
-+++ gregkh-2.6/drivers/usb/media/usbvideo.c
-@@ -714,7 +714,7 @@ int usbvideo_register(
- cams->md_module = md;
- if (cams->md_module == NULL)
- warn("%s: module == NULL!", __FUNCTION__);
-- init_MUTEX(&cams->lock); /* to 1 == available */
-+ mutex_init(&cams->lock); /* to 1 == available */
-
- for (i = 0; i < num_cams; i++) {
- struct uvd *up = &cams->cam[i];
-@@ -862,7 +862,7 @@ static void usbvideo_Disconnect(struct u
- if (uvd->debug > 0)
- info("%s(%p.)", __FUNCTION__, intf);
-
-- down(&uvd->lock);
-+ mutex_lock(&uvd->lock);
- uvd->remove_pending = 1; /* Now all ISO data will be ignored */
-
- /* At this time we ask to cancel outstanding URBs */
-@@ -882,7 +882,7 @@ static void usbvideo_Disconnect(struct u
- info("%s: In use, disconnect pending.", __FUNCTION__);
- else
- usbvideo_CameraRelease(uvd);
-- up(&uvd->lock);
-+ mutex_unlock(&uvd->lock);
- info("USB camera disconnected.");
-
- usbvideo_ClientDecModCount(uvd);
-@@ -929,19 +929,19 @@ static int usbvideo_find_struct(struct u
- err("No usbvideo handle?");
- return -1;
- }
-- down(&cams->lock);
-+ mutex_lock(&cams->lock);
- for (u = 0; u < cams->num_cameras; u++) {
- struct uvd *uvd = &cams->cam[u];
- if (!uvd->uvd_used) /* This one is free */
- {
- uvd->uvd_used = 1; /* In use now */
-- init_MUTEX(&uvd->lock); /* to 1 == available */
-+ mutex_init(&uvd->lock); /* to 1 == available */
- uvd->dev = NULL;
- rv = u;
- break;
- }
- }
-- up(&cams->lock);
-+ mutex_unlock(&cams->lock);
- return rv;
- }
-
-@@ -983,7 +983,7 @@ struct uvd *usbvideo_AllocateDevice(stru
- /* Not relying upon caller we increase module counter ourselves */
- usbvideo_ClientIncModCount(uvd);
-
-- down(&uvd->lock);
-+ mutex_lock(&uvd->lock);
- for (i=0; i < USBVIDEO_NUMSBUF; i++) {
- uvd->sbuf[i].urb = usb_alloc_urb(FRAMES_PER_DESC, GFP_KERNEL);
- if (uvd->sbuf[i].urb == NULL) {
-@@ -1006,7 +1006,7 @@ struct uvd *usbvideo_AllocateDevice(stru
- * return control to the client's probe function right now.
- */
- allocate_done:
-- up (&uvd->lock);
-+ mutex_unlock(&uvd->lock);
- usbvideo_ClientDecModCount(uvd);
- return uvd;
- }
-@@ -1120,7 +1120,7 @@ static int usbvideo_v4l_open(struct inod
- info("%s($%p)", __FUNCTION__, dev);
-
- usbvideo_ClientIncModCount(uvd);
-- down(&uvd->lock);
-+ mutex_lock(&uvd->lock);
-
- if (uvd->user) {
- err("%s: Someone tried to open an already opened device!", __FUNCTION__);
-@@ -1201,7 +1201,7 @@ static int usbvideo_v4l_open(struct inod
- }
- }
- }
-- up(&uvd->lock);
-+ mutex_unlock(&uvd->lock);
- if (errCode != 0)
- usbvideo_ClientDecModCount(uvd);
- if (uvd->debug > 0)
-@@ -1230,7 +1230,7 @@ static int usbvideo_v4l_close(struct ino
- if (uvd->debug > 1)
- info("%s($%p)", __FUNCTION__, dev);
-
-- down(&uvd->lock);
-+ mutex_lock(&uvd->lock);
- GET_CALLBACK(uvd, stopDataPump)(uvd);
- usbvideo_rvfree(uvd->fbuf, uvd->fbuf_size);
- uvd->fbuf = NULL;
-@@ -1251,7 +1251,7 @@ static int usbvideo_v4l_close(struct ino
- info("usbvideo_v4l_close: Final disconnect.");
- usbvideo_CameraRelease(uvd);
- }
-- up(&uvd->lock);
-+ mutex_unlock(&uvd->lock);
- usbvideo_ClientDecModCount(uvd);
-
- if (uvd->debug > 1)
-@@ -1511,7 +1511,7 @@ static ssize_t usbvideo_v4l_read(struct
- if (uvd->debug >= 1)
- info("%s: %Zd. bytes, noblock=%d.", __FUNCTION__, count, noblock);
-
-- down(&uvd->lock);
-+ mutex_lock(&uvd->lock);
-
- /* See if a frame is completed, then use it. */
- for(i = 0; i < USBVIDEO_NUMFRAMES; i++) {
-@@ -1643,7 +1643,7 @@ static ssize_t usbvideo_v4l_read(struct
- }
- }
- read_done:
-- up(&uvd->lock);
-+ mutex_unlock(&uvd->lock);
- return count;
- }
-
---- gregkh-2.6.orig/drivers/usb/media/usbvideo.h
-+++ gregkh-2.6/drivers/usb/media/usbvideo.h
-@@ -19,6 +19,7 @@
- #include <linux/config.h>
- #include <linux/videodev.h>
- #include <linux/usb.h>
-+#include <linux/mutex.h>
-
- /* Most helpful debugging aid */
- #define assert(expr) ((void) ((expr) ? 0 : (err("assert failed at line %d",__LINE__))))
-@@ -213,7 +214,7 @@ struct uvd {
- unsigned long flags; /* FLAGS_USBVIDEO_xxx */
- unsigned long paletteBits; /* Which palettes we accept? */
- unsigned short defaultPalette; /* What palette to use for read() */
-- struct semaphore lock;
-+ struct mutex lock;
- int user; /* user count for exclusive use */
-
- videosize_t videosize; /* Current setting */
-@@ -272,7 +273,7 @@ struct usbvideo {
- int num_cameras; /* As allocated */
- struct usb_driver usbdrv; /* Interface to the USB stack */
- char drvName[80]; /* Driver name */
-- struct semaphore lock; /* Mutex protecting camera structures */
-+ struct mutex lock; /* Mutex protecting camera structures */
- struct usbvideo_cb cb; /* Table of callbacks (virtual methods) */
- struct video_device vdt; /* Video device template */
- struct uvd *cam; /* Array of camera structures */
---- gregkh-2.6.orig/drivers/usb/media/vicam.c
-+++ gregkh-2.6/drivers/usb/media/vicam.c
-@@ -42,6 +42,7 @@
- #include <linux/vmalloc.h>
- #include <linux/slab.h>
- #include <linux/proc_fs.h>
-+#include <linux/mutex.h>
- #include "usbvideo.h"
-
- // #define VICAM_DEBUG
-@@ -407,7 +408,7 @@ struct vicam_camera {
- struct usb_device *udev; // usb device
-
- /* guard against simultaneous accesses to the camera */
-- struct semaphore cam_lock;
-+ struct mutex cam_lock;
-
- int is_initialized;
- u8 open_count;
-@@ -461,12 +462,12 @@ static int send_control_msg(struct vicam
- u16 size)
- {
- int status = -ENODEV;
-- down(&cam->cam_lock);
-+ mutex_lock(&cam->cam_lock);
- if (cam->udev) {
- status = __send_control_msg(cam, request, value,
- index, cp, size);
- }
-- up(&cam->cam_lock);
-+ mutex_unlock(&cam->cam_lock);
- return status;
- }
- static int
-@@ -831,13 +832,13 @@ vicam_close(struct inode *inode, struct
- rvfree(cam->framebuf, VICAM_MAX_FRAME_SIZE * VICAM_FRAMES);
- kfree(cam->cntrlbuf);
-
-- down(&cam->cam_lock);
-+ mutex_lock(&cam->cam_lock);
-
- cam->open_count--;
- open_count = cam->open_count;
- udev = cam->udev;
-
-- up(&cam->cam_lock);
-+ mutex_unlock(&cam->cam_lock);
-
- if (!open_count && !udev) {
- kfree(cam);
-@@ -960,7 +961,7 @@ read_frame(struct vicam_camera *cam, int
- request[8] = 0;
- // bytes 9-15 do not seem to affect exposure or image quality
-
-- down(&cam->cam_lock);
-+ mutex_lock(&cam->cam_lock);
-
- if (!cam->udev) {
- goto done;
-@@ -985,7 +986,7 @@ read_frame(struct vicam_camera *cam, int
- }
-
- done:
-- up(&cam->cam_lock);
-+ mutex_unlock(&cam->cam_lock);
- }
-
- static ssize_t
-@@ -1309,7 +1310,7 @@ vicam_probe( struct usb_interface *intf,
-
- cam->shutter_speed = 15;
-
-- init_MUTEX(&cam->cam_lock);
-+ mutex_init(&cam->cam_lock);
-
- memcpy(&cam->vdev, &vicam_template,
- sizeof (vicam_template));
-@@ -1351,7 +1352,7 @@ vicam_disconnect(struct usb_interface *i
-
- /* stop the camera from being used */
-
-- down(&cam->cam_lock);
-+ mutex_lock(&cam->cam_lock);
-
- /* mark the camera as gone */
-
-@@ -1368,7 +1369,7 @@ vicam_disconnect(struct usb_interface *i
-
- open_count = cam->open_count;
-
-- up(&cam->cam_lock);
-+ mutex_unlock(&cam->cam_lock);
-
- if (!open_count) {
- kfree(cam);
---- gregkh-2.6.orig/drivers/usb/media/w9968cf.c
-+++ gregkh-2.6/drivers/usb/media/w9968cf.c
-@@ -47,6 +47,13 @@
- #include "w9968cf.h"
- #include "w9968cf_decoder.h"
-
-+static struct w9968cf_vpp_t* w9968cf_vpp;
-+static DECLARE_WAIT_QUEUE_HEAD(w9968cf_vppmod_wait);
-+
-+static LIST_HEAD(w9968cf_dev_list); /* head of V4L registered cameras list */
-+static DEFINE_MUTEX(w9968cf_devlist_mutex); /* semaphore for list traversal */
-+
-+static DECLARE_RWSEM(w9968cf_disconnect); /* prevent races with open() */
-
-
- /****************************************************************************
-@@ -2418,7 +2425,7 @@ w9968cf_configure_camera(struct w9968cf_
- enum w9968cf_model_id mod_id,
- const unsigned short dev_nr)
- {
-- init_MUTEX(&cam->fileop_sem);
-+ mutex_init(&cam->fileop_mutex);
- init_waitqueue_head(&cam->open);
- spin_lock_init(&cam->urb_lock);
- spin_lock_init(&cam->flist_lock);
-@@ -2646,7 +2653,7 @@ static void w9968cf_adjust_configuration
- --------------------------------------------------------------------------*/
- static void w9968cf_release_resources(struct w9968cf_device* cam)
- {
-- down(&w9968cf_devlist_sem);
-+ mutex_lock(&w9968cf_devlist_mutex);
-
- DBG(2, "V4L device deregistered: /dev/video%d", cam->v4ldev->minor)
-
-@@ -2657,7 +2664,7 @@ static void w9968cf_release_resources(st
- kfree(cam->control_buffer);
- kfree(cam->data_buffer);
-
-- up(&w9968cf_devlist_sem);
-+ mutex_unlock(&w9968cf_devlist_mutex);
- }
-
-
-@@ -2677,14 +2684,14 @@ static int w9968cf_open(struct inode* in
-
- cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp));
-
-- down(&cam->dev_sem);
-+ mutex_lock(&cam->dev_mutex);
-
- if (cam->sensor == CC_UNKNOWN) {
- DBG(2, "No supported image sensor has been detected by the "
- "'ovcamchip' module for the %s (/dev/video%d). Make "
- "sure it is loaded *before* (re)connecting the camera.",
- symbolic(camlist, cam->id), cam->v4ldev->minor)
-- up(&cam->dev_sem);
-+ mutex_unlock(&cam->dev_mutex);
- up_read(&w9968cf_disconnect);
- return -ENODEV;
- }
-@@ -2693,11 +2700,11 @@ static int w9968cf_open(struct inode* in
- DBG(2, "%s (/dev/video%d) has been already occupied by '%s'",
- symbolic(camlist, cam->id),cam->v4ldev->minor,cam->command)
- if ((filp->f_flags & O_NONBLOCK)||(filp->f_flags & O_NDELAY)) {
-- up(&cam->dev_sem);
-+ mutex_unlock(&cam->dev_mutex);
- up_read(&w9968cf_disconnect);
- return -EWOULDBLOCK;
- }
-- up(&cam->dev_sem);
-+ mutex_unlock(&cam->dev_mutex);
- err = wait_event_interruptible_exclusive(cam->open,
- cam->disconnected ||
- !cam->users);
-@@ -2709,7 +2716,7 @@ static int w9968cf_open(struct inode* in
- up_read(&w9968cf_disconnect);
- return -ENODEV;
- }
-- down(&cam->dev_sem);
-+ mutex_lock(&cam->dev_mutex);
- }
-
- DBG(5, "Opening '%s', /dev/video%d ...",
-@@ -2738,7 +2745,7 @@ static int w9968cf_open(struct inode* in
-
- DBG(5, "Video device is open")
-
-- up(&cam->dev_sem);
-+ mutex_unlock(&cam->dev_mutex);
- up_read(&w9968cf_disconnect);
-
- return 0;
-@@ -2746,7 +2753,7 @@ static int w9968cf_open(struct inode* in
- deallocate_memory:
- w9968cf_deallocate_memory(cam);
- DBG(2, "Failed to open the video device")
-- up(&cam->dev_sem);
-+ mutex_unlock(&cam->dev_mutex);
- up_read(&w9968cf_disconnect);
- return err;
- }
-@@ -2758,13 +2765,13 @@ static int w9968cf_release(struct inode*
-
- cam = (struct w9968cf_device*)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 */
-
- w9968cf_stop_transfer(cam);
-
- if (cam->disconnected) {
- w9968cf_release_resources(cam);
-- up(&cam->dev_sem);
-+ mutex_unlock(&cam->dev_mutex);
- kfree(cam);
- return 0;
- }
-@@ -2774,7 +2781,7 @@ static int w9968cf_release(struct inode*
- wake_up_interruptible_nr(&cam->open, 1);
-
- DBG(5, "Video device closed")
-- up(&cam->dev_sem);
-+ mutex_unlock(&cam->dev_mutex);
- return 0;
- }
-
-@@ -2791,18 +2798,18 @@ w9968cf_read(struct file* filp, char __u
- if (filp->f_flags & O_NONBLOCK)
- return -EWOULDBLOCK;
-
-- if (down_interruptible(&cam->fileop_sem))
-+ if (mutex_lock_interruptible(&cam->fileop_mutex))
- return -ERESTARTSYS;
-
- if (cam->disconnected) {
- DBG(2, "Device not present")
-- up(&cam->fileop_sem);
-+ mutex_unlock(&cam->fileop_mutex);
- return -ENODEV;
- }
-
- if (cam->misconfigured) {
- DBG(2, "The camera is misconfigured. Close and open it again.")
-- up(&cam->fileop_sem);
-+ mutex_unlock(&cam->fileop_mutex);
- return -EIO;
- }
-
-@@ -2817,11 +2824,11 @@ w9968cf_read(struct file* filp, char __u
- cam->frame[1].status == F_READY ||
- cam->disconnected);
- if (err) {
-- up(&cam->fileop_sem);
-+ mutex_unlock(&cam->fileop_mutex);
- return err;
- }
- if (cam->disconnected) {
-- up(&cam->fileop_sem);
-+ mutex_unlock(&cam->fileop_mutex);
- return -ENODEV;
- }
-
-@@ -2835,7 +2842,7 @@ w9968cf_read(struct file* filp, char __u
-
- if (copy_to_user(buf, fr->buffer, count)) {
- fr->status = F_UNUSED;
-- up(&cam->fileop_sem);
-+ mutex_unlock(&cam->fileop_mutex);
- return -EFAULT;
- }
- *f_pos += count;
-@@ -2844,7 +2851,7 @@ w9968cf_read(struct file* filp, char __u
-
- DBG(5, "%zu bytes read", count)
-
-- up(&cam->fileop_sem);
-+ mutex_unlock(&cam->fileop_mutex);
- return count;
- }
-
-@@ -2898,24 +2905,24 @@ w9968cf_ioctl(struct inode* inode, struc
-
- cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp));
-
-- if (down_interruptible(&cam->fileop_sem))
-+ if (mutex_lock_interruptible(&cam->fileop_mutex))
- return -ERESTARTSYS;
-
- if (cam->disconnected) {
- DBG(2, "Device not present")
-- up(&cam->fileop_sem);
-+ mutex_unlock(&cam->fileop_mutex);
- return -ENODEV;
- }
-
- if (cam->misconfigured) {
- DBG(2, "The camera is misconfigured. Close and open it again.")
-- up(&cam->fileop_sem);
-+ mutex_unlock(&cam->fileop_mutex);
- return -EIO;
- }
-
- err = w9968cf_v4l_ioctl(inode, filp, cmd, (void __user *)arg);
-
-- up(&cam->fileop_sem);
-+ mutex_unlock(&cam->fileop_mutex);
- return err;
- }
-
-@@ -3502,8 +3509,8 @@ w9968cf_usb_probe(struct usb_interface*
- if (!cam)
- return -ENOMEM;
-
-- init_MUTEX(&cam->dev_sem);
-- down(&cam->dev_sem);
-+ mutex_init(&cam->dev_mutex);
-+ mutex_lock(&cam->dev_mutex);
-
- cam->usbdev = udev;
- /* NOTE: a local copy is used to avoid possible race conditions */
-@@ -3515,10 +3522,10 @@ w9968cf_usb_probe(struct usb_interface*
- simcams = W9968CF_SIMCAMS;
-
- /* How many cameras are connected ? */
-- down(&w9968cf_devlist_sem);
-+ mutex_lock(&w9968cf_devlist_mutex);
- list_for_each(ptr, &w9968cf_dev_list)
- sc++;
-- up(&w9968cf_devlist_sem);
-+ mutex_unlock(&w9968cf_devlist_mutex);
-
- if (sc >= simcams) {
- DBG(2, "Device rejected: too many connected cameras "
-@@ -3578,9 +3585,9 @@ w9968cf_usb_probe(struct usb_interface*
- w9968cf_configure_camera(cam, udev, mod_id, dev_nr);
-
- /* Add a new entry into the list of V4L registered devices */
-- down(&w9968cf_devlist_sem);
-+ mutex_lock(&w9968cf_devlist_mutex);
- list_add(&cam->v4llist, &w9968cf_dev_list);
-- up(&w9968cf_devlist_sem);
-+ mutex_unlock(&w9968cf_devlist_mutex);
- dev_nr = (dev_nr < W9968CF_MAX_DEVICES-1) ? dev_nr+1 : 0;
-
- w9968cf_turn_on_led(cam);
-@@ -3588,7 +3595,7 @@ w9968cf_usb_probe(struct usb_interface*
- w9968cf_i2c_init(cam);
-
- usb_set_intfdata(intf, cam);
-- up(&cam->dev_sem);
-+ mutex_unlock(&cam->dev_mutex);
- return 0;
-
- fail: /* Free unused memory */
-@@ -3596,7 +3603,7 @@ fail: /* Free unused memory */
- kfree(cam->data_buffer);
- if (cam->v4ldev)
- video_device_release(cam->v4ldev);
-- up(&cam->dev_sem);
-+ mutex_unlock(&cam->dev_mutex);
- kfree(cam);
- return err;
- }
-@@ -3611,7 +3618,7 @@ static void w9968cf_usb_disconnect(struc
-
- if (cam) {
- /* Prevent concurrent accesses to data */
-- down(&cam->dev_sem);
-+ mutex_lock(&cam->dev_mutex);
-
- cam->disconnected = 1;
-
-@@ -3630,7 +3637,7 @@ static void w9968cf_usb_disconnect(struc
- } else
- w9968cf_release_resources(cam);
-
-- up(&cam->dev_sem);
-+ mutex_unlock(&cam->dev_mutex);
-
- if (!cam->users)
- kfree(cam);
---- gregkh-2.6.orig/drivers/usb/media/w9968cf.h
-+++ gregkh-2.6/drivers/usb/media/w9968cf.h
-@@ -32,7 +32,7 @@
- #include <linux/param.h>
- #include <linux/types.h>
- #include <linux/rwsem.h>
--#include <asm/semaphore.h>
-+#include <linux/mutex.h>
-
- #include <media/ovcamchip.h>
-
-@@ -194,14 +194,6 @@ enum w9968cf_vpp_flag {
- VPP_UYVY_TO_RGBX = 0x08,
- };
-
--static struct w9968cf_vpp_t* w9968cf_vpp;
--static DECLARE_WAIT_QUEUE_HEAD(w9968cf_vppmod_wait);
--
--static LIST_HEAD(w9968cf_dev_list); /* head of V4L registered cameras list */
--static DECLARE_MUTEX(w9968cf_devlist_sem); /* semaphore for list traversal */
--
--static DECLARE_RWSEM(w9968cf_disconnect); /* prevent races with open() */
--
- /* Main device driver structure */
- struct w9968cf_device {
- struct device dev; /* device structure */
-@@ -277,8 +269,8 @@ struct w9968cf_device {
- struct i2c_client* sensor_client;
-
- /* Locks */
-- struct semaphore dev_sem, /* for probe, disconnect,open and close */
-- fileop_sem; /* for read and ioctl */
-+ struct mutex dev_mutex, /* for probe, disconnect,open and close */
-+ fileop_mutex; /* for read and ioctl */
- spinlock_t urb_lock, /* for submit_urb() and unlink_urb() */
- flist_lock; /* for requested frame list accesses */
- wait_queue_head_t open, wait_queue;
---- gregkh-2.6.orig/drivers/usb/misc/idmouse.c
-+++ gregkh-2.6/drivers/usb/misc/idmouse.c
-@@ -25,6 +25,7 @@
- #include <linux/module.h>
- #include <linux/smp_lock.h>
- #include <linux/completion.h>
-+#include <linux/mutex.h>
- #include <asm/uaccess.h>
- #include <linux/usb.h>
-
-@@ -121,7 +122,7 @@ static struct usb_driver idmouse_driver
- };
-
- /* prevent races between open() and disconnect() */
--static DECLARE_MUTEX(disconnect_sem);
-+static DEFINE_MUTEX(disconnect_mutex);
-
- static int idmouse_create_image(struct usb_idmouse *dev)
- {
-@@ -213,18 +214,18 @@ static int idmouse_open(struct inode *in
- int result = 0;
-
- /* prevent disconnects */
-- down(&disconnect_sem);
-+ mutex_lock(&disconnect_mutex);
-
- /* get the interface from minor number and driver information */
- interface = usb_find_interface (&idmouse_driver, iminor (inode));
- if (!interface) {
-- up(&disconnect_sem);
-+ mutex_unlock(&disconnect_mutex);
- return -ENODEV;
- }
- /* get the device information block from the interface */
- dev = usb_get_intfdata(interface);
- if (!dev) {
-- up(&disconnect_sem);
-+ mutex_unlock(&disconnect_mutex);
- return -ENODEV;
- }
-
-@@ -258,7 +259,7 @@ error:
- up(&dev->sem);
-
- /* unlock the disconnect semaphore */
-- up(&disconnect_sem);
-+ mutex_unlock(&disconnect_mutex);
- return result;
- }
-
-@@ -267,12 +268,12 @@ static int idmouse_release(struct inode
- struct usb_idmouse *dev;
-
- /* prevent a race condition with open() */
-- down(&disconnect_sem);
-+ mutex_lock(&disconnect_mutex);
-
- dev = (struct usb_idmouse *) file->private_data;
-
- if (dev == NULL) {
-- up(&disconnect_sem);
-+ mutex_unlock(&disconnect_mutex);
- return -ENODEV;
- }
-
-@@ -282,7 +283,7 @@ static int idmouse_release(struct inode
- /* are we really open? */
- if (dev->open <= 0) {
- up(&dev->sem);
-- up(&disconnect_sem);
-+ mutex_unlock(&disconnect_mutex);
- return -ENODEV;
- }
-
-@@ -292,12 +293,12 @@ static int idmouse_release(struct inode
- /* the device was unplugged before the file was released */
- up(&dev->sem);
- idmouse_delete(dev);
-- up(&disconnect_sem);
-+ mutex_unlock(&disconnect_mutex);
- return 0;
- }
-
- up(&dev->sem);
-- up(&disconnect_sem);
-+ mutex_unlock(&disconnect_mutex);
- return 0;
- }
-
-@@ -399,7 +400,7 @@ static void idmouse_disconnect(struct us
- struct usb_idmouse *dev;
-
- /* prevent races with open() */
-- down(&disconnect_sem);
-+ mutex_lock(&disconnect_mutex);
-
- /* get device structure */
- dev = usb_get_intfdata(interface);
-@@ -421,7 +422,7 @@ static void idmouse_disconnect(struct us
- if (!dev->open)
- idmouse_delete(dev);
-
-- up(&disconnect_sem);
-+ mutex_unlock(&disconnect_mutex);
-
- info("%s disconnected", DRIVER_DESC);
- }
---- gregkh-2.6.orig/drivers/usb/misc/ldusb.c
-+++ gregkh-2.6/drivers/usb/misc/ldusb.c
-@@ -33,6 +33,7 @@
- #include <linux/init.h>
- #include <linux/slab.h>
- #include <linux/module.h>
-+#include <linux/mutex.h>
-
- #include <asm/uaccess.h>
- #include <linux/input.h>
-@@ -172,7 +173,7 @@ struct ld_usb {
- };
-
- /* prevent races between open() and disconnect() */
--static DECLARE_MUTEX(disconnect_sem);
-+static DEFINE_MUTEX(disconnect_mutex);
-
- static struct usb_driver ld_usb_driver;
-
-@@ -293,7 +294,7 @@ static int ld_usb_open(struct inode *ino
- nonseekable_open(inode, file);
- subminor = iminor(inode);
-
-- down(&disconnect_sem);
-+ mutex_lock(&disconnect_mutex);
-
- interface = usb_find_interface(&ld_usb_driver, subminor);
-
-@@ -355,7 +356,7 @@ unlock_exit:
- up(&dev->sem);
-
- unlock_disconnect_exit:
-- up(&disconnect_sem);
-+ mutex_unlock(&disconnect_mutex);
-
- return retval;
- }
-@@ -740,7 +741,7 @@ static void ld_usb_disconnect(struct usb
- struct ld_usb *dev;
- int minor;
-
-- down(&disconnect_sem);
-+ mutex_lock(&disconnect_mutex);
-
- dev = usb_get_intfdata(intf);
- usb_set_intfdata(intf, NULL);
-@@ -761,7 +762,7 @@ static void ld_usb_disconnect(struct usb
- up(&dev->sem);
- }
-
-- up(&disconnect_sem);
-+ mutex_unlock(&disconnect_mutex);
-
- dev_info(&intf->dev, "LD USB Device #%d now disconnected\n",
- (minor - USB_LD_MINOR_BASE));
---- gregkh-2.6.orig/drivers/usb/misc/legousbtower.c
-+++ gregkh-2.6/drivers/usb/misc/legousbtower.c
-@@ -83,6 +83,7 @@
- #include <linux/module.h>
- #include <linux/smp_lock.h>
- #include <linux/completion.h>
-+#include <linux/mutex.h>
- #include <asm/uaccess.h>
- #include <linux/usb.h>
- #include <linux/poll.h>
-@@ -256,7 +257,7 @@ static void tower_disconnect (struct usb
-
-
- /* prevent races between open() and disconnect */
--static DECLARE_MUTEX (disconnect_sem);
-+static DEFINE_MUTEX (disconnect_mutex);
-
- /* file operations needed when we register this driver */
- static struct file_operations tower_fops = {
-@@ -349,7 +350,7 @@ static int tower_open (struct inode *ino
- nonseekable_open(inode, file);
- subminor = iminor(inode);
-
-- down (&disconnect_sem);
-+ mutex_lock (&disconnect_mutex);
-
- interface = usb_find_interface (&tower_driver, subminor);
-
-@@ -427,7 +428,7 @@ unlock_exit:
- up (&dev->sem);
-
- unlock_disconnect_exit:
-- up (&disconnect_sem);
-+ mutex_unlock (&disconnect_mutex);
-
- dbg(2, "%s: leave, return value %d ", __FUNCTION__, retval);
-
-@@ -1005,7 +1006,7 @@ static void tower_disconnect (struct usb
-
- dbg(2, "%s: enter", __FUNCTION__);
-
-- down (&disconnect_sem);
-+ mutex_lock (&disconnect_mutex);
-
- dev = usb_get_intfdata (interface);
- usb_set_intfdata (interface, NULL);
-@@ -1027,7 +1028,7 @@ static void tower_disconnect (struct usb
- up (&dev->sem);
- }
-
-- up (&disconnect_sem);
-+ mutex_unlock (&disconnect_mutex);
-
- info("LEGO USB Tower #%d now disconnected", (minor - LEGO_USB_TOWER_MINOR_BASE));
-
---- gregkh-2.6.orig/drivers/usb/mon/mon_main.c
-+++ gregkh-2.6/drivers/usb/mon/mon_main.c
-@@ -12,6 +12,7 @@
- #include <linux/debugfs.h>
- #include <linux/smp_lock.h>
- #include <linux/notifier.h>
-+#include <linux/mutex.h>
-
- #include "usb_mon.h"
- #include "../core/hcd.h"
-@@ -23,7 +24,7 @@ static void mon_dissolve(struct mon_bus
- static void mon_bus_drop(struct kref *r);
- static void mon_bus_init(struct dentry *mondir, struct usb_bus *ubus);
-
--DECLARE_MUTEX(mon_lock);
-+DEFINE_MUTEX(mon_lock);
-
- static struct dentry *mon_dir; /* /dbg/usbmon */
- static LIST_HEAD(mon_buses); /* All buses we know: struct mon_bus */
-@@ -196,14 +197,14 @@ static void mon_bus_remove(struct usb_bu
- {
- struct mon_bus *mbus = ubus->mon_bus;
-
-- down(&mon_lock);
-+ mutex_lock(&mon_lock);
- list_del(&mbus->bus_link);
- debugfs_remove(mbus->dent_t);
- debugfs_remove(mbus->dent_s);
-
- mon_dissolve(mbus, ubus);
- kref_put(&mbus->ref, mon_bus_drop);
-- up(&mon_lock);
-+ mutex_unlock(&mon_lock);
- }
-
- static int mon_notify(struct notifier_block *self, unsigned long action,
-@@ -307,9 +308,9 @@ static void mon_bus_init(struct dentry *
- goto err_create_s;
- mbus->dent_s = d;
-
-- down(&mon_lock);
-+ mutex_lock(&mon_lock);
- list_add_tail(&mbus->bus_link, &mon_buses);
-- up(&mon_lock);
-+ mutex_unlock(&mon_lock);
- return;
-
- err_create_s:
-@@ -347,11 +348,11 @@ static int __init mon_init(void)
-
- usb_register_notify(&mon_nb);
-
-- down(&usb_bus_list_lock);
-+ mutex_lock(&usb_bus_list_lock);
- list_for_each_entry (ubus, &usb_bus_list, bus_list) {
- mon_bus_init(mondir, ubus);
- }
-- up(&usb_bus_list_lock);
-+ mutex_unlock(&usb_bus_list_lock);
- return 0;
- }
-
-@@ -363,7 +364,7 @@ static void __exit mon_exit(void)
- usb_unregister_notify(&mon_nb);
- usb_mon_deregister();
-
-- down(&mon_lock);
-+ mutex_lock(&mon_lock);
- while (!list_empty(&mon_buses)) {
- p = mon_buses.next;
- mbus = list_entry(p, struct mon_bus, bus_link);
-@@ -387,7 +388,7 @@ static void __exit mon_exit(void)
- mon_dissolve(mbus, mbus->u_bus);
- kref_put(&mbus->ref, mon_bus_drop);
- }
-- up(&mon_lock);
-+ mutex_unlock(&mon_lock);
-
- debugfs_remove(mon_dir);
- }
---- gregkh-2.6.orig/drivers/usb/mon/mon_text.c
-+++ gregkh-2.6/drivers/usb/mon/mon_text.c
-@@ -8,6 +8,7 @@
- #include <linux/list.h>
- #include <linux/usb.h>
- #include <linux/time.h>
-+#include <linux/mutex.h>
- #include <asm/uaccess.h>
-
- #include "usb_mon.h"
-@@ -54,7 +55,7 @@ struct mon_reader_text {
- wait_queue_head_t wait;
- int printf_size;
- char *printf_buf;
-- struct semaphore printf_lock;
-+ struct mutex printf_lock;
-
- char slab_name[SLAB_NAME_SZ];
- };
-@@ -208,7 +209,7 @@ static int mon_text_open(struct inode *i
- struct mon_reader_text *rp;
- int rc;
-
-- down(&mon_lock);
-+ mutex_lock(&mon_lock);
- mbus = inode->u.generic_ip;
- ubus = mbus->u_bus;
-
-@@ -220,7 +221,7 @@ static int mon_text_open(struct inode *i
- memset(rp, 0, sizeof(struct mon_reader_text));
- INIT_LIST_HEAD(&rp->e_list);
- init_waitqueue_head(&rp->wait);
-- init_MUTEX(&rp->printf_lock);
-+ mutex_init(&rp->printf_lock);
-
- rp->printf_size = PRINTF_DFL;
- rp->printf_buf = kmalloc(rp->printf_size, GFP_KERNEL);
-@@ -247,7 +248,7 @@ static int mon_text_open(struct inode *i
- mon_reader_add(mbus, &rp->r);
-
- file->private_data = rp;
-- up(&mon_lock);
-+ mutex_unlock(&mon_lock);
- return 0;
-
- // err_busy:
-@@ -257,7 +258,7 @@ err_slab:
- err_alloc_pr:
- kfree(rp);
- err_alloc:
-- up(&mon_lock);
-+ mutex_unlock(&mon_lock);
- return rc;
- }
-
-@@ -301,7 +302,7 @@ static ssize_t mon_text_read(struct file
- set_current_state(TASK_RUNNING);
- remove_wait_queue(&rp->wait, &waita);
-
-- down(&rp->printf_lock);
-+ mutex_lock(&rp->printf_lock);
- cnt = 0;
- pbuf = rp->printf_buf;
- limit = rp->printf_size;
-@@ -358,7 +359,7 @@ static ssize_t mon_text_read(struct file
-
- if (copy_to_user(buf, rp->printf_buf, cnt))
- cnt = -EFAULT;
-- up(&rp->printf_lock);
-+ mutex_unlock(&rp->printf_lock);
- kmem_cache_free(rp->e_slab, ep);
- return cnt;
- }
-@@ -371,12 +372,12 @@ static int mon_text_release(struct inode
- struct list_head *p;
- struct mon_event_text *ep;
-
-- down(&mon_lock);
-+ mutex_lock(&mon_lock);
- mbus = inode->u.generic_ip;
-
- if (mbus->nreaders <= 0) {
- printk(KERN_ERR TAG ": consistency error on close\n");
-- up(&mon_lock);
-+ mutex_unlock(&mon_lock);
- return 0;
- }
- mon_reader_del(mbus, &rp->r);
-@@ -402,7 +403,7 @@ static int mon_text_release(struct inode
- kfree(rp->printf_buf);
- kfree(rp);
-
-- up(&mon_lock);
-+ mutex_unlock(&mon_lock);
- return 0;
- }
-
---- gregkh-2.6.orig/drivers/usb/mon/usb_mon.h
-+++ gregkh-2.6/drivers/usb/mon/usb_mon.h
-@@ -49,7 +49,7 @@ void mon_reader_del(struct mon_bus *mbus
- */
- extern char mon_dmapeek(unsigned char *dst, dma_addr_t dma_addr, int len);
-
--extern struct semaphore mon_lock;
-+extern struct mutex mon_lock;
-
- extern struct file_operations mon_fops_text;
- extern struct file_operations mon_fops_stat;
---- gregkh-2.6.orig/drivers/usb/storage/scsiglue.c
-+++ gregkh-2.6/drivers/usb/storage/scsiglue.c
-@@ -47,6 +47,7 @@
-
- #include <linux/slab.h>
- #include <linux/module.h>
-+#include <linux/mutex.h>
-
- #include <scsi/scsi.h>
- #include <scsi/scsi_cmnd.h>
-@@ -271,9 +272,9 @@ static int device_reset(struct scsi_cmnd
- US_DEBUGP("%s called\n", __FUNCTION__);
-
- /* lock the device pointers and do the reset */
-- down(&(us->dev_semaphore));
-+ mutex_lock(&(us->dev_mutex));
- result = us->transport_reset(us);
-- up(&(us->dev_semaphore));
-+ mutex_unlock(&us->dev_mutex);
-
- return result < 0 ? FAILED : SUCCESS;
- }
-@@ -286,9 +287,9 @@ static int bus_reset(struct scsi_cmnd *s
-
- US_DEBUGP("%s called\n", __FUNCTION__);
-
-- down(&(us->dev_semaphore));
-+ mutex_lock(&(us->dev_mutex));
- result = usb_stor_port_reset(us);
-- up(&(us->dev_semaphore));
-+ mutex_unlock(&us->dev_mutex);
-
- return result < 0 ? FAILED : SUCCESS;
- }
---- gregkh-2.6.orig/drivers/usb/storage/usb.c
-+++ gregkh-2.6/drivers/usb/storage/usb.c
-@@ -55,6 +55,7 @@
- #include <linux/init.h>
- #include <linux/slab.h>
- #include <linux/kthread.h>
-+#include <linux/mutex.h>
-
- #include <scsi/scsi.h>
- #include <scsi/scsi_cmnd.h>
-@@ -188,7 +189,7 @@ static int storage_suspend(struct usb_in
- struct us_data *us = usb_get_intfdata(iface);
-
- /* Wait until no command is running */
-- down(&us->dev_semaphore);
-+ mutex_lock(&us->dev_mutex);
-
- US_DEBUGP("%s\n", __FUNCTION__);
- if (us->suspend_resume_hook)
-@@ -198,7 +199,7 @@ static int storage_suspend(struct usb_in
- /* When runtime PM is working, we'll set a flag to indicate
- * whether we should autoresume when a SCSI request arrives. */
-
-- up(&us->dev_semaphore);
-+ mutex_unlock(&us->dev_mutex);
- return 0;
- }
-
-@@ -206,14 +207,14 @@ static int storage_resume(struct usb_int
- {
- struct us_data *us = usb_get_intfdata(iface);
-
-- down(&us->dev_semaphore);
-+ mutex_lock(&us->dev_mutex);
-
- US_DEBUGP("%s\n", __FUNCTION__);
- if (us->suspend_resume_hook)
- (us->suspend_resume_hook)(us, US_RESUME);
- iface->dev.power.power_state.event = PM_EVENT_ON;
-
-- up(&us->dev_semaphore);
-+ mutex_unlock(&us->dev_mutex);
- return 0;
- }
-
-@@ -276,12 +277,12 @@ static int usb_stor_control_thread(void
- US_DEBUGP("*** thread awakened.\n");
-
- /* lock the device pointers */
-- down(&(us->dev_semaphore));
-+ mutex_lock(&(us->dev_mutex));
-
- /* if the device has disconnected, we are free to exit */
- if (test_bit(US_FLIDX_DISCONNECTING, &us->flags)) {
- US_DEBUGP("-- exiting\n");
-- up(&(us->dev_semaphore));
-+ mutex_unlock(&us->dev_mutex);
- break;
- }
-
-@@ -370,7 +371,7 @@ SkipForAbort:
- scsi_unlock(host);
-
- /* unlock the device pointers */
-- up(&(us->dev_semaphore));
-+ mutex_unlock(&us->dev_mutex);
- } /* for (;;) */
-
- scsi_host_put(host);
-@@ -815,8 +816,8 @@ static void quiesce_and_remove_host(stru
- * The thread will exit when it sees the DISCONNECTING flag. */
-
- /* Wait for the current command to finish, then remove the host */
-- down(&us->dev_semaphore);
-- up(&us->dev_semaphore);
-+ mutex_lock(&us->dev_mutex);
-+ mutex_unlock(&us->dev_mutex);
-
- /* queuecommand won't accept any new commands and the control
- * thread won't execute a previously-queued command. If there
-@@ -870,9 +871,9 @@ retry:
- /* For bulk-only devices, determine the max LUN value */
- if (us->protocol == US_PR_BULK &&
- !(us->flags & US_FL_SINGLE_LUN)) {
-- down(&us->dev_semaphore);
-+ mutex_lock(&us->dev_mutex);
- us->max_lun = usb_stor_Bulk_max_lun(us);
-- up(&us->dev_semaphore);
-+ mutex_unlock(&us->dev_mutex);
- }
- scsi_scan_host(us_to_host(us));
- printk(KERN_DEBUG "usb-storage: device scan complete\n");
-@@ -912,7 +913,7 @@ static int storage_probe(struct usb_inte
-
- us = host_to_us(host);
- memset(us, 0, sizeof(struct us_data));
-- init_MUTEX(&(us->dev_semaphore));
-+ mutex_init(&(us->dev_mutex));
- init_MUTEX_LOCKED(&(us->sema));
- init_completion(&(us->notify));
- init_waitqueue_head(&us->delay_wait);
---- gregkh-2.6.orig/drivers/usb/storage/usb.h
-+++ gregkh-2.6/drivers/usb/storage/usb.h
-@@ -49,6 +49,7 @@
- #include <linux/blkdev.h>
- #include <linux/smp_lock.h>
- #include <linux/completion.h>
-+#include <linux/mutex.h>
- #include <scsi/scsi_host.h>
-
- struct us_data;
-@@ -103,9 +104,9 @@ typedef void (*pm_hook)(struct us_data *
- struct us_data {
- /* The device we're working with
- * It's important to note:
-- * (o) you must hold dev_semaphore to change pusb_dev
-+ * (o) you must hold dev_mutex to change pusb_dev
- */
-- struct semaphore dev_semaphore; /* protect pusb_dev */
-+ struct mutex dev_mutex; /* protect pusb_dev */
- struct usb_device *pusb_dev; /* this usb_device */
- struct usb_interface *pusb_intf; /* this interface */
- struct us_unusual_dev *unusual_dev; /* device-filter entry */
diff --git a/usb/usb-core-and-hcds-don-t-put_device-while-atomic.patch b/usb/usb-core-and-hcds-don-t-put_device-while-atomic.patch
deleted file mode 100644
index fb56e59c9d5eb..0000000000000
--- a/usb/usb-core-and-hcds-don-t-put_device-while-atomic.patch
+++ /dev/null
@@ -1,160 +0,0 @@
-From stern@rowland.harvard.edu Thu Jan 19 07:46:36 2006
-Date: Thu, 19 Jan 2006 10:46:27 -0500 (EST)
-From: Alan Stern <stern@rowland.harvard.edu>
-To: Greg KH <greg@kroah.com>
-cc: David Brownell <david-b@pacbell.net>, Olav Kongas <ok@artecdesign.ee>
-Subject: [PATCH] USB core and HCDs: don't put_device while atomic
-Message-ID: <Pine.LNX.4.44L0.0601191036380.4622-100000@iolanthe.rowland.org>
-
-This patch (as640) removes several put_device and the corresponding
-get_device calls from the USB core and HCDs. Some of the puts were done
-in atomic contexts, and none of them are needed since the core now
-guarantees that every endpoint will be disabled and every URB completed
-before a USB device is released.
-
-
-Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
-Acked-by: David Brownell <david-b@pacbell.net>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-
----
- drivers/usb/core/hcd.c | 2 --
- drivers/usb/host/ehci-mem.c | 1 -
- drivers/usb/host/ehci-q.c | 2 +-
- drivers/usb/host/ehci-sched.c | 6 ++----
- drivers/usb/host/isp116x-hcd.c | 3 +--
- drivers/usb/host/sl811-hcd.c | 3 +--
- drivers/usb/host/uhci-q.c | 2 --
- 7 files changed, 5 insertions(+), 14 deletions(-)
-
---- gregkh-2.6.orig/drivers/usb/core/hcd.c
-+++ gregkh-2.6/drivers/usb/core/hcd.c
-@@ -1105,7 +1105,6 @@ static void urb_unlink (struct urb *urb)
- spin_lock_irqsave (&hcd_data_lock, flags);
- list_del_init (&urb->urb_list);
- spin_unlock_irqrestore (&hcd_data_lock, flags);
-- usb_put_dev (urb->dev);
- }
-
-
-@@ -1145,7 +1144,6 @@ static int hcd_submit_urb (struct urb *u
- case HC_STATE_RUNNING:
- case HC_STATE_RESUMING:
- doit:
-- usb_get_dev (urb->dev);
- list_add_tail (&urb->urb_list, &ep->urb_list);
- status = 0;
- break;
---- gregkh-2.6.orig/drivers/usb/host/ehci-mem.c
-+++ gregkh-2.6/drivers/usb/host/ehci-mem.c
-@@ -75,7 +75,6 @@ static void qh_destroy (struct kref *kre
- }
- if (qh->dummy)
- ehci_qtd_free (ehci, qh->dummy);
-- usb_put_dev (qh->dev);
- dma_pool_free (ehci->qh_pool, qh, qh->qh_dma);
- }
-
---- gregkh-2.6.orig/drivers/usb/host/ehci-q.c
-+++ gregkh-2.6/drivers/usb/host/ehci-q.c
-@@ -702,7 +702,7 @@ qh_make (
- }
-
- /* support for tt scheduling, and access to toggles */
-- qh->dev = usb_get_dev (urb->dev);
-+ qh->dev = urb->dev;
-
- /* using TT? */
- switch (urb->dev->speed) {
---- gregkh-2.6.orig/drivers/usb/host/ehci-sched.c
-+++ gregkh-2.6/drivers/usb/host/ehci-sched.c
-@@ -1399,7 +1399,7 @@ itd_complete (
- */
-
- /* give urb back to the driver ... can be out-of-order */
-- dev = usb_get_dev (urb->dev);
-+ dev = urb->dev;
- ehci_urb_done (ehci, urb, regs);
- urb = NULL;
-
-@@ -1418,7 +1418,6 @@ itd_complete (
- (stream->bEndpointAddress & USB_DIR_IN) ? "in" : "out");
- }
- iso_stream_put (ehci, stream);
-- usb_put_dev (dev);
-
- return 1;
- }
-@@ -1765,7 +1764,7 @@ sitd_complete (
- */
-
- /* give urb back to the driver */
-- dev = usb_get_dev (urb->dev);
-+ dev = urb->dev;
- ehci_urb_done (ehci, urb, regs);
- urb = NULL;
-
-@@ -1784,7 +1783,6 @@ sitd_complete (
- (stream->bEndpointAddress & USB_DIR_IN) ? "in" : "out");
- }
- iso_stream_put (ehci, stream);
-- usb_put_dev (dev);
-
- return 1;
- }
---- gregkh-2.6.orig/drivers/usb/host/isp116x-hcd.c
-+++ gregkh-2.6/drivers/usb/host/isp116x-hcd.c
-@@ -724,7 +724,7 @@ static int isp116x_urb_enqueue(struct us
- ep = hep->hcpriv;
- else {
- INIT_LIST_HEAD(&ep->schedule);
-- ep->udev = usb_get_dev(udev);
-+ ep->udev = udev;
- ep->epnum = epnum;
- ep->maxpacket = usb_maxpacket(udev, urb->pipe, is_out);
- usb_settoggle(udev, epnum, is_out, 0);
-@@ -891,7 +891,6 @@ static void isp116x_endpoint_disable(str
- if (!list_empty(&hep->urb_list))
- WARN("ep %p not empty?\n", ep);
-
-- usb_put_dev(ep->udev);
- kfree(ep);
- hep->hcpriv = NULL;
- }
---- gregkh-2.6.orig/drivers/usb/host/sl811-hcd.c
-+++ gregkh-2.6/drivers/usb/host/sl811-hcd.c
-@@ -853,7 +853,7 @@ static int sl811h_urb_enqueue(
-
- } else {
- INIT_LIST_HEAD(&ep->schedule);
-- ep->udev = usb_get_dev(udev);
-+ ep->udev = udev;
- ep->epnum = epnum;
- ep->maxpacket = usb_maxpacket(udev, urb->pipe, is_out);
- ep->defctrl = SL11H_HCTLMASK_ARM | SL11H_HCTLMASK_ENABLE;
-@@ -1052,7 +1052,6 @@ sl811h_endpoint_disable(struct usb_hcd *
- if (!list_empty(&hep->urb_list))
- WARN("ep %p not empty?\n", ep);
-
-- usb_put_dev(ep->udev);
- kfree(ep);
- hep->hcpriv = NULL;
- }
---- gregkh-2.6.orig/drivers/usb/host/uhci-q.c
-+++ gregkh-2.6/drivers/usb/host/uhci-q.c
-@@ -179,7 +179,6 @@ static struct uhci_qh *uhci_alloc_qh(str
- qh->hep = hep;
- qh->udev = udev;
- hep->hcpriv = qh;
-- usb_get_dev(udev);
-
- } else { /* Skeleton QH */
- qh->state = QH_STATE_ACTIVE;
-@@ -197,7 +196,6 @@ static void uhci_free_qh(struct uhci_hcd
- list_del(&qh->node);
- if (qh->udev) {
- qh->hep->hcpriv = NULL;
-- usb_put_dev(qh->udev);
- uhci_free_td(uhci, qh->dummy_td);
- }
- dma_pool_free(uhci->qh_pool, qh, qh->dma_handle);
diff --git a/usb/usb-cp2101-add-new-device-ids.patch b/usb/usb-cp2101-add-new-device-ids.patch
deleted file mode 100644
index e7dbd888bffbc..0000000000000
--- a/usb/usb-cp2101-add-new-device-ids.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From craig@microtron.org.uk Sat Mar 11 03:26:16 2006
-From: Craig Shelley <craig@microtron.org.uk>
-Subject: USB: cp2101: add new device IDs
-To: linux-usb-devel@lists.sourceforge.net
-Cc: Greg KH <greg@kroah.com>
-Date: Sat, 11 Mar 2006 11:29:02 +0000
-Message-Id: <1142076542.19343.30.camel@teratron.lan.etheus.net>
-
-This patch adds a new device ID to the cp2101 driver
-
-Signed-off-by: Craig Shelley <craig@microtron.org.uk>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-
-
----
- drivers/usb/serial/cp2101.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
---- gregkh-2.6.orig/drivers/usb/serial/cp2101.c
-+++ gregkh-2.6/drivers/usb/serial/cp2101.c
-@@ -32,7 +32,7 @@
- /*
- * Version Information
- */
--#define DRIVER_VERSION "v0.06"
-+#define DRIVER_VERSION "v0.07"
- #define DRIVER_DESC "Silicon Labs CP2101/CP2102 RS232 serial adaptor driver"
-
- /*
-@@ -58,6 +58,7 @@ static struct usb_device_id id_table []
- { USB_DEVICE(0x10A6, 0xAA26) }, /* Knock-off DCU-11 cable */
- { USB_DEVICE(0x10AB, 0x10C5) }, /* Siemens MC60 Cable */
- { USB_DEVICE(0x10B5, 0xAC70) }, /* Nokia CA-42 USB */
-+ { USB_DEVICE(0x10C4, 0x803B) }, /* Pololu USB-serial converter */
- { USB_DEVICE(0x10C4, 0x807A) }, /* Crumb128 board */
- { USB_DEVICE(0x10C4, 0x80CA) }, /* Degree Controls Inc */
- { USB_DEVICE(0x10C4, 0x80F6) }, /* Suunto sports instrument */
diff --git a/usb/usb-credits-add-credits-about-the-zc0301-and-et61x51-usb-drivers.patch b/usb/usb-credits-add-credits-about-the-zc0301-and-et61x51-usb-drivers.patch
deleted file mode 100644
index 44a149c6b1d66..0000000000000
--- a/usb/usb-credits-add-credits-about-the-zc0301-and-et61x51-usb-drivers.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From luca.risolia@studio.unibo.it Tue Feb 7 15:49:05 2006
-Date: Wed, 8 Feb 2006 00:50:59 +0000
-From: Luca Risolia <luca.risolia@studio.unibo.it>
-To: Greg Kroah-Hartman <gregkh@suse.de>
-Subject: USB: CREDITS: Add credits about the ZC0301 and ET61X[12]51 USB drivers
-Message-ID: <20060208005059.GA10459@studio.unibo.it>
-Content-Disposition: inline
-
-This patch adds credits about the ZC0301 and ET61X[12]51 USB drivers
-which have been included in the mainline kernel recently.
-
-Signed-off-by: Luca Risolia <luca.risolia@studio.unibo.it>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-
----
- CREDITS | 2 ++
- 1 file changed, 2 insertions(+)
-
---- gregkh-2.6.orig/CREDITS
-+++ gregkh-2.6/CREDITS
-@@ -2814,6 +2814,8 @@ E: luca.risolia@studio.unibo.it
- P: 1024D/FCE635A4 88E8 F32F 7244 68BA 3958 5D40 99DA 5D2A FCE6 35A4
- D: V4L driver for W996[87]CF JPEG USB Dual Mode Camera Chips
- D: V4L2 driver for SN9C10x PC Camera Controllers
-+D: V4L2 driver for ET61X151 and ET61X251 PC Camera Controllers
-+D: V4L2 driver for ZC0301 Image Processor and Control Chip
- S: Via Liberta' 41/A
- S: Osio Sotto, 24046, Bergamo
- S: Italy
diff --git a/usb/usb-drivers-usb-core-message.c-make-usb_get_string-static.patch b/usb/usb-drivers-usb-core-message.c-make-usb_get_string-static.patch
deleted file mode 100644
index 22986520f932f..0000000000000
--- a/usb/usb-drivers-usb-core-message.c-make-usb_get_string-static.patch
+++ /dev/null
@@ -1,52 +0,0 @@
-From bunk@stusta.de Tue Nov 8 13:17:46 2005
-Date: Tue, 8 Nov 2005 21:05:43 +0100
-From: Adrian Bunk <bunk@stusta.de>
-To: Greg KH <gregkh@suse.de>
-Subject: USB: drivers/usb/core/message.c: make usb_get_string() static
-Message-ID: <20051108200543.GF3847@stusta.de>
-Content-Disposition: inline
-
-After the removal of usb-midi.c, there's no longer any external user of
-usb_get_string().
-
-
-Signed-off-by: Adrian Bunk <bunk@stusta.de>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-
----
- drivers/usb/core/message.c | 5 ++---
- include/linux/usb.h | 2 --
- 2 files changed, 2 insertions(+), 5 deletions(-)
-
---- gregkh-2.6.orig/drivers/usb/core/message.c
-+++ gregkh-2.6/drivers/usb/core/message.c
-@@ -631,8 +631,8 @@ int usb_get_descriptor(struct usb_device
- * Returns the number of bytes received on success, or else the status code
- * returned by the underlying usb_control_msg() call.
- */
--int usb_get_string(struct usb_device *dev, unsigned short langid,
-- unsigned char index, void *buf, int size)
-+static int usb_get_string(struct usb_device *dev, unsigned short langid,
-+ unsigned char index, void *buf, int size)
- {
- int i;
- int result;
-@@ -1488,7 +1488,6 @@ EXPORT_SYMBOL(usb_sg_wait);
- // synchronous control message convenience routines
- EXPORT_SYMBOL(usb_get_descriptor);
- EXPORT_SYMBOL(usb_get_status);
--EXPORT_SYMBOL(usb_get_string);
- EXPORT_SYMBOL(usb_string);
-
- // synchronous calls that also maintain usbcore state
---- gregkh-2.6.orig/include/linux/usb.h
-+++ gregkh-2.6/include/linux/usb.h
-@@ -1018,8 +1018,6 @@ extern int usb_get_descriptor(struct usb
- unsigned char descindex, void *buf, int size);
- extern int usb_get_status(struct usb_device *dev,
- int type, int target, void *data);
--extern int usb_get_string(struct usb_device *dev,
-- unsigned short langid, unsigned char index, void *buf, int size);
- extern int usb_string(struct usb_device *dev, int index,
- char *buf, size_t size);
-
diff --git a/usb/usb-ehci-and-freescale-83xx-quirk.patch b/usb/usb-ehci-and-freescale-83xx-quirk.patch
deleted file mode 100644
index dcd4bf5cd741d..0000000000000
--- a/usb/usb-ehci-and-freescale-83xx-quirk.patch
+++ /dev/null
@@ -1,94 +0,0 @@
-From david-b@pacbell.net Fri Jan 20 17:25:17 2006
-From: David Brownell <david-b@pacbell.net>
-To: Greg KH <greg@kroah.com>
-Subject: USB: EHCI and Freescale 83xx quirk
-Date: Fri, 20 Jan 2006 13:57:52 -0800
-Message-Id: <200601201357.52344.david-b@pacbell.net>
-
-From: Kumar Gala <galak@gate.crashing.org>
-
-On the MPC834x processors the multiport host (MPH) EHCI controller has an
-erratum in which the port number in the queue head expects to be 0..N-1
-instead of 1..N. If we are on one of these chips we subtract one from
-the port number before putting it into the queue head.
-
-Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
-Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-
----
- drivers/usb/host/ehci-fsl.c | 10 ++++++++++
- drivers/usb/host/ehci-q.c | 9 ++++++++-
- drivers/usb/host/ehci.h | 15 +++++++++++++++
- 3 files changed, 33 insertions(+), 1 deletion(-)
-
---- gregkh-2.6.orig/drivers/usb/host/ehci-fsl.c
-+++ gregkh-2.6/drivers/usb/host/ehci-fsl.c
-@@ -198,6 +198,16 @@ static void mpc83xx_usb_setup(struct usb
- mpc83xx_setup_phy(ehci, pdata->phy_mode, 0);
-
- if (pdata->operating_mode == FSL_USB2_MPH_HOST) {
-+ unsigned int chip, rev, svr;
-+
-+ svr = mfspr(SPRN_SVR);
-+ chip = svr >> 16;
-+ rev = (svr >> 4) & 0xf;
-+
-+ /* Deal with USB Erratum #14 on MPC834x Rev 1.0 & 1.1 chips */
-+ if ((rev == 1) && (chip >= 0x8050) && (chip <= 0x8055))
-+ ehci->has_fsl_port_bug = 1;
-+
- if (pdata->port_enables & FSL_USB2_PORT0_ENABLED)
- mpc83xx_setup_phy(ehci, pdata->phy_mode, 0);
- if (pdata->port_enables & FSL_USB2_PORT1_ENABLED)
---- gregkh-2.6.orig/drivers/usb/host/ehci-q.c
-+++ gregkh-2.6/drivers/usb/host/ehci-q.c
-@@ -721,7 +721,14 @@ qh_make (
- info1 |= maxp << 16;
-
- info2 |= (EHCI_TUNE_MULT_TT << 30);
-- info2 |= urb->dev->ttport << 23;
-+
-+ /* Some Freescale processors have an erratum in which the
-+ * port number in the queue head was 0..N-1 instead of 1..N.
-+ */
-+ if (ehci_has_fsl_portno_bug(ehci))
-+ info2 |= (urb->dev->ttport-1) << 23;
-+ else
-+ info2 |= urb->dev->ttport << 23;
-
- /* set the address of the TT; for TDI's integrated
- * root hub tt, leave it zeroed.
---- gregkh-2.6.orig/drivers/usb/host/ehci.h
-+++ gregkh-2.6/drivers/usb/host/ehci.h
-@@ -88,8 +88,11 @@ struct ehci_hcd { /* one per controlle
- unsigned long next_statechange;
- u32 command;
-
-+ /* SILICON QUIRKS */
- unsigned is_tdi_rh_tt:1; /* TDI roothub with TT */
- unsigned no_selective_suspend:1;
-+ unsigned has_fsl_port_bug:1; /* FreeScale */
-+
- u8 sbrn; /* packed release number */
-
- /* irq statistics */
-@@ -639,6 +642,18 @@ ehci_port_speed(struct ehci_hcd *ehci, u
-
- /*-------------------------------------------------------------------------*/
-
-+#ifdef CONFIG_PPC_83xx
-+/* Some Freescale processors have an erratum in which the TT
-+ * port number in the queue head was 0..N-1 instead of 1..N.
-+ */
-+#define ehci_has_fsl_portno_bug(e) ((e)->has_fsl_port_bug)
-+#else
-+#define ehci_has_fsl_portno_bug(e) (0)
-+#endif
-+
-+
-+/*-------------------------------------------------------------------------*/
-+
- #ifndef DEBUG
- #define STUB_DEBUG_FILES
- #endif /* DEBUG */
diff --git a/usb/usb-ehci-and-nf2-quirk.patch b/usb/usb-ehci-and-nf2-quirk.patch
deleted file mode 100644
index 3305ef7a7e64d..0000000000000
--- a/usb/usb-ehci-and-nf2-quirk.patch
+++ /dev/null
@@ -1,120 +0,0 @@
-From david-b@pacbell.net Fri Jan 20 17:25:17 2006
-From: David Brownell <david-b@pacbell.net>
-Subject: USB: EHCI and NF2 quirk
-To: Greg KH <greg@kroah.com>
-Date: Fri, 20 Jan 2006 13:55:14 -0800
-Message-Id: <200601201355.14378.david-b@pacbell.net>
-
-This teaches the EHCI driver about a quirk seen in older NForce2 chips,
-adding a workaround to ignore selective suspend requests. Bus-wide
-(so-called "global") suspend still works, as does USB wakeup of a
-root hub that's globally suspended.
-
-There's still a hole in this support though. Strictly speaking, this
-should _fail_ selective suspend requests, rather than ignoring them,
-since doing it this way means that devices which should be able to issue
-remote wakeup are not going to be able to do that. For now, we'll just
-live with that problem ... since usbcore expects to do selective suspend
-on the way towards a full bus suspend, and usbcore needs to be able to
-do full bus suspend.
-
-Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-
----
- drivers/usb/host/ehci-hub.c | 4 ++++
- drivers/usb/host/ehci-pci.c | 25 ++++++++++++++++++++++++-
- drivers/usb/host/ehci.h | 3 ++-
- 3 files changed, 30 insertions(+), 2 deletions(-)
-
---- gregkh-2.6.orig/drivers/usb/host/ehci-hub.c
-+++ gregkh-2.6/drivers/usb/host/ehci-hub.c
-@@ -359,6 +359,8 @@ static int ehci_hub_control (
- case USB_PORT_FEAT_SUSPEND:
- if (temp & PORT_RESET)
- goto error;
-+ if (ehci->no_selective_suspend)
-+ break;
- if (temp & PORT_SUSPEND) {
- if ((temp & PORT_PE) == 0)
- goto error;
-@@ -514,6 +516,8 @@ static int ehci_hub_control (
- temp &= ~PORT_RWC_BITS;
- switch (wValue) {
- case USB_PORT_FEAT_SUSPEND:
-+ if (ehci->no_selective_suspend)
-+ break;
- if ((temp & PORT_PE) == 0
- || (temp & PORT_RESET) != 0)
- goto error;
---- gregkh-2.6.orig/drivers/usb/host/ehci-pci.c
-+++ gregkh-2.6/drivers/usb/host/ehci-pci.c
-@@ -106,11 +106,11 @@ static int ehci_pci_setup(struct usb_hcd
- }
- break;
- case PCI_VENDOR_ID_NVIDIA:
-+ switch (pdev->device) {
- /* NVidia reports that certain chips don't handle
- * QH, ITD, or SITD addresses above 2GB. (But TD,
- * data buffer, and periodic schedule are normal.)
- */
-- switch (pdev->device) {
- case 0x003c: /* MCP04 */
- case 0x005b: /* CK804 */
- case 0x00d8: /* CK8 */
-@@ -120,6 +120,14 @@ static int ehci_pci_setup(struct usb_hcd
- ehci_warn(ehci, "can't enable NVidia "
- "workaround for >2GB RAM\n");
- break;
-+ /* Some NForce2 chips have problems with selective suspend;
-+ * fixed in newer silicon.
-+ */
-+ case 0x0068:
-+ pci_read_config_dword(pdev, PCI_REVISION_ID, &temp);
-+ if ((temp & 0xff) < 0xa4)
-+ ehci->no_selective_suspend = 1;
-+ break;
- }
- break;
- }
-@@ -163,6 +171,21 @@ static int ehci_pci_setup(struct usb_hcd
- device_init_wakeup(&pdev->dev, 1);
- }
-
-+#ifdef CONFIG_USB_SUSPEND
-+ /* REVISIT: the controller works fine for wakeup iff the root hub
-+ * itself is "globally" suspended, but usbcore currently doesn't
-+ * understand such things.
-+ *
-+ * System suspend currently expects to be able to suspend the entire
-+ * device tree, device-at-a-time. If we failed selective suspend
-+ * reports, system suspend would fail; so the root hub code must claim
-+ * success. That's lying to usbcore, and it matters for for runtime
-+ * PM scenarios with selective suspend and remote wakeup...
-+ */
-+ if (ehci->no_selective_suspend && device_can_wakeup(&pdev->dev))
-+ ehci_warn(ehci, "selective suspend/wakeup unavailable\n");
-+#endif
-+
- retval = ehci_pci_reinit(ehci, pdev);
- done:
- return retval;
---- gregkh-2.6.orig/drivers/usb/host/ehci.h
-+++ gregkh-2.6/drivers/usb/host/ehci.h
-@@ -89,6 +89,8 @@ struct ehci_hcd { /* one per controlle
- u32 command;
-
- unsigned is_tdi_rh_tt:1; /* TDI roothub with TT */
-+ unsigned no_selective_suspend:1;
-+ u8 sbrn; /* packed release number */
-
- /* irq statistics */
- #ifdef EHCI_STATS
-@@ -97,7 +99,6 @@ struct ehci_hcd { /* one per controlle
- #else
- # define COUNT(x) do {} while (0)
- #endif
-- u8 sbrn; /* packed release number */
- };
-
- /* convert between an HCD pointer and the corresponding EHCI_HCD */
diff --git a/usb/usb-ehci-for-au1200.patch b/usb/usb-ehci-for-au1200.patch
deleted file mode 100644
index 7ab53dc8f9d12..0000000000000
--- a/usb/usb-ehci-for-au1200.patch
+++ /dev/null
@@ -1,425 +0,0 @@
-From david-b@pacbell.net Fri Jan 20 17:25:17 2006
-From: Jordan Crouse <jordan.crouse@amd.com>
-To: Greg KH <greg@kroah.com>
-Subject: USB: EHCI for AU1200
-Date: Fri, 20 Jan 2006 14:06:09 -0800
-Message-Id: <200601201406.10265.david-b@pacbell.net>
-
-
-ALCHEMY: Add EHCI support for AU1200
-
-Updated by removing the OHCI support
-
-Signed-off-by: Jordan Crouse <jordan.crouse@amd.com>
-Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-
----
- arch/mips/au1000/common/cputable.c | 2
- arch/mips/au1000/common/platform.c | 2
- drivers/usb/Kconfig | 9
- drivers/usb/host/Kconfig | 2
- drivers/usb/host/ehci-au1xxx.c | 297 +++++++++++++++++++++
- drivers/usb/host/ehci-hcd.c | 11
- include/asm-mips/mach-mips/cpu-feature-overrides.h | 4
- 7 files changed, 319 insertions(+), 8 deletions(-)
-
---- gregkh-2.6.orig/arch/mips/au1000/common/cputable.c
-+++ gregkh-2.6/arch/mips/au1000/common/cputable.c
-@@ -38,7 +38,7 @@ struct cpu_spec cpu_specs[] = {
- { 0xffffffff, 0x02030204, "Au1100 BE", 0, 1 },
- { 0xffffffff, 0x03030200, "Au1550 AA", 0, 1 },
- { 0xffffffff, 0x04030200, "Au1200 AB", 0, 0 },
-- { 0xffffffff, 0x04030201, "Au1200 AC", 0, 1 },
-+ { 0xffffffff, 0x04030201, "Au1200 AC", 1, 0 },
- { 0x00000000, 0x00000000, "Unknown Au1xxx", 1, 0 },
- };
-
---- gregkh-2.6.orig/arch/mips/au1000/common/platform.c
-+++ gregkh-2.6/arch/mips/au1000/common/platform.c
-@@ -278,9 +278,7 @@ static struct platform_device *au1xxx_pl
- &au1100_lcd_device,
- #endif
- #ifdef CONFIG_SOC_AU1200
--#if 0 /* fixme */
- &au1xxx_usb_ehci_device,
--#endif
- &au1xxx_usb_gdt_device,
- &au1xxx_usb_otg_device,
- &au1200_lcd_device,
---- gregkh-2.6.orig/drivers/usb/Kconfig
-+++ gregkh-2.6/drivers/usb/Kconfig
-@@ -10,8 +10,8 @@ menu "USB support"
- config USB_ARCH_HAS_HCD
- boolean
- default y if USB_ARCH_HAS_OHCI
-+ default y if USB_ARCH_HAS_EHCI
- default y if ARM # SL-811
-- default y if PPC_83xx
- default PCI
-
- # many non-PCI SOC chips embed OHCI
-@@ -31,6 +31,13 @@ config USB_ARCH_HAS_OHCI
- # more:
- default PCI
-
-+# some non-PCI hcds implement EHCI
-+config USB_ARCH_HAS_EHCI
-+ boolean
-+ default y if PPC_83xx
-+ default y if SOC_AU1200
-+ default PCI
-+
- # ARM SA1111 chips have a non-PCI based "OHCI-compatible" USB host interface.
- config USB
- tristate "Support for Host-side USB"
---- gregkh-2.6.orig/drivers/usb/host/Kconfig
-+++ gregkh-2.6/drivers/usb/host/Kconfig
-@@ -6,7 +6,7 @@ comment "USB Host Controller Drivers"
-
- config USB_EHCI_HCD
- tristate "EHCI HCD (USB 2.0) support"
-- depends on USB && (PCI || PPC_83xx)
-+ depends on USB && USB_ARCH_HAS_EHCI
- ---help---
- The Enhanced Host Controller Interface (EHCI) is standard for USB 2.0
- "high speed" (480 Mbit/sec, 60 Mbyte/sec) host controller hardware.
---- /dev/null
-+++ gregkh-2.6/drivers/usb/host/ehci-au1xxx.c
-@@ -0,0 +1,297 @@
-+/*
-+ * EHCI HCD (Host Controller Driver) for USB.
-+ *
-+ * (C) Copyright 2000-2004 David Brownell <dbrownell@users.sourceforge.net>
-+ *
-+ * Bus Glue for AMD Alchemy Au1xxx
-+ *
-+ * Based on "ohci-au1xxx.c" by Matt Porter <mporter@kernel.crashing.org>
-+ *
-+ * Modified for AMD Alchemy Au1200 EHC
-+ * by K.Boge <karsten.boge@amd.com>
-+ *
-+ * This file is licenced under the GPL.
-+ */
-+
-+#include <linux/platform_device.h>
-+#include <asm/mach-au1x00/au1000.h>
-+
-+#ifndef CONFIG_SOC_AU1200
-+#error "this Alchemy chip doesn't have EHCI"
-+#else /* Au1200 */
-+
-+#define USB_HOST_CONFIG (USB_MSR_BASE + USB_MSR_MCFG)
-+#define USB_MCFG_PFEN (1<<31)
-+#define USB_MCFG_RDCOMB (1<<30)
-+#define USB_MCFG_SSDEN (1<<23)
-+#define USB_MCFG_PHYPLLEN (1<<19)
-+#define USB_MCFG_EHCCLKEN (1<<17)
-+#define USB_MCFG_UCAM (1<<7)
-+#define USB_MCFG_EBMEN (1<<3)
-+#define USB_MCFG_EMEMEN (1<<2)
-+
-+#define USBH_ENABLE_CE (USB_MCFG_PHYPLLEN | USB_MCFG_EHCCLKEN)
-+
-+#ifdef CONFIG_DMA_COHERENT
-+#define USBH_ENABLE_INIT (USBH_ENABLE_CE \
-+ | USB_MCFG_PFEN | USB_MCFG_RDCOMB \
-+ | USB_MCFG_SSDEN | USB_MCFG_UCAM \
-+ | USB_MCFG_EBMEN | USB_MCFG_EMEMEN)
-+#else
-+#define USBH_ENABLE_INIT (USBH_ENABLE_CE \
-+ | USB_MCFG_PFEN | USB_MCFG_RDCOMB \
-+ | USB_MCFG_SSDEN \
-+ | USB_MCFG_EBMEN | USB_MCFG_EMEMEN)
-+#endif
-+#define USBH_DISABLE (USB_MCFG_EBMEN | USB_MCFG_EMEMEN)
-+
-+#endif /* Au1200 */
-+
-+extern int usb_disabled(void);
-+
-+/*-------------------------------------------------------------------------*/
-+
-+static void au1xxx_start_ehc(struct platform_device *dev)
-+{
-+ pr_debug(__FILE__ ": starting Au1xxx EHCI USB Controller\n");
-+
-+ /* write HW defaults again in case Yamon cleared them */
-+ if (au_readl(USB_HOST_CONFIG) == 0) {
-+ au_writel(0x00d02000, USB_HOST_CONFIG);
-+ au_readl(USB_HOST_CONFIG);
-+ udelay(1000);
-+ }
-+ /* enable host controller */
-+ au_writel(USBH_ENABLE_CE | au_readl(USB_HOST_CONFIG), USB_HOST_CONFIG);
-+ au_readl(USB_HOST_CONFIG);
-+ udelay(1000);
-+ au_writel(USBH_ENABLE_INIT | au_readl(USB_HOST_CONFIG),
-+ USB_HOST_CONFIG);
-+ au_readl(USB_HOST_CONFIG);
-+ udelay(1000);
-+
-+ pr_debug(__FILE__ ": Clock to USB host has been enabled\n");
-+}
-+
-+static void au1xxx_stop_ehc(struct platform_device *dev)
-+{
-+ pr_debug(__FILE__ ": stopping Au1xxx EHCI USB Controller\n");
-+
-+ /* Disable mem */
-+ au_writel(~USBH_DISABLE & au_readl(USB_HOST_CONFIG), USB_HOST_CONFIG);
-+ udelay(1000);
-+ /* Disable clock */
-+ au_writel(~USB_MCFG_EHCCLKEN & au_readl(USB_HOST_CONFIG),
-+ USB_HOST_CONFIG);
-+ au_readl(USB_HOST_CONFIG);
-+}
-+
-+/*-------------------------------------------------------------------------*/
-+
-+/* configure so an HC device and id are always provided */
-+/* always called with process context; sleeping is OK */
-+
-+/**
-+ * usb_ehci_au1xxx_probe - initialize Au1xxx-based HCDs
-+ * Context: !in_interrupt()
-+ *
-+ * Allocates basic resources for this USB host controller, and
-+ * then invokes the start() method for the HCD associated with it
-+ * through the hotplug entry's driver_data.
-+ *
-+ */
-+int usb_ehci_au1xxx_probe(const struct hc_driver *driver,
-+ struct usb_hcd **hcd_out, struct platform_device *dev)
-+{
-+ int retval;
-+ struct usb_hcd *hcd;
-+ struct ehci_hcd *ehci;
-+
-+#if defined(CONFIG_SOC_AU1200) && defined(CONFIG_DMA_COHERENT)
-+
-+ /* Au1200 AB USB does not support coherent memory */
-+ if (!(read_c0_prid() & 0xff)) {
-+ pr_info("%s: this is chip revision AB!\n", dev->dev.name);
-+ pr_info("%s: update your board or re-configure the kernel\n",
-+ dev->dev.name);
-+ return -ENODEV;
-+ }
-+#endif
-+
-+ au1xxx_start_ehc(dev);
-+
-+ if (dev->resource[1].flags != IORESOURCE_IRQ) {
-+ pr_debug("resource[1] is not IORESOURCE_IRQ");
-+ retval = -ENOMEM;
-+ }
-+ hcd = usb_create_hcd(driver, &dev->dev, "Au1xxx");
-+ if (!hcd)
-+ return -ENOMEM;
-+ hcd->rsrc_start = dev->resource[0].start;
-+ hcd->rsrc_len = dev->resource[0].end - dev->resource[0].start + 1;
-+
-+ if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
-+ pr_debug("request_mem_region failed");
-+ retval = -EBUSY;
-+ goto err1;
-+ }
-+
-+ hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
-+ if (!hcd->regs) {
-+ pr_debug("ioremap failed");
-+ retval = -ENOMEM;
-+ goto err2;
-+ }
-+
-+ ehci = hcd_to_ehci(hcd);
-+ ehci->caps = hcd->regs;
-+ ehci->regs = hcd->regs + HC_LENGTH(readl(&ehci->caps->hc_capbase));
-+ /* cache this readonly data; minimize chip reads */
-+ ehci->hcs_params = readl(&ehci->caps->hcs_params);
-+
-+ /* ehci_hcd_init(hcd_to_ehci(hcd)); */
-+
-+ retval =
-+ usb_add_hcd(hcd, dev->resource[1].start, SA_INTERRUPT | SA_SHIRQ);
-+ if (retval == 0)
-+ return retval;
-+
-+ au1xxx_stop_ehc(dev);
-+ iounmap(hcd->regs);
-+err2:
-+ release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
-+err1:
-+ usb_put_hcd(hcd);
-+ return retval;
-+}
-+
-+/* may be called without controller electrically present */
-+/* may be called with controller, bus, and devices active */
-+
-+/**
-+ * usb_ehci_hcd_au1xxx_remove - shutdown processing for Au1xxx-based HCDs
-+ * @dev: USB Host Controller being removed
-+ * Context: !in_interrupt()
-+ *
-+ * Reverses the effect of usb_ehci_hcd_au1xxx_probe(), first invoking
-+ * the HCD's stop() method. It is always called from a thread
-+ * context, normally "rmmod", "apmd", or something similar.
-+ *
-+ */
-+void usb_ehci_au1xxx_remove(struct usb_hcd *hcd, struct platform_device *dev)
-+{
-+ usb_remove_hcd(hcd);
-+ iounmap(hcd->regs);
-+ release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
-+ usb_put_hcd(hcd);
-+ au1xxx_stop_ehc(dev);
-+}
-+
-+/*-------------------------------------------------------------------------*/
-+
-+static const struct hc_driver ehci_au1xxx_hc_driver = {
-+ .description = hcd_name,
-+ .product_desc = "Au1xxx EHCI",
-+ .hcd_priv_size = sizeof(struct ehci_hcd),
-+
-+ /*
-+ * generic hardware linkage
-+ */
-+ .irq = ehci_irq,
-+ .flags = HCD_MEMORY | HCD_USB2,
-+
-+ /*
-+ * basic lifecycle operations
-+ */
-+ .reset = ehci_init,
-+ .start = ehci_run,
-+ .stop = ehci_stop,
-+
-+ /*
-+ * managing i/o requests and associated device resources
-+ */
-+ .urb_enqueue = ehci_urb_enqueue,
-+ .urb_dequeue = ehci_urb_dequeue,
-+ .endpoint_disable = ehci_endpoint_disable,
-+
-+ /*
-+ * scheduling support
-+ */
-+ .get_frame_number = ehci_get_frame,
-+
-+ /*
-+ * root hub support
-+ */
-+ .hub_status_data = ehci_hub_status_data,
-+ .hub_control = ehci_hub_control,
-+#ifdef CONFIG_PM
-+ .hub_suspend = ehci_hub_suspend,
-+ .hub_resume = ehci_hub_resume,
-+#endif
-+};
-+
-+/*-------------------------------------------------------------------------*/
-+
-+static int ehci_hcd_au1xxx_drv_probe(struct device *dev)
-+{
-+ struct platform_device *pdev = to_platform_device(dev);
-+ struct usb_hcd *hcd = NULL;
-+ int ret;
-+
-+ pr_debug("In ehci_hcd_au1xxx_drv_probe\n");
-+
-+ if (usb_disabled())
-+ return -ENODEV;
-+
-+ ret = usb_ehci_au1xxx_probe(&ehci_au1xxx_hc_driver, &hcd, pdev);
-+ return ret;
-+}
-+
-+static int ehci_hcd_au1xxx_drv_remove(struct device *dev)
-+{
-+ struct platform_device *pdev = to_platform_device(dev);
-+ struct usb_hcd *hcd = dev_get_drvdata(dev);
-+
-+ usb_ehci_au1xxx_remove(hcd, pdev);
-+ return 0;
-+}
-+
-+ /*TBD*/
-+/*static int ehci_hcd_au1xxx_drv_suspend(struct device *dev)
-+{
-+ struct platform_device *pdev = to_platform_device(dev);
-+ struct usb_hcd *hcd = dev_get_drvdata(dev);
-+
-+ return 0;
-+}
-+static int ehci_hcd_au1xxx_drv_resume(struct device *dev)
-+{
-+ struct platform_device *pdev = to_platform_device(dev);
-+ struct usb_hcd *hcd = dev_get_drvdata(dev);
-+
-+ return 0;
-+}
-+*/
-+static struct device_driver ehci_hcd_au1xxx_driver = {
-+ .name = "au1xxx-ehci",
-+ .bus = &platform_bus_type,
-+ .probe = ehci_hcd_au1xxx_drv_probe,
-+ .remove = ehci_hcd_au1xxx_drv_remove,
-+ /*.suspend = ehci_hcd_au1xxx_drv_suspend, */
-+ /*.resume = ehci_hcd_au1xxx_drv_resume, */
-+};
-+
-+static int __init ehci_hcd_au1xxx_init(void)
-+{
-+ pr_debug(DRIVER_INFO " (Au1xxx)\n");
-+
-+ return driver_register(&ehci_hcd_au1xxx_driver);
-+}
-+
-+static void __exit ehci_hcd_au1xxx_cleanup(void)
-+{
-+ driver_unregister(&ehci_hcd_au1xxx_driver);
-+}
-+
-+module_init(ehci_hcd_au1xxx_init);
-+module_exit(ehci_hcd_au1xxx_cleanup);
---- gregkh-2.6.orig/drivers/usb/host/ehci-hcd.c
-+++ gregkh-2.6/drivers/usb/host/ehci-hcd.c
-@@ -889,14 +889,19 @@ MODULE_LICENSE ("GPL");
-
- #ifdef CONFIG_PCI
- #include "ehci-pci.c"
-+#define EHCI_BUS_GLUED
- #endif
-
- #ifdef CONFIG_PPC_83xx
- #include "ehci-fsl.c"
-+#define EHCI_BUS_GLUED
- #endif
-
--#if !(defined(CONFIG_PCI) || \
-- defined(CONFIG_PPC_83xx) \
-- )
-+#ifdef CONFIG_SOC_AU1X00
-+#include "ehci-au1xxx.c"
-+#define EHCI_BUS_GLUED
-+#endif
-+
-+#ifndef EHCI_BUS_GLUED
- #error "missing bus glue for ehci-hcd"
- #endif
---- gregkh-2.6.orig/include/asm-mips/mach-mips/cpu-feature-overrides.h
-+++ gregkh-2.6/include/asm-mips/mach-mips/cpu-feature-overrides.h
-@@ -29,7 +29,11 @@
- /* #define cpu_has_prefetch ? */
- #define cpu_has_mcheck 1
- /* #define cpu_has_ejtag ? */
-+#ifdef CONFIG_CPU_HAS_LLSC
- #define cpu_has_llsc 1
-+#else
-+#define cpu_has_llsc 0
-+#endif
- /* #define cpu_has_vtag_icache ? */
- /* #define cpu_has_dc_aliases ? */
- /* #define cpu_has_ic_fills_f_dc ? */
diff --git a/usb/usb-ehci-for-freescale-83xx.patch b/usb/usb-ehci-for-freescale-83xx.patch
deleted file mode 100644
index 9d29889daa8df..0000000000000
--- a/usb/usb-ehci-for-freescale-83xx.patch
+++ /dev/null
@@ -1,503 +0,0 @@
-From david-b@pacbell.net Fri Jan 20 17:25:17 2006
-From: David Brownell <david-b@pacbell.net>
-To: Greg KH <greg@kroah.com>
-Subject: USB: EHCI for Freescale 83xx
-Date: Fri, 20 Jan 2006 13:53:38 -0800
-Cc: linux-usb-devel@lists.sourceforge.net
-Message-Id: <200601201353.38733.david-b@pacbell.net>
-
-From: Randy Vinson <rvinson@mvista.com>
-
-Adding a Host Mode USB driver for the Freescale 83xx.
-
-This driver supports both the Dual-Role (DR) controller and the
-Multi-Port-Host (MPH) controller present in the Freescale MPC8349. It has
-been tested with the MPC8349CDS reference system. This driver depends on
-platform support code for setting up the pins on the device package in a
-manner appropriate for the board in use. Note that this patch requires
-selecting the EHCI controller option under the USB Host menu.
-
-Signed-off-by: Randy Vinson <rvinson@mvista.com>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-
----
- drivers/usb/Kconfig | 1
- drivers/usb/host/Kconfig | 2
- drivers/usb/host/ehci-fsl.c | 357 ++++++++++++++++++++++++++++++++++++++++++++
- drivers/usb/host/ehci-fsl.h | 37 ++++
- drivers/usb/host/ehci-hcd.c | 8
- include/linux/fsl_devices.h | 27 +++
- 6 files changed, 430 insertions(+), 2 deletions(-)
-
---- gregkh-2.6.orig/drivers/usb/Kconfig
-+++ gregkh-2.6/drivers/usb/Kconfig
-@@ -11,6 +11,7 @@ config USB_ARCH_HAS_HCD
- boolean
- default y if USB_ARCH_HAS_OHCI
- default y if ARM # SL-811
-+ default y if PPC_83xx
- default PCI
-
- # many non-PCI SOC chips embed OHCI
---- gregkh-2.6.orig/drivers/usb/host/Kconfig
-+++ gregkh-2.6/drivers/usb/host/Kconfig
-@@ -6,7 +6,7 @@ comment "USB Host Controller Drivers"
-
- config USB_EHCI_HCD
- tristate "EHCI HCD (USB 2.0) support"
-- depends on USB && PCI
-+ depends on USB && (PCI || PPC_83xx)
- ---help---
- The Enhanced Host Controller Interface (EHCI) is standard for USB 2.0
- "high speed" (480 Mbit/sec, 60 Mbyte/sec) host controller hardware.
---- /dev/null
-+++ gregkh-2.6/drivers/usb/host/ehci-fsl.c
-@@ -0,0 +1,357 @@
-+/*
-+ * (C) Copyright David Brownell 2000-2002
-+ * Copyright (c) 2005 MontaVista Software
-+ *
-+ * 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.
-+ *
-+ * Ported to 834x by Randy Vinson <rvinson@mvista.com> using code provided
-+ * by Hunter Wu.
-+ */
-+
-+#include <linux/platform_device.h>
-+#include <linux/fsl_devices.h>
-+
-+#include "ehci-fsl.h"
-+
-+/* FIXME: Power Managment is un-ported so temporarily disable it */
-+#undef CONFIG_PM
-+
-+/* PCI-based HCs are common, but plenty of non-PCI HCs are used too */
-+
-+/* configure so an HC device and id are always provided */
-+/* always called with process context; sleeping is OK */
-+
-+/**
-+ * usb_hcd_fsl_probe - initialize FSL-based HCDs
-+ * @drvier: Driver to be used for this HCD
-+ * @pdev: USB Host Controller being probed
-+ * Context: !in_interrupt()
-+ *
-+ * Allocates basic resources for this USB host controller.
-+ *
-+ */
-+int usb_hcd_fsl_probe(const struct hc_driver *driver,
-+ struct platform_device *pdev)
-+{
-+ struct fsl_usb2_platform_data *pdata;
-+ struct usb_hcd *hcd;
-+ struct resource *res;
-+ int irq;
-+ int retval;
-+ unsigned int temp;
-+
-+ pr_debug("initializing FSL-SOC USB Controller\n");
-+
-+ /* Need platform data for setup */
-+ pdata = (struct fsl_usb2_platform_data *)pdev->dev.platform_data;
-+ if (!pdata) {
-+ dev_err(&pdev->dev,
-+ "No platform data for %s.\n", pdev->dev.bus_id);
-+ return -ENODEV;
-+ }
-+
-+ /*
-+ * This is a host mode driver, verify that we're supposed to be
-+ * in host mode.
-+ */
-+ if (!((pdata->operating_mode == FSL_USB2_DR_HOST) ||
-+ (pdata->operating_mode == FSL_USB2_MPH_HOST))) {
-+ dev_err(&pdev->dev,
-+ "Non Host Mode configured for %s. Wrong driver linked.\n",
-+ pdev->dev.bus_id);
-+ return -ENODEV;
-+ }
-+
-+ res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-+ if (!res) {
-+ dev_err(&pdev->dev,
-+ "Found HC with no IRQ. Check %s setup!\n",
-+ pdev->dev.bus_id);
-+ return -ENODEV;
-+ }
-+ irq = res->start;
-+
-+ hcd = usb_create_hcd(driver, &pdev->dev, pdev->dev.bus_id);
-+ if (!hcd) {
-+ retval = -ENOMEM;
-+ goto err1;
-+ }
-+
-+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+ if (!res) {
-+ dev_err(&pdev->dev,
-+ "Found HC with no register addr. Check %s setup!\n",
-+ pdev->dev.bus_id);
-+ retval = -ENODEV;
-+ goto err2;
-+ }
-+ hcd->rsrc_start = res->start;
-+ hcd->rsrc_len = res->end - res->start + 1;
-+ if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len,
-+ driver->description)) {
-+ dev_dbg(&pdev->dev, "controller already in use\n");
-+ retval = -EBUSY;
-+ goto err2;
-+ }
-+ hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
-+
-+ if (hcd->regs == NULL) {
-+ dev_dbg(&pdev->dev, "error mapping memory\n");
-+ retval = -EFAULT;
-+ goto err3;
-+ }
-+
-+ /* Enable USB controller */
-+ temp = in_be32(hcd->regs + 0x500);
-+ out_be32(hcd->regs + 0x500, temp | 0x4);
-+
-+ /* Set to Host mode */
-+ temp = in_le32(hcd->regs + 0x1a8);
-+ out_le32(hcd->regs + 0x1a8, temp | 0x3);
-+
-+ retval = usb_add_hcd(hcd, irq, SA_SHIRQ);
-+ if (retval != 0)
-+ goto err4;
-+ return retval;
-+
-+ err4:
-+ iounmap(hcd->regs);
-+ err3:
-+ release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
-+ err2:
-+ usb_put_hcd(hcd);
-+ err1:
-+ dev_err(&pdev->dev, "init %s fail, %d\n", pdev->dev.bus_id, retval);
-+ return retval;
-+}
-+
-+/* may be called without controller electrically present */
-+/* may be called with controller, bus, and devices active */
-+
-+/**
-+ * usb_hcd_fsl_remove - shutdown processing for FSL-based HCDs
-+ * @dev: USB Host Controller being removed
-+ * Context: !in_interrupt()
-+ *
-+ * Reverses the effect of usb_hcd_fsl_probe().
-+ *
-+ */
-+void usb_hcd_fsl_remove(struct usb_hcd *hcd, struct platform_device *pdev)
-+{
-+ usb_remove_hcd(hcd);
-+ iounmap(hcd->regs);
-+ release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
-+ usb_put_hcd(hcd);
-+}
-+
-+static void mpc83xx_setup_phy(struct ehci_hcd *ehci,
-+ enum fsl_usb2_phy_modes phy_mode,
-+ unsigned int port_offset)
-+{
-+ u32 portsc = readl(&ehci->regs->port_status[port_offset]);
-+ portsc &= ~PORT_PTS_MSK;
-+ switch (phy_mode) {
-+ case FSL_USB2_PHY_ULPI:
-+ portsc |= PORT_PTS_ULPI;
-+ break;
-+ case FSL_USB2_PHY_SERIAL:
-+ portsc |= PORT_PTS_SERIAL;
-+ break;
-+ case FSL_USB2_PHY_UTMI_WIDE:
-+ portsc |= PORT_PTS_PTW;
-+ /* fall through */
-+ case FSL_USB2_PHY_UTMI:
-+ portsc |= PORT_PTS_UTMI;
-+ break;
-+ case FSL_USB2_PHY_NONE:
-+ break;
-+ }
-+ writel(portsc, &ehci->regs->port_status[port_offset]);
-+}
-+
-+static void mpc83xx_usb_setup(struct usb_hcd *hcd)
-+{
-+ struct ehci_hcd *ehci = hcd_to_ehci(hcd);
-+ struct fsl_usb2_platform_data *pdata;
-+ void __iomem *non_ehci = hcd->regs;
-+
-+ pdata =
-+ (struct fsl_usb2_platform_data *)hcd->self.controller->
-+ platform_data;
-+ /* Enable PHY interface in the control reg. */
-+ out_be32(non_ehci + FSL_SOC_USB_CTRL, 0x00000004);
-+ out_be32(non_ehci + FSL_SOC_USB_SNOOP1, 0x0000001b);
-+
-+ if (pdata->operating_mode == FSL_USB2_DR_HOST)
-+ mpc83xx_setup_phy(ehci, pdata->phy_mode, 0);
-+
-+ if (pdata->operating_mode == FSL_USB2_MPH_HOST) {
-+ if (pdata->port_enables & FSL_USB2_PORT0_ENABLED)
-+ mpc83xx_setup_phy(ehci, pdata->phy_mode, 0);
-+ if (pdata->port_enables & FSL_USB2_PORT1_ENABLED)
-+ mpc83xx_setup_phy(ehci, pdata->phy_mode, 1);
-+ }
-+
-+ /* put controller in host mode. */
-+ writel(0x00000003, non_ehci + FSL_SOC_USB_USBMODE);
-+ out_be32(non_ehci + FSL_SOC_USB_PRICTRL, 0x0000000c);
-+ out_be32(non_ehci + FSL_SOC_USB_AGECNTTHRSH, 0x00000040);
-+ out_be32(non_ehci + FSL_SOC_USB_SICTRL, 0x00000001);
-+}
-+
-+/* called after powerup, by probe or system-pm "wakeup" */
-+static int ehci_fsl_reinit(struct ehci_hcd *ehci)
-+{
-+ mpc83xx_usb_setup(ehci_to_hcd(ehci));
-+ ehci_port_power(ehci, 0);
-+
-+ return 0;
-+}
-+
-+/* called during probe() after chip reset completes */
-+static int ehci_fsl_setup(struct usb_hcd *hcd)
-+{
-+ struct ehci_hcd *ehci = hcd_to_ehci(hcd);
-+ int retval;
-+
-+ /* EHCI registers start at offset 0x100 */
-+ ehci->caps = hcd->regs + 0x100;
-+ ehci->regs = hcd->regs + 0x100 +
-+ HC_LENGTH(readl(&ehci->caps->hc_capbase));
-+ dbg_hcs_params(ehci, "reset");
-+ dbg_hcc_params(ehci, "reset");
-+
-+ /* cache this readonly data; minimize chip reads */
-+ ehci->hcs_params = readl(&ehci->caps->hcs_params);
-+
-+ retval = ehci_halt(ehci);
-+ if (retval)
-+ return retval;
-+
-+ /* data structure init */
-+ retval = ehci_init(hcd);
-+ if (retval)
-+ return retval;
-+
-+ ehci->is_tdi_rh_tt = 1;
-+
-+ ehci->sbrn = 0x20;
-+
-+ ehci_reset(ehci);
-+
-+ retval = ehci_fsl_reinit(ehci);
-+ return retval;
-+}
-+
-+static const struct hc_driver ehci_fsl_hc_driver = {
-+ .description = hcd_name,
-+ .product_desc = "Freescale On-Chip EHCI Host Controller",
-+ .hcd_priv_size = sizeof(struct ehci_hcd),
-+
-+ /*
-+ * generic hardware linkage
-+ */
-+ .irq = ehci_irq,
-+ .flags = HCD_USB2,
-+
-+ /*
-+ * basic lifecycle operations
-+ */
-+ .reset = ehci_fsl_setup,
-+ .start = ehci_run,
-+#ifdef CONFIG_PM
-+ .suspend = ehci_bus_suspend,
-+ .resume = ehci_bus_resume,
-+#endif
-+ .stop = ehci_stop,
-+
-+ /*
-+ * managing i/o requests and associated device resources
-+ */
-+ .urb_enqueue = ehci_urb_enqueue,
-+ .urb_dequeue = ehci_urb_dequeue,
-+ .endpoint_disable = ehci_endpoint_disable,
-+
-+ /*
-+ * scheduling support
-+ */
-+ .get_frame_number = ehci_get_frame,
-+
-+ /*
-+ * root hub support
-+ */
-+ .hub_status_data = ehci_hub_status_data,
-+ .hub_control = ehci_hub_control,
-+ .bus_suspend = ehci_bus_suspend,
-+ .bus_resume = ehci_bus_resume,
-+};
-+
-+static int ehci_fsl_drv_probe(struct platform_device *pdev)
-+{
-+ if (usb_disabled())
-+ return -ENODEV;
-+
-+ return usb_hcd_fsl_probe(&ehci_fsl_hc_driver, pdev);
-+}
-+
-+static int ehci_fsl_drv_remove(struct platform_device *pdev)
-+{
-+ struct usb_hcd *hcd = platform_get_drvdata(pdev);
-+
-+ usb_hcd_fsl_remove(hcd, pdev);
-+
-+ return 0;
-+}
-+
-+static struct platform_driver ehci_fsl_dr_driver = {
-+ .probe = ehci_fsl_drv_probe,
-+ .remove = ehci_fsl_drv_remove,
-+ .driver = {
-+ .name = "fsl-usb2-dr",
-+ },
-+};
-+
-+static struct platform_driver ehci_fsl_mph_driver = {
-+ .probe = ehci_fsl_drv_probe,
-+ .remove = ehci_fsl_drv_remove,
-+ .driver = {
-+ .name = "fsl-usb2-mph",
-+ },
-+};
-+
-+static int __init ehci_fsl_init(void)
-+{
-+ int retval;
-+
-+ pr_debug("%s: block sizes: qh %Zd qtd %Zd itd %Zd sitd %Zd\n",
-+ hcd_name,
-+ sizeof(struct ehci_qh), sizeof(struct ehci_qtd),
-+ sizeof(struct ehci_itd), sizeof(struct ehci_sitd));
-+
-+ retval = platform_driver_register(&ehci_fsl_dr_driver);
-+ if (retval)
-+ return retval;
-+
-+ return platform_driver_register(&ehci_fsl_mph_driver);
-+}
-+
-+static void __exit ehci_fsl_cleanup(void)
-+{
-+ platform_driver_unregister(&ehci_fsl_mph_driver);
-+ platform_driver_unregister(&ehci_fsl_dr_driver);
-+}
-+
-+module_init(ehci_fsl_init);
-+module_exit(ehci_fsl_cleanup);
---- /dev/null
-+++ gregkh-2.6/drivers/usb/host/ehci-fsl.h
-@@ -0,0 +1,37 @@
-+/* Copyright (c) 2005 freescale semiconductor
-+ * Copyright (c) 2005 MontaVista Software
-+ *
-+ * 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.
-+ */
-+#ifndef _EHCI_FSL_H
-+#define _EHCI_FSL_H
-+
-+/* offsets for the non-ehci registers in the FSL SOC USB controller */
-+#define FSL_SOC_USB_ULPIVP 0x170
-+#define FSL_SOC_USB_PORTSC1 0x184
-+#define PORT_PTS_MSK (3<<30)
-+#define PORT_PTS_UTMI (0<<30)
-+#define PORT_PTS_ULPI (2<<30)
-+#define PORT_PTS_SERIAL (3<<30)
-+#define PORT_PTS_PTW (1<<28)
-+#define FSL_SOC_USB_PORTSC2 0x188
-+#define FSL_SOC_USB_USBMODE 0x1a8
-+#define FSL_SOC_USB_SNOOP1 0x400 /* NOTE: big-endian */
-+#define FSL_SOC_USB_SNOOP2 0x404 /* NOTE: big-endian */
-+#define FSL_SOC_USB_AGECNTTHRSH 0x408 /* NOTE: big-endian */
-+#define FSL_SOC_USB_SICTRL 0x40c /* NOTE: big-endian */
-+#define FSL_SOC_USB_PRICTRL 0x410 /* NOTE: big-endian */
-+#define FSL_SOC_USB_CTRL 0x500 /* NOTE: big-endian */
-+#endif /* _EHCI_FSL_H */
---- gregkh-2.6.orig/drivers/usb/host/ehci-hcd.c
-+++ gregkh-2.6/drivers/usb/host/ehci-hcd.c
-@@ -891,6 +891,12 @@ MODULE_LICENSE ("GPL");
- #include "ehci-pci.c"
- #endif
-
--#if !defined(CONFIG_PCI)
-+#ifdef CONFIG_PPC_83xx
-+#include "ehci-fsl.c"
-+#endif
-+
-+#if !(defined(CONFIG_PCI) || \
-+ defined(CONFIG_PPC_83xx) \
-+ )
- #error "missing bus glue for ehci-hcd"
- #endif
---- gregkh-2.6.orig/include/linux/fsl_devices.h
-+++ gregkh-2.6/include/linux/fsl_devices.h
-@@ -83,5 +83,32 @@ struct fsl_i2c_platform_data {
- #define FSL_I2C_DEV_SEPARATE_DFSRR 0x00000001
- #define FSL_I2C_DEV_CLOCK_5200 0x00000002
-
-+
-+enum fsl_usb2_operating_modes {
-+ FSL_USB2_MPH_HOST,
-+ FSL_USB2_DR_HOST,
-+ FSL_USB2_DR_DEVICE,
-+ FSL_USB2_DR_OTG,
-+};
-+
-+enum fsl_usb2_phy_modes {
-+ FSL_USB2_PHY_NONE,
-+ FSL_USB2_PHY_ULPI,
-+ FSL_USB2_PHY_UTMI,
-+ FSL_USB2_PHY_UTMI_WIDE,
-+ FSL_USB2_PHY_SERIAL,
-+};
-+
-+struct fsl_usb2_platform_data {
-+ /* board specific information */
-+ enum fsl_usb2_operating_modes operating_mode;
-+ enum fsl_usb2_phy_modes phy_mode;
-+ unsigned int port_enables;
-+};
-+
-+/* Flags in fsl_usb2_mph_platform_data */
-+#define FSL_USB2_PORT0_ENABLED 0x00000001
-+#define FSL_USB2_PORT1_ENABLED 0x00000002
-+
- #endif /* _FSL_DEVICE_H_ */
- #endif /* __KERNEL__ */
diff --git a/usb/usb-ehci-full-speed-iso-bugfixes.patch b/usb/usb-ehci-full-speed-iso-bugfixes.patch
deleted file mode 100644
index 5c2091449a28e..0000000000000
--- a/usb/usb-ehci-full-speed-iso-bugfixes.patch
+++ /dev/null
@@ -1,68 +0,0 @@
-From david-b@pacbell.net Fri Jan 20 17:25:14 2006
-From: Clemens Ladisch <clemens@ladisch.de>
-To: Greg KH <greg@kroah.com>
-Subject: USB: EHCI full speed ISO bugfixes
-Date: Fri, 20 Jan 2006 13:49:10 -0800
-Cc: <clemens@ladisch.de>
-Message-Id: <200601201349.10841.david-b@pacbell.net>
-
-
-This patch replaces the split ISO raw_mask calculation code in the
-iso_stream_init() function that computed incorrect numbers of high
-speed transactions for both input and output transfers.
-
-In the output case, it added a superfluous start-split transaction for
-all maxmimum packet sizes that are a multiple of 188.
-
-In the input case, it forgot to add complete-split transactions for all
-microframes covered by the full speed transaction, and the additional
-complete-split transaction needed for the case when full speed data
-starts arriving near the end of a microframe.
-
-These changes don't affect the lack of full speed bandwidth, but at
-least it removes the MMF errors that the HC raised with some input
-streams.
-
-Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
-Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-
----
- drivers/usb/host/ehci-sched.c | 11 ++++++-----
- 1 file changed, 6 insertions(+), 5 deletions(-)
-
---- gregkh-2.6.orig/drivers/usb/host/ehci-sched.c
-+++ gregkh-2.6/drivers/usb/host/ehci-sched.c
-@@ -707,6 +707,7 @@ iso_stream_init (
- } else {
- u32 addr;
- int think_time;
-+ int hs_transfers;
-
- addr = dev->ttport << 24;
- if (!ehci_is_TDI(ehci)
-@@ -719,6 +720,7 @@ iso_stream_init (
- think_time = dev->tt ? dev->tt->think_time : 0;
- stream->tt_usecs = NS_TO_US (think_time + usb_calc_bus_time (
- dev->speed, is_input, 1, maxp));
-+ hs_transfers = max (1u, (maxp + 187) / 188);
- if (is_input) {
- u32 tmp;
-
-@@ -727,12 +729,11 @@ iso_stream_init (
- stream->usecs = HS_USECS_ISO (1);
- stream->raw_mask = 1;
-
-- /* pessimistic c-mask */
-- tmp = usb_calc_bus_time (USB_SPEED_FULL, 1, 0, maxp)
-- / (125 * 1000);
-- stream->raw_mask |= 3 << (tmp + 9);
-+ /* c-mask as specified in USB 2.0 11.18.4 3.c */
-+ tmp = (1 << (hs_transfers + 2)) - 1;
-+ stream->raw_mask |= tmp << (8 + 2);
- } else
-- stream->raw_mask = smask_out [maxp / 188];
-+ stream->raw_mask = smask_out [hs_transfers - 1];
- bandwidth = stream->usecs + stream->c_usecs;
- bandwidth /= 1 << (interval + 2);
-
diff --git a/usb/usb-ehci-unlink-tweaks.patch b/usb/usb-ehci-unlink-tweaks.patch
deleted file mode 100644
index ea676fd543258..0000000000000
--- a/usb/usb-ehci-unlink-tweaks.patch
+++ /dev/null
@@ -1,44 +0,0 @@
-From david-b@pacbell.net Fri Jan 20 17:25:17 2006
-From: David Brownell <david-b@pacbell.net>
-To: Greg KH <greg@kroah.com>
-Subject: USB: EHCI unlink tweaks
-Date: Fri, 20 Jan 2006 14:35:55 -0800
-Message-Id: <200601201435.56129.david-b@pacbell.net>
-
-This patch modifies the behavior of the EHCI driver in an unlink path
-that seems to be causing various issues on some systems. Those problems
-have included issues with disconnection, driver unbinding, and similar
-cases where urb unlinking would just not work right.
-
-This patch should help avoid those problems by not turning off the async
-(control/bulk) schedule until it's not expecting an "async advance" IRQ,
-which comes from the processing passing the schedule head. Whether the
-driver attempts to do such things is dependent on system timings, so
-many folk would never have seen these problems.
-
-Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-
----
- drivers/usb/host/ehci-q.c | 6 ++++--
- 1 file changed, 4 insertions(+), 2 deletions(-)
-
---- gregkh-2.6.orig/drivers/usb/host/ehci-q.c
-+++ gregkh-2.6/drivers/usb/host/ehci-q.c
-@@ -1022,12 +1022,14 @@ static void start_unlink_async (struct e
- /* stop async schedule right now? */
- if (unlikely (qh == ehci->async)) {
- /* can't get here without STS_ASS set */
-- if (ehci_to_hcd(ehci)->state != HC_STATE_HALT) {
-+ if (ehci_to_hcd(ehci)->state != HC_STATE_HALT
-+ && !ehci->reclaim) {
-+ /* ... and CMD_IAAD clear */
- writel (cmd & ~CMD_ASE, &ehci->regs->command);
- wmb ();
- // handshake later, if we need to
-+ timer_action_done (ehci, TIMER_ASYNC_OFF);
- }
-- timer_action_done (ehci, TIMER_ASYNC_OFF);
- return;
- }
-
diff --git a/usb/usb-et61x51-driver-updates.patch b/usb/usb-et61x51-driver-updates.patch
deleted file mode 100644
index 27d200d631932..0000000000000
--- a/usb/usb-et61x51-driver-updates.patch
+++ /dev/null
@@ -1,1211 +0,0 @@
-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.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_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_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-ethernet-gadget-driver-section-fixups.patch b/usb/usb-ethernet-gadget-driver-section-fixups.patch
deleted file mode 100644
index a4e78ff61afd0..0000000000000
--- a/usb/usb-ethernet-gadget-driver-section-fixups.patch
+++ /dev/null
@@ -1,145 +0,0 @@
-From david-b@pacbell.net Sat Feb 18 12:51:14 2006
-From: David Brownell <david-b@pacbell.net>
-To: Greg KH <gregkh@suse.de>
-Subject: USB: ethernet gadget driver section fixups
-Date: Sat, 18 Feb 2006 12:31:23 -0800
-Cc: Aras Vaichas <arasv@magellan-technology.com>
-Message-Id: <200602181231.23445.david-b@pacbell.net>
-
-From: Aras Vaichas <arasv@magellan-technology.com>
-
-This patch allows you to set the iSerialNumber field in the
-usb_device_descriptor structure for your USB ethernet gadget.
-
-It also changes the parameters shown through sysfs so they're
-no longer declared as __initdata, preventing potential oopses.
-
-That's most useful for the Ethernet addresses, which may in
-some cases be random "locally administered" addresses.
-
-Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-
----
- drivers/usb/gadget/ether.c | 38 +++++++++++++++++++++++++++-----------
- 1 file changed, 27 insertions(+), 11 deletions(-)
-
---- gregkh-2.6.orig/drivers/usb/gadget/ether.c
-+++ gregkh-2.6/drivers/usb/gadget/ether.c
-@@ -182,33 +182,37 @@ struct eth_dev {
- * parameters are in UTF-8 (superset of ASCII's 7 bit characters).
- */
-
--static ushort __initdata idVendor;
-+static ushort idVendor;
- module_param(idVendor, ushort, S_IRUGO);
- MODULE_PARM_DESC(idVendor, "USB Vendor ID");
-
--static ushort __initdata idProduct;
-+static ushort idProduct;
- module_param(idProduct, ushort, S_IRUGO);
- MODULE_PARM_DESC(idProduct, "USB Product ID");
-
--static ushort __initdata bcdDevice;
-+static ushort bcdDevice;
- module_param(bcdDevice, ushort, S_IRUGO);
- MODULE_PARM_DESC(bcdDevice, "USB Device version (BCD)");
-
--static char *__initdata iManufacturer;
-+static char *iManufacturer;
- module_param(iManufacturer, charp, S_IRUGO);
- MODULE_PARM_DESC(iManufacturer, "USB Manufacturer string");
-
--static char *__initdata iProduct;
-+static char *iProduct;
- module_param(iProduct, charp, S_IRUGO);
- MODULE_PARM_DESC(iProduct, "USB Product string");
-
-+static char *iSerialNumber;
-+module_param(iSerialNumber, charp, S_IRUGO);
-+MODULE_PARM_DESC(iSerialNumber, "SerialNumber");
-+
- /* initial value, changed by "ifconfig usb0 hw ether xx:xx:xx:xx:xx:xx" */
--static char *__initdata dev_addr;
-+static char *dev_addr;
- module_param(dev_addr, charp, S_IRUGO);
- MODULE_PARM_DESC(dev_addr, "Device Ethernet Address");
-
- /* this address is invisible to ifconfig */
--static char *__initdata host_addr;
-+static char *host_addr;
- module_param(host_addr, charp, S_IRUGO);
- MODULE_PARM_DESC(host_addr, "Host Ethernet Address");
-
-@@ -403,6 +407,7 @@ static inline int BITRATE(struct usb_gad
- #define STRING_CDC 7
- #define STRING_SUBSET 8
- #define STRING_RNDIS 9
-+#define STRING_SERIALNUMBER 10
-
- /* holds our biggest descriptor (or RNDIS response) */
- #define USB_BUFSIZ 256
-@@ -870,6 +875,7 @@ static inline void __init hs_subset_desc
-
- static char manufacturer [50];
- static char product_desc [40] = DRIVER_DESC;
-+static char serial_number [20];
-
- #ifdef DEV_CONFIG_CDC
- /* address that the host will use ... usually assigned at random */
-@@ -880,6 +886,7 @@ static char ethaddr [2 * ETH_ALEN + 1
- static struct usb_string strings [] = {
- { STRING_MANUFACTURER, manufacturer, },
- { STRING_PRODUCT, product_desc, },
-+ { STRING_SERIALNUMBER, serial_number, },
- { STRING_DATA, "Ethernet Data", },
- #ifdef DEV_CONFIG_CDC
- { STRING_CDC, "CDC Ethernet", },
-@@ -2162,7 +2169,7 @@ static u8 __init nibble (unsigned char c
- return 0;
- }
-
--static void __init get_ether_addr (const char *str, u8 *dev_addr)
-+static int __init get_ether_addr(const char *str, u8 *dev_addr)
- {
- if (str) {
- unsigned i;
-@@ -2177,9 +2184,10 @@ static void __init get_ether_addr (const
- dev_addr [i] = num;
- }
- if (is_valid_ether_addr (dev_addr))
-- return;
-+ return 0;
- }
- random_ether_addr(dev_addr);
-+ return 1;
- }
-
- static int __init
-@@ -2277,6 +2285,10 @@ eth_bind (struct usb_gadget *gadget)
- strlcpy (manufacturer, iManufacturer, sizeof manufacturer);
- if (iProduct)
- strlcpy (product_desc, iProduct, sizeof product_desc);
-+ if (iSerialNumber) {
-+ device_desc.iSerialNumber = STRING_SERIALNUMBER,
-+ strlcpy(serial_number, iSerialNumber, sizeof serial_number);
-+ }
-
- /* all we really need is bulk IN/OUT */
- usb_ep_autoconfig_reset (gadget);
-@@ -2386,9 +2398,13 @@ autoconf_fail:
- * The host side address is used with CDC and RNDIS, and commonly
- * ends up in a persistent config database.
- */
-- get_ether_addr(dev_addr, net->dev_addr);
-+ if (get_ether_addr(dev_addr, net->dev_addr))
-+ dev_warn(&gadget->dev,
-+ "using random %s ethernet address\n", "self");
- if (cdc || rndis) {
-- get_ether_addr(host_addr, dev->host_mac);
-+ if (get_ether_addr(host_addr, dev->host_mac))
-+ dev_warn(&gadget->dev,
-+ "using random %s ethernet address\n", "host");
- #ifdef DEV_CONFIG_CDC
- snprintf (ethaddr, sizeof ethaddr, "%02X%02X%02X%02X%02X%02X",
- dev->host_mac [0], dev->host_mac [1],
diff --git a/usb/usb-fix-check_ctrlrecip-to-allow-control-transfers-in-state-address.patch b/usb/usb-fix-check_ctrlrecip-to-allow-control-transfers-in-state-address.patch
deleted file mode 100644
index 91a2942744afd..0000000000000
--- a/usb/usb-fix-check_ctrlrecip-to-allow-control-transfers-in-state-address.patch
+++ /dev/null
@@ -1,41 +0,0 @@
-From akpm@osdl.org Sat Mar 11 00:19:34 2006
-Message-Id: <200603110819.k2B8J2q3023867@shell0.pdx.osdl.net>
-From: Horst Schirmeier <horst@schirmeier.com>
-Subject: USB: fix check_ctrlrecip to allow control transfers in state ADDRESS
-To: horst@schirmeier.com, david-b@pacbell.net, greg@kroah.com,
- stern@rowland.harvard.edu, mm-commits@vger.kernel.org
-Date: Sat, 11 Mar 2006 00:16:55 -0800
-
-
-From: Horst Schirmeier <horst@schirmeier.com>
-
-check_ctrlrecip() disallows any control transfers if the device is
-deconfigured (in configuration 0, ie. state ADDRESS). This for example
-makes it impossible to read the device descriptors without configuring the
-device, although most standard device requests are allowed in this state by
-the spec. This patch allows control transfers for the ADDRESS state, too.
-
-Signed-off-by: Horst Schirmeier <horst@schirmeier.com>
-Cc: Alan Stern <stern@rowland.harvard.edu>
-Cc: David Brownell <david-b@pacbell.net>
-Signed-off-by: Andrew Morton <akpm@osdl.org>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
----
-
-
----
- drivers/usb/core/devio.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
---- gregkh-2.6.orig/drivers/usb/core/devio.c
-+++ gregkh-2.6/drivers/usb/core/devio.c
-@@ -493,7 +493,8 @@ static int check_ctrlrecip(struct dev_st
- {
- int ret = 0;
-
-- if (ps->dev->state != USB_STATE_CONFIGURED)
-+ if (ps->dev->state != USB_STATE_ADDRESS
-+ && ps->dev->state != USB_STATE_CONFIGURED)
- return -EHOSTUNREACH;
- if (USB_TYPE_VENDOR == (USB_TYPE_MASK & requesttype))
- return 0;
diff --git a/usb/usb-fix-irda-usb-use-after-use.patch b/usb/usb-fix-irda-usb-use-after-use.patch
deleted file mode 100644
index 68dd9debca1eb..0000000000000
--- a/usb/usb-fix-irda-usb-use-after-use.patch
+++ /dev/null
@@ -1,47 +0,0 @@
-From akpm@osdl.org Wed Mar 15 14:55:13 2006
-Message-Id: <200603152255.k2FMt0sE006736@shell0.pdx.osdl.net>
-From: Eugene Teo <eugene.teo@eugeneteo.net>
-Subject: USB: Fix irda-usb use after use
-To: eugene.teo@eugeneteo.net, davem@davemloft.net, greg@kroah.com
-Date: Wed, 15 Mar 2006 14:57:19 -0800
-
-From: Eugene Teo <eugene.teo@eugeneteo.net>
-
-Don't read from free'd memory after calling netif_rx(). docopy is used as
-a boolean (0 and 1) so unsigned int is sufficient.
-
-Coverity bug #928
-
-Signed-off-by: Eugene Teo <eugene.teo@eugeneteo.net>
-Cc: "David S. Miller" <davem@davemloft.net>
-Signed-off-by: Andrew Morton <akpm@osdl.org>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
----
-
- drivers/net/irda/irda-usb.c | 5 +++--
- 1 file changed, 3 insertions(+), 2 deletions(-)
-
---- gregkh-2.6.orig/drivers/net/irda/irda-usb.c
-+++ gregkh-2.6/drivers/net/irda/irda-usb.c
-@@ -740,7 +740,7 @@ static void irda_usb_receive(struct urb
- struct sk_buff *newskb;
- struct sk_buff *dataskb;
- struct urb *next_urb;
-- int docopy;
-+ unsigned int len, docopy;
-
- IRDA_DEBUG(2, "%s(), len=%d\n", __FUNCTION__, urb->actual_length);
-
-@@ -851,10 +851,11 @@ static void irda_usb_receive(struct urb
- dataskb->dev = self->netdev;
- dataskb->mac.raw = dataskb->data;
- dataskb->protocol = htons(ETH_P_IRDA);
-+ len = dataskb->len;
- netif_rx(dataskb);
-
- /* Keep stats up to date */
-- self->stats.rx_bytes += dataskb->len;
-+ self->stats.rx_bytes += len;
- self->stats.rx_packets++;
- self->netdev->last_rx = jiffies;
-
diff --git a/usb/usb-fix-masking-bug-initialization-of-freescale-ehci-controller.patch b/usb/usb-fix-masking-bug-initialization-of-freescale-ehci-controller.patch
deleted file mode 100644
index 39e777d5c9bde..0000000000000
--- a/usb/usb-fix-masking-bug-initialization-of-freescale-ehci-controller.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From linux-usb-devel-admin@lists.sourceforge.net Tue Jan 24 08:41:21 2006
-From: Kumar Gala <galak@kernel.crashing.org>
-To: linux-usb-devel@lists.sourceforge.net
-Subject: USB: Fix masking bug initialization of Freescale EHCI controller
-Cc: Kumar Gala <galak@gate.crashing.org>, dbrownell@users.sourceforge.net, Randy Vinson <rvinson@mvista.com>
-Content-Disposition: inline
-Message-Id: <200601240811.27539.david-b@pacbell.net>
-Date: Tue, 24 Jan 2006 08:11:27 -0800
-
-In setting up the of PHY we masked off too many bits, instead just
-initialize PORTSC for the type of PHY we are using.
-
-Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
-Acked-by: David Brownell <dbrownell@users.sourceforge.net>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-
----
- drivers/usb/host/ehci-fsl.c | 3 +--
- 1 file changed, 1 insertion(+), 2 deletions(-)
-
---- gregkh-2.6.orig/drivers/usb/host/ehci-fsl.c
-+++ gregkh-2.6/drivers/usb/host/ehci-fsl.c
-@@ -160,8 +160,7 @@ static void mpc83xx_setup_phy(struct ehc
- enum fsl_usb2_phy_modes phy_mode,
- unsigned int port_offset)
- {
-- u32 portsc = readl(&ehci->regs->port_status[port_offset]);
-- portsc &= ~PORT_PTS_MSK;
-+ u32 portsc = 0;
- switch (phy_mode) {
- case FSL_USB2_PHY_ULPI:
- portsc |= PORT_PTS_ULPI;
diff --git a/usb/usb-fix-warning-in-drivers-usb-media-ov511.c.patch b/usb/usb-fix-warning-in-drivers-usb-media-ov511.c.patch
deleted file mode 100644
index 176062ebd0ac7..0000000000000
--- a/usb/usb-fix-warning-in-drivers-usb-media-ov511.c.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-From kernel-janitors-bounces@lists.osdl.org Wed Feb 15 13:45:49 2006
-From: Matthew Martin <lihnucks@gmail.com>
-To: kernel-janitors@lists.osdl.org
-Date: Wed, 15 Feb 2006 15:41:25 -0600
-Message-Id: <1140039685.14352.1.camel@localhost.localdomain>
-Subject: USB: Fix warning in drivers/usb/media/ov511.c
-
-Gcc 4.0.2 had the warning:
-
-drivers/usb/media/ov511.c: In function 'show_exposure':
-drivers/usb/media/ov511.c:5642: warning: 'exp' may be used uninitialized
-in this function
-
-Here is the patch to fix that warning.
-
-Signed-off-by: Matthew Martin <lihnucks@gmail.com>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-
----
- drivers/usb/media/ov511.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- gregkh-2.6.orig/drivers/usb/media/ov511.c
-+++ gregkh-2.6/drivers/usb/media/ov511.c
-@@ -5639,7 +5639,7 @@ static CLASS_DEVICE_ATTR(hue, S_IRUGO, s
- static ssize_t show_exposure(struct class_device *cd, char *buf)
- {
- struct usb_ov511 *ov = cd_to_ov(cd);
-- unsigned char exp;
-+ unsigned char exp = 0;
-
- if (!ov->dev)
- return -ENODEV;
diff --git a/usb/usb-ftdi_sio-add-icom-id1-usb-product-and-vendor-ids.patch b/usb/usb-ftdi_sio-add-icom-id1-usb-product-and-vendor-ids.patch
deleted file mode 100644
index 68a4802b110d3..0000000000000
--- a/usb/usb-ftdi_sio-add-icom-id1-usb-product-and-vendor-ids.patch
+++ /dev/null
@@ -1,50 +0,0 @@
-From bottoms@airborne.nrl.navy.mil Tue Mar 14 15:44:28 2006
-Message-ID: <17431.21847.295167.980061@airborne.nrl.navy.mil>
-Date: Tue, 14 Mar 2006 18:44:23 -0500
-From: "A. Maitland Bottoms" <bottoms@debian.org>
-To: Greg KH <greg@kroah.com>, Bill Ryder <bryder@sgi.com>,
- Kuba Ober <kuba@mareimbrium.org>
-Cc: Vojtech Pavlik <vojtech@suse.cz>
-Subject: USB: ftdi_sio: add Icom ID1 USB product and vendor ids
-
-From: "A. Maitland Bottoms" <bottoms@debian.org>
-
-The Icom ID-1 1.2 GHz band digital transceiver is a new radio
-that has a USB interface. With this patch, the ftdi_sio driver
-will report "Detected FT8U232AM" and provide a serial device
-interface.
-
-Signed-off-by: "A. Maitland Bottoms" <bottoms@debian.org>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-
----
- drivers/usb/serial/ftdi_sio.c | 1 +
- drivers/usb/serial/ftdi_sio.h | 7 +++++++
- 2 files changed, 8 insertions(+)
-
---- gregkh-2.6.orig/drivers/usb/serial/ftdi_sio.c
-+++ gregkh-2.6/drivers/usb/serial/ftdi_sio.c
-@@ -492,6 +492,7 @@ static struct usb_device_id id_table_com
- { USB_DEVICE(FTDI_VID, FTDI_WESTREX_MODEL_777_PID) },
- { USB_DEVICE(FTDI_VID, FTDI_WESTREX_MODEL_8900F_PID) },
- { USB_DEVICE(FTDI_VID, FTDI_PCDJ_DAC2_PID) },
-+ { USB_DEVICE(ICOM_ID1_VID, ICOM_ID1_PID) },
- { }, /* Optional parameter entry */
- { } /* Terminating entry */
- };
---- gregkh-2.6.orig/drivers/usb/serial/ftdi_sio.h
-+++ gregkh-2.6/drivers/usb/serial/ftdi_sio.h
-@@ -146,6 +146,13 @@
- #define KOBIL_CONV_KAAN_PID 0x2021 /* KOBIL_Konverter for KAAN */
-
- /*
-+ * Icom ID-1 digital transceiver
-+ */
-+
-+#define ICOM_ID1_VID 0x0C26
-+#define ICOM_ID1_PID 0x0004
-+
-+/*
- * DSS-20 Sync Station for Sony Ericsson P800
- */
-
diff --git a/usb/usb-gadget-driver-section-fixups.patch b/usb/usb-gadget-driver-section-fixups.patch
deleted file mode 100644
index 82ea27ecd63cb..0000000000000
--- a/usb/usb-gadget-driver-section-fixups.patch
+++ /dev/null
@@ -1,147 +0,0 @@
-From david-b@pacbell.net Sat Feb 18 12:51:14 2006
-From: David Brownell <david-b@pacbell.net>
-To: Greg KH <gregkh@suse.de>
-Subject: USB: gadget driver section fixups
-Date: Sat, 18 Feb 2006 12:31:05 -0800
-Message-Id: <200602181231.05193.david-b@pacbell.net>
-
-
-This adds __init section annotations to gadget driver bind() routines to
-remove calls from .text into .init sections (for endpoint autoconfig).
-Likewise it adds __exit section annotations to their unbind() routines.
-
-The specification of the gadget driver register/unregister functions is
-updated to explicitly allow use of those sections.
-
-Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-
----
- drivers/usb/gadget/ether.c | 4 ++--
- drivers/usb/gadget/file_storage.c | 4 ++--
- drivers/usb/gadget/serial.c | 6 +++---
- drivers/usb/gadget/zero.c | 6 +++---
- include/linux/usb_gadget.h | 7 +++++--
- 5 files changed, 15 insertions(+), 12 deletions(-)
-
---- gregkh-2.6.orig/drivers/usb/gadget/ether.c
-+++ gregkh-2.6/drivers/usb/gadget/ether.c
-@@ -2125,7 +2125,7 @@ eth_req_free (struct usb_ep *ep, struct
- }
-
-
--static void
-+static void __exit
- eth_unbind (struct usb_gadget *gadget)
- {
- struct eth_dev *dev = get_gadget_data (gadget);
-@@ -2532,7 +2532,7 @@ static struct usb_gadget_driver eth_driv
-
- .function = (char *) driver_desc,
- .bind = eth_bind,
-- .unbind = eth_unbind,
-+ .unbind = __exit_p(eth_unbind),
-
- .setup = eth_setup,
- .disconnect = eth_disconnect,
---- gregkh-2.6.orig/drivers/usb/gadget/file_storage.c
-+++ gregkh-2.6/drivers/usb/gadget/file_storage.c
-@@ -3678,7 +3678,7 @@ static void lun_release(struct device *d
- kref_put(&fsg->ref, fsg_release);
- }
-
--static void fsg_unbind(struct usb_gadget *gadget)
-+static void __exit fsg_unbind(struct usb_gadget *gadget)
- {
- struct fsg_dev *fsg = get_gadget_data(gadget);
- int i;
-@@ -4064,7 +4064,7 @@ static struct usb_gadget_driver fsg_dri
- #endif
- .function = (char *) longname,
- .bind = fsg_bind,
-- .unbind = fsg_unbind,
-+ .unbind = __exit_p(fsg_unbind),
- .disconnect = fsg_disconnect,
- .setup = fsg_setup,
- .suspend = fsg_suspend,
---- gregkh-2.6.orig/drivers/usb/gadget/serial.c
-+++ gregkh-2.6/drivers/usb/gadget/serial.c
-@@ -369,7 +369,7 @@ static struct usb_gadget_driver gs_gadge
- #endif /* CONFIG_USB_GADGET_DUALSPEED */
- .function = GS_LONG_NAME,
- .bind = gs_bind,
-- .unbind = gs_unbind,
-+ .unbind = __exit_p(gs_unbind),
- .setup = gs_setup,
- .disconnect = gs_disconnect,
- .driver = {
-@@ -1413,7 +1413,7 @@ requeue:
- * Called on module load. Allocates and initializes the device
- * structure and a control request.
- */
--static int gs_bind(struct usb_gadget *gadget)
-+static int __init gs_bind(struct usb_gadget *gadget)
- {
- int ret;
- struct usb_ep *ep;
-@@ -1538,7 +1538,7 @@ autoconf_fail:
- * Called on module unload. Frees the control request and device
- * structure.
- */
--static void gs_unbind(struct usb_gadget *gadget)
-+static void __exit gs_unbind(struct usb_gadget *gadget)
- {
- struct gs_dev *dev = get_gadget_data(gadget);
-
---- gregkh-2.6.orig/drivers/usb/gadget/zero.c
-+++ gregkh-2.6/drivers/usb/gadget/zero.c
-@@ -1119,7 +1119,7 @@ zero_autoresume (unsigned long _dev)
-
- /*-------------------------------------------------------------------------*/
-
--static void
-+static void __exit
- zero_unbind (struct usb_gadget *gadget)
- {
- struct zero_dev *dev = get_gadget_data (gadget);
-@@ -1136,7 +1136,7 @@ zero_unbind (struct usb_gadget *gadget)
- set_gadget_data (gadget, NULL);
- }
-
--static int
-+static int __init
- zero_bind (struct usb_gadget *gadget)
- {
- struct zero_dev *dev;
-@@ -1288,7 +1288,7 @@ static struct usb_gadget_driver zero_dri
- #endif
- .function = (char *) longname,
- .bind = zero_bind,
-- .unbind = zero_unbind,
-+ .unbind = __exit_p(zero_unbind),
-
- .setup = zero_setup,
- .disconnect = zero_disconnect,
---- gregkh-2.6.orig/include/linux/usb_gadget.h
-+++ gregkh-2.6/include/linux/usb_gadget.h
-@@ -801,7 +801,9 @@ struct usb_gadget_driver {
- * Call this in your gadget driver's module initialization function,
- * to tell the underlying usb controller driver about your driver.
- * The driver's bind() function will be called to bind it to a
-- * gadget. This function must be called in a context that can sleep.
-+ * gadget before this registration call returns. It's expected that
-+ * the bind() functions will be in init sections.
-+ * This function must be called in a context that can sleep.
- */
- int usb_gadget_register_driver (struct usb_gadget_driver *driver);
-
-@@ -814,7 +816,8 @@ int usb_gadget_register_driver (struct u
- * going away. If the controller is connected to a USB host,
- * it will first disconnect(). The driver is also requested
- * to unbind() and clean up any device state, before this procedure
-- * finally returns.
-+ * finally returns. It's expected that the unbind() functions
-+ * will in in exit sections, so may not be linked in some kernels.
- * This function must be called in a context that can sleep.
- */
- int usb_gadget_unregister_driver (struct usb_gadget_driver *driver);
diff --git a/usb/usb-initdata-fixes.patch b/usb/usb-initdata-fixes.patch
deleted file mode 100644
index e02037ee9504b..0000000000000
--- a/usb/usb-initdata-fixes.patch
+++ /dev/null
@@ -1,24 +0,0 @@
-From: Greg Kroah-Hartman <gregkh@suse.de>
-Subject: USB: fix initdata issue in isp116x-hcd
-
-As found by Sam's scripts.
-
-Cc: Sam Ravnborg <sam@ravnborg.org>
-Cc: David Brownell <david-b@pacbell.net>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-
----
- drivers/usb/host/isp116x-hcd.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- gregkh-2.6.orig/drivers/usb/host/isp116x-hcd.c
-+++ gregkh-2.6/drivers/usb/host/isp116x-hcd.c
-@@ -1552,7 +1552,7 @@ static struct hc_driver isp116x_hc_drive
-
- /*----------------------------------------------------------------*/
-
--static int __init_or_module isp116x_remove(struct platform_device *pdev)
-+static int isp116x_remove(struct platform_device *pdev)
- {
- struct usb_hcd *hcd = platform_get_drvdata(pdev);
- struct isp116x *isp116x;
diff --git a/usb/usb-kzalloc-conversion-for-rest-of-drivers-usb.patch b/usb/usb-kzalloc-conversion-for-rest-of-drivers-usb.patch
deleted file mode 100644
index 4691e5d8f105b..0000000000000
--- a/usb/usb-kzalloc-conversion-for-rest-of-drivers-usb.patch
+++ /dev/null
@@ -1,690 +0,0 @@
-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
deleted file mode 100644
index e5d034766505f..0000000000000
--- a/usb/usb-kzalloc-conversion-in-drivers-usb-gadget.patch
+++ /dev/null
@@ -1,186 +0,0 @@
-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-kzalloc-for-hid.patch b/usb/usb-kzalloc-for-hid.patch
deleted file mode 100644
index 3e38e45f75821..0000000000000
--- a/usb/usb-kzalloc-for-hid.patch
+++ /dev/null
@@ -1,150 +0,0 @@
-From linux-usb-devel-admin@lists.sourceforge.net Fri Jan 6 12:50:01 2006
-From: Oliver Neukum <oliver@neukum.org>
-To: Michael Haboustak <mike-@cinci.rr.com>, Greg KH <gregkh@suse.de>, Vojtech Pavlik <vojtech@suse.cz>, dtor_core@ameritech.net
-Content-Disposition: inline
-Message-Id: <200601062054.30226.oliver@neukum.org>
-Subject: USB: kzalloc for hid
-Date: Fri, 6 Jan 2006 20:54:29 +0100
-
-this uses kzalloc in hid.
-
-Signed-off-by: Oliver Neukum <oliver@neukum.name>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-
----
- drivers/usb/input/hid-core.c | 18 +++++-------------
- drivers/usb/input/hid-lgff.c | 6 ++----
- drivers/usb/input/hid-tmff.c | 3 +--
- drivers/usb/input/hiddev.c | 6 ++----
- 4 files changed, 10 insertions(+), 23 deletions(-)
-
---- gregkh-2.6.orig/drivers/usb/input/hid-core.c
-+++ gregkh-2.6/drivers/usb/input/hid-core.c
-@@ -66,9 +66,8 @@ static struct hid_report *hid_register_r
- if (report_enum->report_id_hash[id])
- return report_enum->report_id_hash[id];
-
-- if (!(report = kmalloc(sizeof(struct hid_report), GFP_KERNEL)))
-+ if (!(report = kzalloc(sizeof(struct hid_report), GFP_KERNEL)))
- return NULL;
-- memset(report, 0, sizeof(struct hid_report));
-
- if (id != 0)
- report_enum->numbered = 1;
-@@ -97,12 +96,9 @@ static struct hid_field *hid_register_fi
- return NULL;
- }
-
-- if (!(field = kmalloc(sizeof(struct hid_field) + usages * sizeof(struct hid_usage)
-+ if (!(field = kzalloc(sizeof(struct hid_field) + usages * sizeof(struct hid_usage)
- + values * sizeof(unsigned), GFP_KERNEL))) return NULL;
-
-- memset(field, 0, sizeof(struct hid_field) + usages * sizeof(struct hid_usage)
-- + values * sizeof(unsigned));
--
- field->index = report->maxfield++;
- report->field[field->index] = field;
- field->usage = (struct hid_usage *)(field + 1);
-@@ -651,17 +647,14 @@ static struct hid_device *hid_parse_repo
- hid_parser_reserved
- };
-
-- if (!(device = kmalloc(sizeof(struct hid_device), GFP_KERNEL)))
-+ if (!(device = kzalloc(sizeof(struct hid_device), GFP_KERNEL)))
- return NULL;
-- memset(device, 0, sizeof(struct hid_device));
-
-- if (!(device->collection = kmalloc(sizeof(struct hid_collection) *
-+ if (!(device->collection = kzalloc(sizeof(struct hid_collection) *
- HID_DEFAULT_NUM_COLLECTIONS, GFP_KERNEL))) {
- kfree(device);
- return NULL;
- }
-- memset(device->collection, 0, sizeof(struct hid_collection) *
-- HID_DEFAULT_NUM_COLLECTIONS);
- device->collection_size = HID_DEFAULT_NUM_COLLECTIONS;
-
- for (i = 0; i < HID_REPORT_TYPES; i++)
-@@ -675,13 +668,12 @@ static struct hid_device *hid_parse_repo
- memcpy(device->rdesc, start, size);
- device->rsize = size;
-
-- if (!(parser = kmalloc(sizeof(struct hid_parser), GFP_KERNEL))) {
-+ if (!(parser = kzalloc(sizeof(struct hid_parser), GFP_KERNEL))) {
- kfree(device->rdesc);
- kfree(device->collection);
- kfree(device);
- return NULL;
- }
-- memset(parser, 0, sizeof(struct hid_parser));
- parser->device = device;
-
- end = start + size;
---- gregkh-2.6.orig/drivers/usb/input/hid-lgff.c
-+++ gregkh-2.6/drivers/usb/input/hid-lgff.c
-@@ -154,10 +154,9 @@ int hid_lgff_init(struct hid_device* hid
- return -1;
- }
-
-- private = kmalloc(sizeof(struct lgff_device), GFP_KERNEL);
-+ private = kzalloc(sizeof(struct lgff_device), GFP_KERNEL);
- if (!private)
- return -1;
-- memset(private, 0, sizeof(struct lgff_device));
- hid->ff_private = private;
-
- /* Input init */
-@@ -228,13 +227,12 @@ static struct hid_report* hid_lgff_dupli
- }
- *ret->field[0] = *report->field[0];
-
-- ret->field[0]->value = kmalloc(sizeof(s32[8]), GFP_KERNEL);
-+ ret->field[0]->value = kzalloc(sizeof(s32[8]), GFP_KERNEL);
- if (!ret->field[0]->value) {
- kfree(ret->field[0]);
- kfree(ret);
- return NULL;
- }
-- memset(ret->field[0]->value, 0, sizeof(s32[8]));
-
- return ret;
- }
---- gregkh-2.6.orig/drivers/usb/input/hid-tmff.c
-+++ gregkh-2.6/drivers/usb/input/hid-tmff.c
-@@ -113,11 +113,10 @@ int hid_tmff_init(struct hid_device *hid
- struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list);
- struct input_dev *input_dev = hidinput->input;
-
-- private = kmalloc(sizeof(struct tmff_device), GFP_KERNEL);
-+ private = kzalloc(sizeof(struct tmff_device), GFP_KERNEL);
- if (!private)
- return -ENOMEM;
-
-- memset(private, 0, sizeof(struct tmff_device));
- hid->ff_private = private;
-
- /* Find the report to use */
---- gregkh-2.6.orig/drivers/usb/input/hiddev.c
-+++ gregkh-2.6/drivers/usb/input/hiddev.c
-@@ -257,9 +257,8 @@ static int hiddev_open(struct inode * in
- if (i >= HIDDEV_MINORS || !hiddev_table[i])
- return -ENODEV;
-
-- if (!(list = kmalloc(sizeof(struct hiddev_list), GFP_KERNEL)))
-+ if (!(list = kzalloc(sizeof(struct hiddev_list), GFP_KERNEL)))
- return -ENOMEM;
-- memset(list, 0, sizeof(struct hiddev_list));
-
- list->hiddev = hiddev_table[i];
- list->next = hiddev_table[i]->list;
-@@ -754,9 +753,8 @@ int hiddev_connect(struct hid_device *hi
- if (i == hid->maxcollection && (hid->quirks & HID_QUIRK_HIDDEV) == 0)
- return -1;
-
-- if (!(hiddev = kmalloc(sizeof(struct hiddev), GFP_KERNEL)))
-+ if (!(hiddev = kzalloc(sizeof(struct hiddev), GFP_KERNEL)))
- return -1;
-- memset(hiddev, 0, sizeof(struct hiddev));
-
- retval = usb_register_dev(hid->intf, &hiddev_class);
- if (retval) {
diff --git a/usb/usb-kzalloc-for-storage.patch b/usb/usb-kzalloc-for-storage.patch
deleted file mode 100644
index e68e2afe52e2e..0000000000000
--- a/usb/usb-kzalloc-for-storage.patch
+++ /dev/null
@@ -1,112 +0,0 @@
-From oliver@neukum.org Sun Jan 8 03:34:01 2006
-From: Oliver Neukum <oliver@neukum.org>
-To: mdharm-usb@one-eyed-alien.net, usb-storage@lists.one-eyed-alien.net, Greg KH <gregkh@suse.de>
-Subject: USB: kzalloc for storage
-Content-Disposition: inline
-Date: Sun, 8 Jan 2006 12:33:45 +0100
-Message-Id: <200601081233.45552.oliver@neukum.org>
-
-another one for kzalloc. This covers the storage subdirectory.
-
-Signed-off-by: Oliver Neukum <oliver@neukum.name>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-
----
- drivers/usb/storage/datafab.c | 3 +--
- drivers/usb/storage/isd200.c | 8 +++-----
- drivers/usb/storage/jumpshot.c | 3 +--
- drivers/usb/storage/sddr55.c | 3 +--
- drivers/usb/storage/shuttle_usbat.c | 3 +--
- 5 files changed, 7 insertions(+), 13 deletions(-)
-
---- gregkh-2.6.orig/drivers/usb/storage/datafab.c
-+++ gregkh-2.6/drivers/usb/storage/datafab.c
-@@ -512,13 +512,12 @@ int datafab_transport(struct scsi_cmnd *
- };
-
- if (!us->extra) {
-- us->extra = kmalloc(sizeof(struct datafab_info), GFP_NOIO);
-+ us->extra = kzalloc(sizeof(struct datafab_info), GFP_NOIO);
- if (!us->extra) {
- US_DEBUGP("datafab_transport: Gah! "
- "Can't allocate storage for Datafab info struct!\n");
- return USB_STOR_TRANSPORT_ERROR;
- }
-- memset(us->extra, 0, sizeof(struct datafab_info));
- us->extra_destructor = datafab_info_destructor;
- ((struct datafab_info *)us->extra)->lun = -1;
- }
---- gregkh-2.6.orig/drivers/usb/storage/isd200.c
-+++ gregkh-2.6/drivers/usb/storage/isd200.c
-@@ -1361,21 +1361,19 @@ static int isd200_init_info(struct us_da
- struct isd200_info *info;
-
- info = (struct isd200_info *)
-- kmalloc(sizeof(struct isd200_info), GFP_KERNEL);
-+ kzalloc(sizeof(struct isd200_info), GFP_KERNEL);
- if (!info)
- retStatus = ISD200_ERROR;
- else {
-- memset(info, 0, sizeof(struct isd200_info));
- info->id = (struct hd_driveid *)
-- kmalloc(sizeof(struct hd_driveid), GFP_KERNEL);
-+ kzalloc(sizeof(struct hd_driveid), GFP_KERNEL);
- info->RegsBuf = (unsigned char *)
- kmalloc(sizeof(info->ATARegs), GFP_KERNEL);
- if (!info->id || !info->RegsBuf) {
- isd200_free_info_ptrs(info);
- kfree(info);
- retStatus = ISD200_ERROR;
-- } else
-- memset(info->id, 0, sizeof(struct hd_driveid));
-+ }
- }
-
- if (retStatus == ISD200_GOOD) {
---- gregkh-2.6.orig/drivers/usb/storage/jumpshot.c
-+++ gregkh-2.6/drivers/usb/storage/jumpshot.c
-@@ -441,12 +441,11 @@ int jumpshot_transport(struct scsi_cmnd
- };
-
- if (!us->extra) {
-- us->extra = kmalloc(sizeof(struct jumpshot_info), GFP_NOIO);
-+ us->extra = kzalloc(sizeof(struct jumpshot_info), GFP_NOIO);
- if (!us->extra) {
- US_DEBUGP("jumpshot_transport: Gah! Can't allocate storage for jumpshot info struct!\n");
- return USB_STOR_TRANSPORT_ERROR;
- }
-- memset(us->extra, 0, sizeof(struct jumpshot_info));
- us->extra_destructor = jumpshot_info_destructor;
- }
-
---- gregkh-2.6.orig/drivers/usb/storage/sddr55.c
-+++ gregkh-2.6/drivers/usb/storage/sddr55.c
-@@ -751,11 +751,10 @@ int sddr55_transport(struct scsi_cmnd *s
- struct sddr55_card_info *info;
-
- if (!us->extra) {
-- us->extra = kmalloc(
-+ us->extra = kzalloc(
- sizeof(struct sddr55_card_info), GFP_NOIO);
- if (!us->extra)
- return USB_STOR_TRANSPORT_ERROR;
-- memset(us->extra, 0, sizeof(struct sddr55_card_info));
- us->extra_destructor = sddr55_card_info_destructor;
- }
-
---- gregkh-2.6.orig/drivers/usb/storage/shuttle_usbat.c
-+++ gregkh-2.6/drivers/usb/storage/shuttle_usbat.c
-@@ -1318,12 +1318,11 @@ int init_usbat(struct us_data *us)
- unsigned char subcountL = USBAT_ATA_LBA_ME;
- unsigned char *status = us->iobuf;
-
-- us->extra = kmalloc(sizeof(struct usbat_info), GFP_NOIO);
-+ us->extra = kzalloc(sizeof(struct usbat_info), GFP_NOIO);
- if (!us->extra) {
- US_DEBUGP("init_usbat: Gah! Can't allocate storage for usbat info struct!\n");
- return 1;
- }
-- memset(us->extra, 0, sizeof(struct usbat_info));
- info = (struct usbat_info *) (us->extra);
-
- /* Enable peripheral control signals */
diff --git a/usb/usb-kzalloc-in-cytherm.patch b/usb/usb-kzalloc-in-cytherm.patch
deleted file mode 100644
index efadd4a6518c1..0000000000000
--- a/usb/usb-kzalloc-in-cytherm.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From linux-usb-devel-admin@lists.sourceforge.net Fri Jan 6 13:28:33 2006
-From: Oliver Neukum <oliver@neukum.org>
-To: Erik Rigtorp <erkki@linux.nu>
-Content-Disposition: inline
-Message-Id: <200601062224.56945.oliver@neukum.org>
-Subject: USB: kzalloc in cytherm
-Date: Fri, 6 Jan 2006 22:24:56 +0100
-
-
-another one for kzalloc.
-
-Signed-off-by: Oliver Neukum <oliver@neukum.name>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-
----
- drivers/usb/misc/cytherm.c | 3 +--
- 1 file changed, 1 insertion(+), 2 deletions(-)
-
---- gregkh-2.6.orig/drivers/usb/misc/cytherm.c
-+++ gregkh-2.6/drivers/usb/misc/cytherm.c
-@@ -351,12 +351,11 @@ static int cytherm_probe(struct usb_inte
- struct usb_cytherm *dev = NULL;
- int retval = -ENOMEM;
-
-- dev = kmalloc (sizeof(struct usb_cytherm), GFP_KERNEL);
-+ dev = kzalloc (sizeof(struct usb_cytherm), GFP_KERNEL);
- if (dev == NULL) {
- dev_err (&interface->dev, "Out of memory\n");
- goto error;
- }
-- memset (dev, 0x00, sizeof (*dev));
-
- dev->udev = usb_get_dev(udev);
-
diff --git a/usb/usb-kzalloc-in-dabusb.patch b/usb/usb-kzalloc-in-dabusb.patch
deleted file mode 100644
index c3480eb7aa171..0000000000000
--- a/usb/usb-kzalloc-in-dabusb.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From linux-usb-devel-admin@lists.sourceforge.net Fri Jan 6 12:50:10 2006
-From: Oliver Neukum <oliver@neukum.org>
-To: deti@fliegl.de
-Content-Disposition: inline
-Message-Id: <200601062101.47610.oliver@neukum.org>
-Subject: USB: kzalloc in dabusb
-Date: Fri, 6 Jan 2006 21:01:47 +0100
-
-kzalloc in dabusb.
-
-Signed-off-by: Oliver Neukum <oliver@neukum.name>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-
----
- drivers/usb/media/dabusb.c | 5 ++---
- 1 file changed, 2 insertions(+), 3 deletions(-)
-
---- gregkh-2.6.orig/drivers/usb/media/dabusb.c
-+++ gregkh-2.6/drivers/usb/media/dabusb.c
-@@ -217,12 +217,11 @@ static int dabusb_alloc_buffers (pdabusb
- pipesize, packets, transfer_buffer_length);
-
- while (buffers < (s->total_buffer_size << 10)) {
-- b = (pbuff_t) kmalloc (sizeof (buff_t), GFP_KERNEL);
-+ b = (pbuff_t) kzalloc (sizeof (buff_t), GFP_KERNEL);
- if (!b) {
-- err("kmalloc(sizeof(buff_t))==NULL");
-+ err("kzalloc(sizeof(buff_t))==NULL");
- goto err;
- }
-- memset (b, 0, sizeof (buff_t));
- b->s = s;
- b->purb = usb_alloc_urb(packets, GFP_KERNEL);
- if (!b->purb) {
diff --git a/usb/usb-kzalloc-in-idmouse.patch b/usb/usb-kzalloc-in-idmouse.patch
deleted file mode 100644
index e76ea15893469..0000000000000
--- a/usb/usb-kzalloc-in-idmouse.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From linux-usb-devel-admin@lists.sourceforge.net Fri Jan 6 13:39:07 2006
-From: Oliver Neukum <oliver@neukum.org>
-To: echtler@fs.tum.de, aderesch@fs.tum.de
-Content-Disposition: inline
-Message-Id: <200601062236.27991.oliver@neukum.org>
-Subject: USB: kzalloc in idmouse
-Date: Fri, 6 Jan 2006 22:36:27 +0100
-
-
-another for kzalloc.
-
-Signed-off-by: Oliver Neukum <oliver@neukum.name>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-
----
- drivers/usb/misc/idmouse.c | 3 +--
- 1 file changed, 1 insertion(+), 2 deletions(-)
-
---- gregkh-2.6.orig/drivers/usb/misc/idmouse.c
-+++ gregkh-2.6/drivers/usb/misc/idmouse.c
-@@ -340,10 +340,9 @@ static int idmouse_probe(struct usb_inte
- return -ENODEV;
-
- /* allocate memory for our device state and initialize it */
-- dev = kmalloc(sizeof(*dev), GFP_KERNEL);
-+ dev = kzalloc(sizeof(*dev), GFP_KERNEL);
- if (dev == NULL)
- return -ENOMEM;
-- memset(dev, 0x00, sizeof(*dev));
-
- init_MUTEX(&dev->sem);
- dev->udev = udev;
diff --git a/usb/usb-kzalloc-in-ldusb.patch b/usb/usb-kzalloc-in-ldusb.patch
deleted file mode 100644
index 334a4f2ef6985..0000000000000
--- a/usb/usb-kzalloc-in-ldusb.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From linux-usb-devel-admin@lists.sourceforge.net Fri Jan 6 13:44:37 2006
-From: Oliver Neukum <oliver@neukum.org>
-To: Michael Hund <mhund@ld-didactic.de>
-Content-Disposition: inline
-Message-Id: <200601062240.02686.oliver@neukum.org>
-Subject: USB: kzalloc in ldusb
-Date: Fri, 6 Jan 2006 22:40:02 +0100
-
-
-another one for kzalloc
-
-Signed-off-by: Oliver Neukum <oliver@neukum.name>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-
----
- drivers/usb/misc/ldusb.c | 3 +--
- 1 file changed, 1 insertion(+), 2 deletions(-)
-
---- gregkh-2.6.orig/drivers/usb/misc/ldusb.c
-+++ gregkh-2.6/drivers/usb/misc/ldusb.c
-@@ -626,12 +626,11 @@ static int ld_usb_probe(struct usb_inter
-
- /* allocate memory for our device state and intialize it */
-
-- dev = kmalloc(sizeof(*dev), GFP_KERNEL);
-+ dev = kzalloc(sizeof(*dev), GFP_KERNEL);
- if (dev == NULL) {
- dev_err(&intf->dev, "Out of memory\n");
- goto exit;
- }
-- memset(dev, 0x00, sizeof(*dev));
- init_MUTEX(&dev->sem);
- dev->intf = intf;
- init_waitqueue_head(&dev->read_wait);
diff --git a/usb/usb-kzalloc-in-phidgetinterfacekit.patch b/usb/usb-kzalloc-in-phidgetinterfacekit.patch
deleted file mode 100644
index 7b6c99c05ccf4..0000000000000
--- a/usb/usb-kzalloc-in-phidgetinterfacekit.patch
+++ /dev/null
@@ -1,68 +0,0 @@
-From linux-usb-devel-admin@lists.sourceforge.net Fri Jan 6 13:44:40 2006
-From: Oliver Neukum <oliver@neukum.org>
-To: Sean Young <sean@mess.org>
-Content-Disposition: inline
-Message-Id: <200601062241.51664.oliver@neukum.org>
-Subject: USB: kzalloc in PhidgetInterfaceKit
-Date: Fri, 6 Jan 2006 22:41:51 +0100
-
-
-another for kzalloc.
-
-Signed-off-by: Oliver Neukum <oliver@neukum.name>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-
----
- drivers/usb/misc/phidgetkit.c | 9 +++------
- 1 file changed, 3 insertions(+), 6 deletions(-)
-
---- gregkh-2.6.orig/drivers/usb/misc/phidgetkit.c
-+++ gregkh-2.6/drivers/usb/misc/phidgetkit.c
-@@ -88,7 +88,7 @@ static int change_outputs(struct phidget
- int retval;
- int n;
-
-- buffer = kmalloc(4, GFP_KERNEL);
-+ buffer = kzalloc(4, GFP_KERNEL);
- if (!buffer) {
- dev_err(&kit->udev->dev, "%s - out of memory\n",
- __FUNCTION__);
-@@ -96,7 +96,6 @@ static int change_outputs(struct phidget
- }
-
- kit->outputs[output_num] = enable;
-- memset(buffer, 0, 4);
- for (n=0; n<8; n++) {
- if (kit->outputs[n]) {
- buffer[0] |= 1 << n;
-@@ -192,7 +191,7 @@ static ssize_t set_backlight(struct devi
- unsigned char *buffer;
- int retval = -ENOMEM;
-
-- buffer = kmalloc(8, GFP_KERNEL);
-+ buffer = kzalloc(8, GFP_KERNEL);
- if (!buffer) {
- dev_err(&kit->udev->dev, "%s - out of memory\n", __FUNCTION__);
- goto exit;
-@@ -202,7 +201,6 @@ static ssize_t set_backlight(struct devi
- retval = -EINVAL;
- goto exit;
- }
-- memset(buffer, 0x00, 8);
- if (enabled)
- buffer[0] = 0x01;
- buffer[7] = 0x11;
-@@ -406,12 +404,11 @@ static int interfacekit_probe(struct usb
- pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
- maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));
-
-- kit = kmalloc(sizeof(*kit), GFP_KERNEL);
-+ kit = kzalloc(sizeof(*kit), GFP_KERNEL);
- if (kit == NULL) {
- dev_err(&intf->dev, "%s - out of memory\n", __FUNCTION__);
- return -ENOMEM;
- }
-- memset(kit, 0, sizeof(*kit));
- kit->ifkit = ifkit;
-
- kit->data = usb_buffer_alloc(dev, 8, SLAB_ATOMIC, &kit->data_dma);
diff --git a/usb/usb-kzalloc-in-phidgetservo.patch b/usb/usb-kzalloc-in-phidgetservo.patch
deleted file mode 100644
index 35a312e1f07f5..0000000000000
--- a/usb/usb-kzalloc-in-phidgetservo.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-From linux-usb-devel-admin@lists.sourceforge.net Fri Jan 6 13:44:48 2006
-From: Oliver Neukum <oliver@neukum.org>
-To: Sean Young <sean@mess.org>
-Content-Disposition: inline
-Message-Id: <200601062243.33015.oliver@neukum.org>
-Subject: USB: kzalloc in PhidgetServo
-Date: Fri, 6 Jan 2006 22:43:32 +0100
-
-another for kzalloc.
-
-Signed-off-by: Oliver Neukum <oliver@neukum.name>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-
----
- drivers/usb/misc/phidgetservo.c | 3 +--
- 1 file changed, 1 insertion(+), 2 deletions(-)
-
---- gregkh-2.6.orig/drivers/usb/misc/phidgetservo.c
-+++ gregkh-2.6/drivers/usb/misc/phidgetservo.c
-@@ -252,12 +252,11 @@ servo_probe(struct usb_interface *interf
- struct usb_device *udev = interface_to_usbdev(interface);
- struct phidget_servo *dev;
-
-- dev = kmalloc(sizeof (struct phidget_servo), GFP_KERNEL);
-+ dev = kzalloc(sizeof (struct phidget_servo), GFP_KERNEL);
- if (dev == NULL) {
- dev_err(&interface->dev, "%s - out of memory\n", __FUNCTION__);
- return -ENOMEM;
- }
-- memset(dev, 0x00, sizeof (*dev));
-
- dev->udev = usb_get_dev(udev);
- dev->type = id->driver_info;
diff --git a/usb/usb-kzalloc-in-sisusbvga.patch b/usb/usb-kzalloc-in-sisusbvga.patch
deleted file mode 100644
index 395355e1b333f..0000000000000
--- a/usb/usb-kzalloc-in-sisusbvga.patch
+++ /dev/null
@@ -1,44 +0,0 @@
-From linux-usb-devel-admin@lists.sourceforge.net Fri Jan 6 14:32:41 2006
-From: Oliver Neukum <oliver@neukum.org>
-To: Thomas Winischhofer <thomas@winischhofer.net>
-Content-Disposition: inline
-Message-Id: <200601062327.17654.oliver@neukum.org>
-Subject: USB: kzalloc in sisusbvga
-Date: Fri, 6 Jan 2006 23:27:17 +0100
-
-this does two things:
-- use kzalloc where appropriate
-- correct error return codes in ioctl
-
-Signed-off-by: Oliver Neukum <oliver@neukum.name>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-
----
- drivers/usb/misc/sisusbvga/sisusb.c | 5 ++---
- 1 file changed, 2 insertions(+), 3 deletions(-)
-
---- gregkh-2.6.orig/drivers/usb/misc/sisusbvga/sisusb.c
-+++ gregkh-2.6/drivers/usb/misc/sisusbvga/sisusb.c
-@@ -3188,7 +3188,7 @@ sisusb_ioctl(struct inode *inode, struct
- break;
-
- default:
-- retval = -EINVAL;
-+ retval = -ENOTTY;
- break;
- }
-
-@@ -3251,12 +3251,11 @@ static int sisusb_probe(struct usb_inter
- dev->devnum);
-
- /* Allocate memory for our private */
-- if (!(sisusb = kmalloc(sizeof(*sisusb), GFP_KERNEL))) {
-+ if (!(sisusb = kzalloc(sizeof(*sisusb), GFP_KERNEL))) {
- printk(KERN_ERR
- "sisusb: Failed to allocate memory for private data\n");
- return -ENOMEM;
- }
-- memset(sisusb, 0, sizeof(*sisusb));
- kref_init(&sisusb->kref);
-
- init_MUTEX(&(sisusb->lock));
diff --git a/usb/usb-kzalloc-in-usbled.patch b/usb/usb-kzalloc-in-usbled.patch
deleted file mode 100644
index 8d15096d746b2..0000000000000
--- a/usb/usb-kzalloc-in-usbled.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-From linux-usb-devel-admin@lists.sourceforge.net Fri Jan 6 13:49:54 2006
-From: Oliver Neukum <oliver@neukum.org>
-To: Greg KH <gregkh@suse.de>
-Content-Disposition: inline
-Message-Id: <200601062244.52481.oliver@neukum.org>
-Subject: USB: kzalloc in usbled
-Date: Fri, 6 Jan 2006 22:44:52 +0100
-
-another one for kzalloc.
-
-Signed-off-by: Oliver Neukum <oliver@neukum.name>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-
----
- drivers/usb/misc/usbled.c | 3 +--
- 1 file changed, 1 insertion(+), 2 deletions(-)
-
---- gregkh-2.6.orig/drivers/usb/misc/usbled.c
-+++ gregkh-2.6/drivers/usb/misc/usbled.c
-@@ -106,12 +106,11 @@ static int led_probe(struct usb_interfac
- struct usb_led *dev = NULL;
- int retval = -ENOMEM;
-
-- dev = kmalloc(sizeof(struct usb_led), GFP_KERNEL);
-+ dev = kzalloc(sizeof(struct usb_led), GFP_KERNEL);
- if (dev == NULL) {
- dev_err(&interface->dev, "Out of memory\n");
- goto error;
- }
-- memset (dev, 0x00, sizeof (*dev));
-
- dev->udev = usb_get_dev(udev);
-
diff --git a/usb/usb-kzalloc-in-usbvideo.patch b/usb/usb-kzalloc-in-usbvideo.patch
deleted file mode 100644
index 5ee011ed54a46..0000000000000
--- a/usb/usb-kzalloc-in-usbvideo.patch
+++ /dev/null
@@ -1,35 +0,0 @@
-From linux-usb-devel-admin@lists.sourceforge.net Fri Jan 6 12:52:07 2006
-From: Oliver Neukum <oliver@neukum.org>
-To: Greg KH <gregkh@suse.de>
-Content-Disposition: inline
-Message-Id: <200601062135.09101.oliver@neukum.org>
-Subject: USB: kzalloc in usbvideo
-Date: Fri, 6 Jan 2006 21:35:08 +0100
-
-another for kzalloc.
-
-Signed-off-by: Oliver Neukum <oliver@neukum.name>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-
----
- drivers/usb/media/usbvideo.c | 3 +--
- 1 file changed, 1 insertion(+), 2 deletions(-)
-
---- gregkh-2.6.orig/drivers/usb/media/usbvideo.c
-+++ gregkh-2.6/drivers/usb/media/usbvideo.c
-@@ -690,14 +690,13 @@ int usbvideo_register(
- }
-
- base_size = num_cams * sizeof(struct uvd) + sizeof(struct usbvideo);
-- cams = (struct usbvideo *) kmalloc(base_size, GFP_KERNEL);
-+ cams = (struct usbvideo *) kzalloc(base_size, GFP_KERNEL);
- if (cams == NULL) {
- err("Failed to allocate %d. bytes for usbvideo struct", base_size);
- return -ENOMEM;
- }
- dbg("%s: Allocated $%p (%d. bytes) for %d. cameras",
- __FUNCTION__, cams, base_size, num_cams);
-- memset(cams, 0, base_size);
-
- /* Copy callbacks, apply defaults for those that are not set */
- memmove(&cams->cb, cbTbl, sizeof(cams->cb));
diff --git a/usb/usb-kzalloc-in-w9968cf.patch b/usb/usb-kzalloc-in-w9968cf.patch
deleted file mode 100644
index 0b4e2370274db..0000000000000
--- a/usb/usb-kzalloc-in-w9968cf.patch
+++ /dev/null
@@ -1,73 +0,0 @@
-From linux-usb-devel-admin@lists.sourceforge.net Fri Jan 6 12:51:54 2006
-From: Oliver Neukum <oliver@neukum.org>
-To: Luca Risolia <luca.risolia@studio.unibo.it>, Greg KH <gregkh@suse.de>
-Content-Disposition: inline
-Message-Id: <200601062128.41016.oliver@neukum.org>
-Subject: USB: kzalloc in w9968cf
-Date: Fri, 6 Jan 2006 21:28:40 +0100
-
-another one for kzalloc.
-
-
-Signed-off-by: Oliver Neukum <oliver@neukum.name>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-
----
- drivers/usb/media/w9968cf.c | 13 ++++---------
- 1 file changed, 4 insertions(+), 9 deletions(-)
-
---- gregkh-2.6.orig/drivers/usb/media/w9968cf.c
-+++ gregkh-2.6/drivers/usb/media/w9968cf.c
-@@ -695,13 +695,12 @@ static int w9968cf_allocate_memory(struc
- /* Allocate memory for the isochronous transfer buffers */
- for (i = 0; i < W9968CF_URBS; i++) {
- if (!(cam->transfer_buffer[i] =
-- kmalloc(W9968CF_ISO_PACKETS*p_size, GFP_KERNEL))) {
-+ kzalloc(W9968CF_ISO_PACKETS*p_size, GFP_KERNEL))) {
- DBG(1, "Couldn't allocate memory for the isochronous "
- "transfer buffers (%u bytes)",
- p_size * W9968CF_ISO_PACKETS)
- return -ENOMEM;
- }
-- memset(cam->transfer_buffer[i], 0, W9968CF_ISO_PACKETS*p_size);
- }
-
- /* Allocate memory for the temporary frame buffer */
-@@ -3499,12 +3498,10 @@ w9968cf_usb_probe(struct usb_interface*
- return -ENODEV;
-
- cam = (struct w9968cf_device*)
-- kmalloc(sizeof(struct w9968cf_device), GFP_KERNEL);
-+ kzalloc(sizeof(struct w9968cf_device), GFP_KERNEL);
- if (!cam)
- return -ENOMEM;
-
-- memset(cam, 0, sizeof(*cam));
--
- init_MUTEX(&cam->dev_sem);
- down(&cam->dev_sem);
-
-@@ -3532,21 +3529,19 @@ w9968cf_usb_probe(struct usb_interface*
-
-
- /* Allocate 2 bytes of memory for camera control USB transfers */
-- if (!(cam->control_buffer = kmalloc(2, GFP_KERNEL))) {
-+ if (!(cam->control_buffer = kzalloc(2, GFP_KERNEL))) {
- DBG(1,"Couldn't allocate memory for camera control transfers")
- err = -ENOMEM;
- goto fail;
- }
-- memset(cam->control_buffer, 0, 2);
-
- /* Allocate 8 bytes of memory for USB data transfers to the FSB */
-- if (!(cam->data_buffer = kmalloc(8, GFP_KERNEL))) {
-+ if (!(cam->data_buffer = kzalloc(8, GFP_KERNEL))) {
- DBG(1, "Couldn't allocate memory for data "
- "transfers to the FSB")
- err = -ENOMEM;
- goto fail;
- }
-- memset(cam->data_buffer, 0, 8);
-
- /* Register the V4L device */
- cam->v4ldev = video_device_alloc();
diff --git a/usb/usb-mdc800.c-to-kzalloc.patch b/usb/usb-mdc800.c-to-kzalloc.patch
deleted file mode 100644
index 90afc0de6b16b..0000000000000
--- a/usb/usb-mdc800.c-to-kzalloc.patch
+++ /dev/null
@@ -1,35 +0,0 @@
-From linux-usb-devel-admin@lists.sourceforge.net Fri Jan 6 12:49:49 2006
-From: Oliver Neukum <oliver@neukum.org>
-To: Henning Zabel <henning@uni-paderborn.de>
-Content-Disposition: inline
-Message-Id: <200601062045.11939.oliver@neukum.org>
-Subject: USB: mdc800.c to kzalloc
-Date: Fri, 6 Jan 2006 20:45:11 +0100
-
-
-one more conversion to kzalloc.
-
-Signed-off-by: Oliver Neukum <oliver@neukum.name>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-
----
- drivers/usb/image/mdc800.c | 4 +---
- 1 file changed, 1 insertion(+), 3 deletions(-)
-
---- gregkh-2.6.orig/drivers/usb/image/mdc800.c
-+++ gregkh-2.6/drivers/usb/image/mdc800.c
-@@ -978,13 +978,11 @@ static int __init usb_mdc800_init (void)
- {
- int retval = -ENODEV;
- /* Allocate Memory */
-- mdc800=kmalloc (sizeof (struct mdc800_data), GFP_KERNEL);
-+ mdc800=kzalloc (sizeof (struct mdc800_data), GFP_KERNEL);
- if (!mdc800)
- goto cleanup_on_fail;
-
-- memset(mdc800, 0, sizeof(struct mdc800_data));
- mdc800->dev = NULL;
-- mdc800->open=0;
- mdc800->state=NOT_CONNECTED;
- init_MUTEX (&mdc800->io_lock);
-
diff --git a/usb/usb-minor-gadget-rndis-tweak.patch b/usb/usb-minor-gadget-rndis-tweak.patch
deleted file mode 100644
index e84a8f0194243..0000000000000
--- a/usb/usb-minor-gadget-rndis-tweak.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From david-b@pacbell.net Sun Jan 22 11:29:03 2006
-From: David Brownell <david-b@pacbell.net>
-To: Greg KH <greg@kroah.com>
-Subject: USB: minor gadget/rndis tweak
-Date: Sun, 22 Jan 2006 10:33:27 -0800
-Cc: Andrew Victor <andrew@sanpeople.com>
-Message-Id: <200601221033.27776.david-b@pacbell.net>
-
-Resove a minor FIXME: don't change MTU while RNDIS link is active,
-the other end won't expect such things...
-
-Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-
----
- drivers/usb/gadget/ether.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
---- gregkh-2.6.orig/drivers/usb/gadget/ether.c
-+++ gregkh-2.6/drivers/usb/gadget/ether.c
-@@ -1549,7 +1549,8 @@ static int eth_change_mtu (struct net_de
- {
- struct eth_dev *dev = netdev_priv(net);
-
-- // FIXME if rndis, don't change while link's live
-+ if (dev->rndis)
-+ return -EBUSY;
-
- if (new_mtu <= ETH_HLEN || new_mtu > ETH_FRAME_LEN)
- return -ERANGE;
diff --git a/usb/usb-ohci-for-au1200.patch b/usb/usb-ohci-for-au1200.patch
deleted file mode 100644
index c2f058ef71d61..0000000000000
--- a/usb/usb-ohci-for-au1200.patch
+++ /dev/null
@@ -1,241 +0,0 @@
-From david-b@pacbell.net Fri Jan 20 17:25:17 2006
-From: Jordan Crouse <jordan.crouse@amd.com>
-To: Greg KH <greg@kroah.com>
-Subject: USB: OHCI for AU1200
-Date: Fri, 20 Jan 2006 14:09:54 -0800
-Message-Id: <200601201409.54293.david-b@pacbell.net>
-
-ALCHEMY: Add OHCI support for AU1200
-
-Updated by moving the OHCI support out of the EHCI patch.
-
-Signed-off-by: Jordan Crouse <jordan.crouse@amd.com>
-Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-
-
----
- arch/mips/au1000/common/platform.c | 2
- drivers/usb/host/ohci-au1xxx.c | 102 +++++++++++++++++++++++++++++++------
- 2 files changed, 88 insertions(+), 16 deletions(-)
-
---- gregkh-2.6.orig/arch/mips/au1000/common/platform.c
-+++ gregkh-2.6/arch/mips/au1000/common/platform.c
-@@ -20,7 +20,7 @@
- static struct resource au1xxx_usb_ohci_resources[] = {
- [0] = {
- .start = USB_OHCI_BASE,
-- .end = USB_OHCI_BASE + USB_OHCI_LEN,
-+ .end = USB_OHCI_BASE + USB_OHCI_LEN - 1,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
---- gregkh-2.6.orig/drivers/usb/host/ohci-au1xxx.c
-+++ gregkh-2.6/drivers/usb/host/ohci-au1xxx.c
-@@ -23,6 +23,8 @@
-
- #include <asm/mach-au1x00/au1000.h>
-
-+#ifndef CONFIG_SOC_AU1200
-+
- #define USBH_ENABLE_BE (1<<0)
- #define USBH_ENABLE_C (1<<1)
- #define USBH_ENABLE_E (1<<2)
-@@ -37,21 +39,68 @@
- #error not byte order defined
- #endif
-
-+#else /* Au1200 */
-+
-+#define USB_HOST_CONFIG (USB_MSR_BASE + USB_MSR_MCFG)
-+#define USB_MCFG_PFEN (1<<31)
-+#define USB_MCFG_RDCOMB (1<<30)
-+#define USB_MCFG_SSDEN (1<<23)
-+#define USB_MCFG_OHCCLKEN (1<<16)
-+#define USB_MCFG_UCAM (1<<7)
-+#define USB_MCFG_OBMEN (1<<1)
-+#define USB_MCFG_OMEMEN (1<<0)
-+
-+#define USBH_ENABLE_CE USB_MCFG_OHCCLKEN
-+#ifdef CONFIG_DMA_COHERENT
-+#define USBH_ENABLE_INIT (USB_MCFG_OHCCLKEN \
-+ | USB_MCFG_PFEN | USB_MCFG_RDCOMB \
-+ | USB_MCFG_SSDEN | USB_MCFG_UCAM \
-+ | USB_MCFG_OBMEN | USB_MCFG_OMEMEN)
-+#else
-+#define USBH_ENABLE_INIT (USB_MCFG_OHCCLKEN \
-+ | USB_MCFG_PFEN | USB_MCFG_RDCOMB \
-+ | USB_MCFG_SSDEN \
-+ | USB_MCFG_OBMEN | USB_MCFG_OMEMEN)
-+#endif
-+#define USBH_DISABLE (USB_MCFG_OBMEN | USB_MCFG_OMEMEN)
-+
-+#endif /* Au1200 */
-+
- extern int usb_disabled(void);
-
- /*-------------------------------------------------------------------------*/
-
--static void au1xxx_start_hc(struct platform_device *dev)
-+static void au1xxx_start_ohc(struct platform_device *dev)
- {
- printk(KERN_DEBUG __FILE__
- ": starting Au1xxx OHCI USB Controller\n");
-
- /* enable host controller */
-+
-+#ifndef CONFIG_SOC_AU1200
-+
- au_writel(USBH_ENABLE_CE, USB_HOST_CONFIG);
- udelay(1000);
- au_writel(USBH_ENABLE_INIT, USB_HOST_CONFIG);
- udelay(1000);
-
-+#else /* Au1200 */
-+
-+ /* write HW defaults again in case Yamon cleared them */
-+ if (au_readl(USB_HOST_CONFIG) == 0) {
-+ au_writel(0x00d02000, USB_HOST_CONFIG);
-+ au_readl(USB_HOST_CONFIG);
-+ udelay(1000);
-+ }
-+ au_writel(USBH_ENABLE_CE | au_readl(USB_HOST_CONFIG), USB_HOST_CONFIG);
-+ au_readl(USB_HOST_CONFIG);
-+ udelay(1000);
-+ au_writel(USBH_ENABLE_INIT | au_readl(USB_HOST_CONFIG), USB_HOST_CONFIG);
-+ au_readl(USB_HOST_CONFIG);
-+ udelay(1000);
-+
-+#endif /* Au1200 */
-+
- /* wait for reset complete (read register twice; see au1500 errata) */
- while (au_readl(USB_HOST_CONFIG),
- !(au_readl(USB_HOST_CONFIG) & USBH_ENABLE_RD))
-@@ -61,13 +110,25 @@ static void au1xxx_start_hc(struct platf
- ": Clock to USB host has been enabled \n");
- }
-
--static void au1xxx_stop_hc(struct platform_device *dev)
-+static void au1xxx_stop_ohc(struct platform_device *dev)
- {
- printk(KERN_DEBUG __FILE__
- ": stopping Au1xxx OHCI USB Controller\n");
-
-+#ifndef CONFIG_SOC_AU1200
-+
- /* Disable clock */
- au_writel(au_readl(USB_HOST_CONFIG) & ~USBH_ENABLE_CE, USB_HOST_CONFIG);
-+
-+#else /* Au1200 */
-+
-+ /* Disable mem */
-+ au_writel(~USBH_DISABLE & au_readl(USB_HOST_CONFIG), USB_HOST_CONFIG);
-+ udelay(1000);
-+ /* Disable clock */
-+ au_writel(~USBH_ENABLE_CE & au_readl(USB_HOST_CONFIG), USB_HOST_CONFIG);
-+ au_readl(USB_HOST_CONFIG);
-+#endif /* Au1200 */
- }
-
-
-@@ -78,7 +139,7 @@ static void au1xxx_stop_hc(struct platfo
-
-
- /**
-- * usb_hcd_au1xxx_probe - initialize Au1xxx-based HCDs
-+ * usb_ohci_au1xxx_probe - initialize Au1xxx-based HCDs
- * Context: !in_interrupt()
- *
- * Allocates basic resources for this USB host controller, and
-@@ -86,14 +147,25 @@ static void au1xxx_stop_hc(struct platfo
- * through the hotplug entry's driver_data.
- *
- */
--int usb_hcd_au1xxx_probe (const struct hc_driver *driver,
-+static int usb_ohci_au1xxx_probe(const struct hc_driver *driver,
- struct platform_device *dev)
- {
- int retval;
- struct usb_hcd *hcd;
-
-- if(dev->resource[1].flags != IORESOURCE_IRQ) {
-- pr_debug ("resource[1] is not IORESOURCE_IRQ");
-+#if defined(CONFIG_SOC_AU1200) && defined(CONFIG_DMA_COHERENT)
-+ /* Au1200 AB USB does not support coherent memory */
-+ if (!(read_c0_prid() & 0xff)) {
-+ pr_info("%s: this is chip revision AB !!\n",
-+ dev->dev.name);
-+ pr_info("%s: update your board or re-configure the kernel\n",
-+ dev->dev.name);
-+ return -ENODEV;
-+ }
-+#endif
-+
-+ if (dev->resource[1].flags != IORESOURCE_IRQ) {
-+ pr_debug("resource[1] is not IORESOURCE_IRQ\n");
- return -ENOMEM;
- }
-
-@@ -104,26 +176,26 @@ int usb_hcd_au1xxx_probe (const struct h
- hcd->rsrc_len = dev->resource[0].end - dev->resource[0].start + 1;
-
- if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
-- pr_debug("request_mem_region failed");
-+ pr_debug("request_mem_region failed\n");
- retval = -EBUSY;
- goto err1;
- }
-
- hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
- if (!hcd->regs) {
-- pr_debug("ioremap failed");
-+ pr_debug("ioremap failed\n");
- retval = -ENOMEM;
- goto err2;
- }
-
-- au1xxx_start_hc(dev);
-+ au1xxx_start_ohc(dev);
- ohci_hcd_init(hcd_to_ohci(hcd));
-
-- retval = usb_add_hcd(hcd, dev->resource[1].start, SA_INTERRUPT);
-+ retval = usb_add_hcd(hcd, dev->resource[1].start, SA_INTERRUPT | SA_SHIRQ);
- if (retval == 0)
- return retval;
-
-- au1xxx_stop_hc(dev);
-+ au1xxx_stop_ohc(dev);
- iounmap(hcd->regs);
- err2:
- release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
-@@ -146,10 +218,10 @@ int usb_hcd_au1xxx_probe (const struct h
- * context, normally "rmmod", "apmd", or something similar.
- *
- */
--void usb_hcd_au1xxx_remove (struct usb_hcd *hcd, struct platform_device *dev)
-+static void usb_ohci_au1xxx_remove(struct usb_hcd *hcd, struct platform_device *dev)
- {
- usb_remove_hcd(hcd);
-- au1xxx_stop_hc(dev);
-+ au1xxx_stop_ohc(dev);
- iounmap(hcd->regs);
- release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
- usb_put_hcd(hcd);
-@@ -235,7 +307,7 @@ static int ohci_hcd_au1xxx_drv_probe(str
- if (usb_disabled())
- return -ENODEV;
-
-- ret = usb_hcd_au1xxx_probe(&ohci_au1xxx_hc_driver, pdev);
-+ ret = usb_ohci_au1xxx_probe(&ohci_au1xxx_hc_driver, pdev);
- return ret;
- }
-
-@@ -243,7 +315,7 @@ static int ohci_hcd_au1xxx_drv_remove(st
- {
- struct usb_hcd *hcd = platform_get_drvdata(pdev);
-
-- usb_hcd_au1xxx_remove(hcd, pdev);
-+ usb_ohci_au1xxx_remove(hcd, pdev);
- return 0;
- }
- /*TBD*/
diff --git a/usb/usb-ohci-uses-driver-model-wakeup-flags.patch b/usb/usb-ohci-uses-driver-model-wakeup-flags.patch
deleted file mode 100644
index e9cbce5a0527f..0000000000000
--- a/usb/usb-ohci-uses-driver-model-wakeup-flags.patch
+++ /dev/null
@@ -1,228 +0,0 @@
-From david-b@pacbell.net Mon Jan 23 16:29:40 2006
-From: David Brownell <david-b@pacbell.net>
-To: Greg KH <greg@kroah.com>
-Subject: USB: ohci uses driver model wakeup flags
-Date: Mon, 23 Jan 2006 15:28:07 -0800
-Content-Disposition: inline
-Message-Id: <200601231528.07476.david-b@pacbell.net>
-
-This makes OHCI use the driver model wakeup control bits for its root hub
-(e.g. disable on amd756, because of chip erratum) and for the controller
-itself. It no longer uses the hcd glue bits with those roles, and depends
-on the previous patch making the root hub available earlier.
-
-Note that on most platforms (boot code properly setting the RWC bit) this
-gives a partial workaround for the way PCI isn't currently flagging devices
-that support PME# signals. (Because of odd PCI init sequencing on PPC.)
-That's because many OHCI controllers support "legacy PCI PM" ... without
-involving any PCI PM capability.
-
-USB wakeup from STR, if it works on your system, may still involve
-tweaking things by hand in /proc/acpi/wakeup.
-
-Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-
----
- drivers/usb/host/ohci-hcd.c | 49 ++++++++++++++++++++++++--------------------
- drivers/usb/host/ohci-hub.c | 12 +++++-----
- drivers/usb/host/ohci-pci.c | 15 +++++++++++--
- 3 files changed, 46 insertions(+), 30 deletions(-)
-
---- gregkh-2.6.orig/drivers/usb/host/ohci-hcd.c
-+++ gregkh-2.6/drivers/usb/host/ohci-hcd.c
-@@ -443,11 +443,16 @@ ohci_reboot (struct notifier_block *bloc
- static int ohci_init (struct ohci_hcd *ohci)
- {
- int ret;
-+ struct usb_hcd *hcd = ohci_to_hcd(ohci);
-
- disable (ohci);
-- ohci->regs = ohci_to_hcd(ohci)->regs;
-+ ohci->regs = hcd->regs;
- ohci->next_statechange = jiffies;
-
-+ /* REVISIT this BIOS handshake is now moved into PCI "quirks", and
-+ * was never needed for most non-PCI systems ... remove the code?
-+ */
-+
- #ifndef IR_DISABLE
- /* SMM owns the HC? not for long! */
- if (!no_handshake && ohci_readl (ohci,
-@@ -478,8 +483,10 @@ static int ohci_init (struct ohci_hcd *o
-
- /* Disable HC interrupts */
- ohci_writel (ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable);
-- // flush the writes
-- (void) ohci_readl (ohci, &ohci->regs->control);
-+
-+ /* flush the writes, and save key bits like RWC */
-+ if (ohci_readl (ohci, &ohci->regs->control) & OHCI_CTRL_RWC)
-+ ohci->hc_control |= OHCI_CTRL_RWC;
-
- /* Read the number of ports unless overridden */
- if (ohci->num_ports == 0)
-@@ -488,16 +495,19 @@ static int ohci_init (struct ohci_hcd *o
- if (ohci->hcca)
- return 0;
-
-- ohci->hcca = dma_alloc_coherent (ohci_to_hcd(ohci)->self.controller,
-+ ohci->hcca = dma_alloc_coherent (hcd->self.controller,
- sizeof *ohci->hcca, &ohci->hcca_dma, 0);
- if (!ohci->hcca)
- return -ENOMEM;
-
- if ((ret = ohci_mem_init (ohci)) < 0)
-- ohci_stop (ohci_to_hcd(ohci));
-+ ohci_stop (hcd);
-+ else {
-+ register_reboot_notifier (&ohci->reboot_notifier);
-+ create_debug_files (ohci);
-+ }
-
- return ret;
--
- }
-
- /*-------------------------------------------------------------------------*/
-@@ -510,6 +520,7 @@ static int ohci_run (struct ohci_hcd *oh
- {
- u32 mask, temp;
- int first = ohci->fminterval == 0;
-+ struct usb_hcd *hcd = ohci_to_hcd(ohci);
-
- disable (ohci);
-
-@@ -525,18 +536,17 @@ static int ohci_run (struct ohci_hcd *oh
- /* also: power/overcurrent flags in roothub.a */
- }
-
-- /* Reset USB nearly "by the book". RemoteWakeupConnected
-- * saved if boot firmware (BIOS/SMM/...) told us it's connected
-- * (for OHCI integrated on mainboard, it normally is)
-+ /* Reset USB nearly "by the book". RemoteWakeupConnected was
-+ * saved if boot firmware (BIOS/SMM/...) told us it's connected,
-+ * or if bus glue did the same (e.g. for PCI add-in cards with
-+ * PCI PM support).
- */
-- ohci->hc_control = ohci_readl (ohci, &ohci->regs->control);
- ohci_dbg (ohci, "resetting from state '%s', control = 0x%x\n",
- hcfs2string (ohci->hc_control & OHCI_CTRL_HCFS),
-- ohci->hc_control);
--
-- if (ohci->hc_control & OHCI_CTRL_RWC
-- && !(ohci->flags & OHCI_QUIRK_AMD756))
-- ohci_to_hcd(ohci)->can_wakeup = 1;
-+ ohci_readl (ohci, &ohci->regs->control));
-+ if ((ohci->hc_control & OHCI_CTRL_RWC) != 0
-+ && !device_may_wakeup(hcd->self.controller))
-+ device_init_wakeup(hcd->self.controller, 1);
-
- switch (ohci->hc_control & OHCI_CTRL_HCFS) {
- case OHCI_USB_OPER:
-@@ -632,7 +642,7 @@ retry:
- ohci->hc_control &= OHCI_CTRL_RWC;
- ohci->hc_control |= OHCI_CONTROL_INIT | OHCI_USB_OPER;
- ohci_writel (ohci, ohci->hc_control, &ohci->regs->control);
-- ohci_to_hcd(ohci)->state = HC_STATE_RUNNING;
-+ hcd->state = HC_STATE_RUNNING;
-
- /* wake on ConnectStatusChange, matching external hubs */
- ohci_writel (ohci, RH_HS_DRWE, &ohci->regs->roothub.status);
-@@ -667,15 +677,10 @@ retry:
-
- // POTPGT delay is bits 24-31, in 2 ms units.
- mdelay ((temp >> 23) & 0x1fe);
-- ohci_to_hcd(ohci)->state = HC_STATE_RUNNING;
-+ hcd->state = HC_STATE_RUNNING;
-
- ohci_dump (ohci, 1);
-
-- if (ohci_to_hcd(ohci)->self.root_hub == NULL) {
-- register_reboot_notifier (&ohci->reboot_notifier);
-- create_debug_files (ohci);
-- }
--
- return 0;
- }
-
---- gregkh-2.6.orig/drivers/usb/host/ohci-hub.c
-+++ gregkh-2.6/drivers/usb/host/ohci-hub.c
-@@ -107,7 +107,7 @@ static int ohci_bus_suspend (struct usb_
- &ohci->regs->intrstatus);
-
- /* maybe resume can wake root hub */
-- if (hcd->remote_wakeup)
-+ if (device_may_wakeup(&ohci_to_hcd(ohci)->self.root_hub->dev))
- ohci->hc_control |= OHCI_CTRL_RWE;
- else
- ohci->hc_control &= ~OHCI_CTRL_RWE;
-@@ -246,9 +246,9 @@ static int ohci_bus_resume (struct usb_h
- (void) ohci_readl (ohci, &ohci->regs->control);
- msleep (3);
-
-- temp = OHCI_CONTROL_INIT | OHCI_USB_OPER;
-- if (hcd->can_wakeup)
-- temp |= OHCI_CTRL_RWC;
-+ temp = ohci->hc_control;
-+ temp &= OHCI_CTRL_RWC;
-+ temp |= OHCI_CONTROL_INIT | OHCI_USB_OPER;
- ohci->hc_control = temp;
- ohci_writel (ohci, temp, &ohci->regs->control);
- (void) ohci_readl (ohci, &ohci->regs->control);
-@@ -302,7 +302,7 @@ ohci_hub_status_data (struct usb_hcd *hc
- {
- struct ohci_hcd *ohci = hcd_to_ohci (hcd);
- int i, changed = 0, length = 1;
-- int can_suspend = hcd->can_wakeup;
-+ int can_suspend = device_may_wakeup(&hcd->self.root_hub->dev);
- unsigned long flags;
-
- spin_lock_irqsave (&ohci->lock, flags);
-@@ -354,7 +354,7 @@ ohci_hub_status_data (struct usb_hcd *hc
- */
- if (!(status & RH_PS_CCS))
- continue;
-- if ((status & RH_PS_PSS) && hcd->remote_wakeup)
-+ if ((status & RH_PS_PSS) && can_suspend)
- continue;
- can_suspend = 0;
- }
---- gregkh-2.6.orig/drivers/usb/host/ohci-pci.c
-+++ gregkh-2.6/drivers/usb/host/ohci-pci.c
-@@ -35,7 +35,10 @@ ohci_pci_start (struct usb_hcd *hcd)
- struct ohci_hcd *ohci = hcd_to_ohci (hcd);
- int ret;
-
-- if(hcd->self.controller && hcd->self.controller->bus == &pci_bus_type) {
-+ /* REVISIT this whole block should move to reset(), which handles
-+ * all the other one-time init.
-+ */
-+ if (hcd->self.controller) {
- struct pci_dev *pdev = to_pci_dev(hcd->self.controller);
-
- /* AMD 756, for most chips (early revs), corrupts register
-@@ -45,7 +48,8 @@ ohci_pci_start (struct usb_hcd *hcd)
- && pdev->device == 0x740c) {
- ohci->flags = OHCI_QUIRK_AMD756;
- ohci_dbg (ohci, "AMD756 erratum 4 workaround\n");
-- // also somewhat erratum 10 (suspend/resume issues)
-+ /* also erratum 10 (suspend/resume issues) */
-+ device_init_wakeup(&hcd->self.root_hub->dev, 0);
- }
-
- /* FIXME for some of the early AMD 760 southbridges, OHCI
-@@ -88,6 +92,13 @@ ohci_pci_start (struct usb_hcd *hcd)
- ohci_dbg (ohci,
- "enabled Compaq ZFMicro chipset quirk\n");
- }
-+
-+ /* RWC may not be set for add-in PCI cards, since boot
-+ * firmware probably ignored them. This transfers PCI
-+ * PM wakeup capabilities (once the PCI layer is fixed).
-+ */
-+ if (device_may_wakeup(&pdev->dev))
-+ ohci->hc_control |= OHCI_CTRL_RWC;
- }
-
- /* NOTE: there may have already been a first reset, to
diff --git a/usb/usb-optimise-devio.c-usbdev_read-fix.patch b/usb/usb-optimise-devio.c-usbdev_read-fix.patch
deleted file mode 100644
index 8a446cd0249f4..0000000000000
--- a/usb/usb-optimise-devio.c-usbdev_read-fix.patch
+++ /dev/null
@@ -1,43 +0,0 @@
-From akpm@osdl.org Wed Jan 18 23:55:40 2006
-Message-Id: <200601190755.k0J7tLRO027507@shell0.pdx.osdl.net>
-From: Andrew Morton <akpm@osdl.org>
-Subject: USB: optimise devio.c usbdev_read fix
-To: greg@kroah.com
-Cc: akpm@osdl.org, gregkh@suse.de, oliver@neukum.org, zaitcev@redhat.com
-From: akpm@osdl.org
-Date: Wed, 18 Jan 2006 23:55:07 -0800
-
-
-From: Andrew Morton <akpm@osdl.org>
-
-drivers/usb/core/devio.c: In function `usbdev_read':
-drivers/usb/core/devio.c:140: error: invalid type argument of `->'
-drivers/usb/core/devio.c:141: error: invalid type argument of `->'
-drivers/usb/core/devio.c:142: error: invalid type argument of `->'
-drivers/usb/core/devio.c:143: error: invalid type argument of `->'
-
-Cc: Oliver Neukum <oliver@neukum.org>
-Cc: Pete Zaitcev <zaitcev@redhat.com>
-Signed-off-by: Andrew Morton <akpm@osdl.org>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
----
- drivers/usb/core/devio.c | 8 ++++----
- 1 file changed, 4 insertions(+), 4 deletions(-)
-
---- gregkh-2.6.orig/drivers/usb/core/devio.c
-+++ gregkh-2.6/drivers/usb/core/devio.c
-@@ -137,10 +137,10 @@ static ssize_t usbdev_read(struct file *
- struct usb_device_descriptor temp_desc ; /* 18 bytes - fits on the stack */
-
- memcpy(&temp_desc, &dev->descriptor, sizeof(dev->descriptor));
-- le16_to_cpus(&temp_desc->bcdUSB);
-- le16_to_cpus(&temp_desc->idVendor);
-- le16_to_cpus(&temp_desc->idProduct);
-- le16_to_cpus(&temp_desc->bcdDevice);
-+ le16_to_cpus(&temp_desc.bcdUSB);
-+ le16_to_cpus(&temp_desc.idVendor);
-+ le16_to_cpus(&temp_desc.idProduct);
-+ le16_to_cpus(&temp_desc.bcdDevice);
-
- len = sizeof(struct usb_device_descriptor) - pos;
- if (len > nbytes)
diff --git a/usb/usb-optimise-devio.c-usbdev_read.patch b/usb/usb-optimise-devio.c-usbdev_read.patch
deleted file mode 100644
index f7585a6bc75fa..0000000000000
--- a/usb/usb-optimise-devio.c-usbdev_read.patch
+++ /dev/null
@@ -1,56 +0,0 @@
-From linux-usb-devel-admin@lists.sourceforge.net Fri Jan 6 12:51:44 2006
-From: Oliver Neukum <oliver@neukum.org>
-To: Pete Zaitcev <zaitcev@redhat.com>
-Subject: USB: optimise devio.c::usbdev_read
-Cc: gregkh@suse.de
-Content-Disposition: inline
-Message-Id: <200601062124.25970.oliver@neukum.org>
-Date: Fri, 6 Jan 2006 21:24:25 +0100
-
-this is a small optimisation. It is ridiculous to do a kmalloc for
-18 bytes. This puts it onto the stack.
-
-Signed-off-by: Oliver Neukum <oliver@neukum.name>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-
----
- drivers/usb/core/devio.c | 21 ++++++++-------------
- 1 file changed, 8 insertions(+), 13 deletions(-)
-
---- gregkh-2.6.orig/drivers/usb/core/devio.c
-+++ gregkh-2.6/drivers/usb/core/devio.c
-@@ -134,26 +134,21 @@ static ssize_t usbdev_read(struct file *
- }
-
- if (pos < sizeof(struct usb_device_descriptor)) {
-- struct usb_device_descriptor *desc = kmalloc(sizeof(*desc), GFP_KERNEL);
-- if (!desc) {
-- ret = -ENOMEM;
-- goto err;
-- }
-- memcpy(desc, &dev->descriptor, sizeof(dev->descriptor));
-- le16_to_cpus(&desc->bcdUSB);
-- le16_to_cpus(&desc->idVendor);
-- le16_to_cpus(&desc->idProduct);
-- le16_to_cpus(&desc->bcdDevice);
-+ struct usb_device_descriptor temp_desc ; /* 18 bytes - fits on the stack */
-+
-+ memcpy(&temp_desc, &dev->descriptor, sizeof(dev->descriptor));
-+ le16_to_cpus(&temp_desc->bcdUSB);
-+ le16_to_cpus(&temp_desc->idVendor);
-+ le16_to_cpus(&temp_desc->idProduct);
-+ le16_to_cpus(&temp_desc->bcdDevice);
-
- len = sizeof(struct usb_device_descriptor) - pos;
- if (len > nbytes)
- len = nbytes;
-- if (copy_to_user(buf, ((char *)desc) + pos, len)) {
-- kfree(desc);
-+ if (copy_to_user(buf, ((char *)&temp_desc) + pos, len)) {
- ret = -EFAULT;
- goto err;
- }
-- kfree(desc);
-
- *ppos += len;
- buf += len;
diff --git a/usb/usb-pegasus-linksys-usbvpn1-support-cleanup.patch b/usb/usb-pegasus-linksys-usbvpn1-support-cleanup.patch
deleted file mode 100644
index 1b44ddefdd396..0000000000000
--- a/usb/usb-pegasus-linksys-usbvpn1-support-cleanup.patch
+++ /dev/null
@@ -1,104 +0,0 @@
-From linux-usb-devel-admin@lists.sourceforge.net Sat Jan 28 08:49:09 2006
-From: Malte Doersam <mdoersam@arcor.de>
-Message-Id: <200601281748.33177.mdoersam@arcor.de>
-Subject: USB: Pegasus: Linksys USBVPN1 support + cleanup
-Date: Sat, 28 Jan 2006 17:48:33 +0100
-
-This patch adds a second linksys vendor-id (077b) and the product id of the
-pegasus based adapter USBVPN1
-
-http://www1.linksys.com/Products/product.asp?prid=3D543&scid=3D30
-
-Furthermore it replaces all LINKSYS_GPIO_RESET with DEFAULT_GPIO_RESET as both
-are declared like this:
-#define DEFAULT_GPIO_RESET 0x24
-#define LINKSYS_GPIO_RESET 0x24
-
-This is misleading and confusing.
-The check is now done via the VENDOR_ID in pegasus.c:
-if (usb_dev_id[pegasus->dev_index].vendor == VENDOR_LINKSYS
-
-Signed-off-by: Malte Doersam <mdoersam@arcor.de>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-
-
----
- drivers/usb/net/pegasus.c | 1 +
- drivers/usb/net/pegasus.h | 26 ++++++++++++++------------
- 2 files changed, 15 insertions(+), 12 deletions(-)
-
---- gregkh-2.6.orig/drivers/usb/net/pegasus.c
-+++ gregkh-2.6/drivers/usb/net/pegasus.c
-@@ -524,6 +524,7 @@ static int enable_net_traffic(struct net
- ret = set_registers(pegasus, EthCtrl0, 3, data);
-
- if (usb_dev_id[pegasus->dev_index].vendor == VENDOR_LINKSYS ||
-+ usb_dev_id[pegasus->dev_index].vendor == VENDOR_LINKSYS2 ||
- usb_dev_id[pegasus->dev_index].vendor == VENDOR_DLINK) {
- u16 auxmode;
- read_mii_word(pegasus, 0, 0x1b, &auxmode);
---- gregkh-2.6.orig/drivers/usb/net/pegasus.h
-+++ gregkh-2.6/drivers/usb/net/pegasus.h
-@@ -25,7 +25,6 @@
- #define PHY_READ 0x40
- #define PHY_WRITE 0x20
- #define DEFAULT_GPIO_RESET 0x24
--#define LINKSYS_GPIO_RESET 0x24
- #define DEFAULT_GPIO_SET 0x26
-
- #define PEGASUS_PRESENT 0x00000001
-@@ -140,6 +139,7 @@ struct usb_eth_dev {
- #define VENDOR_KINGSTON 0x0951
- #define VENDOR_LANEED 0x056e
- #define VENDOR_LINKSYS 0x066b
-+#define VENDOR_LINKSYS2 0x077b
- #define VENDOR_MELCO 0x0411
- #define VENDOR_MICROSOFT 0x045e
- #define VENDOR_MOBILITY 0x1342
-@@ -218,15 +218,15 @@ PEGASUS_DEV( "Corega FEter USB-TX", VEND
- PEGASUS_DEV( "Corega FEter USB-TXS", VENDOR_COREGA, 0x000d,
- DEFAULT_GPIO_RESET | PEGASUS_II )
- PEGASUS_DEV( "D-Link DSB-650TX", VENDOR_DLINK, 0x4001,
-- LINKSYS_GPIO_RESET )
-+ DEFAULT_GPIO_RESET )
- PEGASUS_DEV( "D-Link DSB-650TX", VENDOR_DLINK, 0x4002,
-- LINKSYS_GPIO_RESET )
-+ DEFAULT_GPIO_RESET )
- PEGASUS_DEV( "D-Link DSB-650TX", VENDOR_DLINK, 0x4102,
-- LINKSYS_GPIO_RESET | PEGASUS_II )
-+ DEFAULT_GPIO_RESET | PEGASUS_II )
- PEGASUS_DEV( "D-Link DSB-650TX", VENDOR_DLINK, 0x400b,
-- LINKSYS_GPIO_RESET | PEGASUS_II )
-+ DEFAULT_GPIO_RESET | PEGASUS_II )
- PEGASUS_DEV( "D-Link DSB-650TX", VENDOR_DLINK, 0x200c,
-- LINKSYS_GPIO_RESET | PEGASUS_II )
-+ DEFAULT_GPIO_RESET | PEGASUS_II )
- PEGASUS_DEV( "D-Link DSB-650TX(PNA)", VENDOR_DLINK, 0x4003,
- DEFAULT_GPIO_RESET | HAS_HOME_PNA )
- PEGASUS_DEV( "D-Link DSB-650", VENDOR_DLINK, 0xabc1,
-@@ -260,17 +260,19 @@ PEGASUS_DEV( "LANEED USB Ethernet LD-USB
- PEGASUS_DEV( "LANEED USB Ethernet LD-USB/TX", VENDOR_LANEED, 0x200c,
- DEFAULT_GPIO_RESET | PEGASUS_II )
- PEGASUS_DEV( "Linksys USB10TX", VENDOR_LINKSYS, 0x2202,
-- LINKSYS_GPIO_RESET )
-+ DEFAULT_GPIO_RESET )
- PEGASUS_DEV( "Linksys USB100TX", VENDOR_LINKSYS, 0x2203,
-- LINKSYS_GPIO_RESET )
-+ DEFAULT_GPIO_RESET )
- PEGASUS_DEV( "Linksys USB100TX", VENDOR_LINKSYS, 0x2204,
-- LINKSYS_GPIO_RESET | HAS_HOME_PNA )
-+ DEFAULT_GPIO_RESET | HAS_HOME_PNA )
- PEGASUS_DEV( "Linksys USB10T Ethernet Adapter", VENDOR_LINKSYS, 0x2206,
-- LINKSYS_GPIO_RESET | PEGASUS_II)
-+ DEFAULT_GPIO_RESET | PEGASUS_II)
-+PEGASUS_DEV( "Linksys USBVPN1", VENDOR_LINKSYS2, 0x08b4,
-+ DEFAULT_GPIO_RESET )
- PEGASUS_DEV( "Linksys USB USB100TX", VENDOR_LINKSYS, 0x400b,
-- LINKSYS_GPIO_RESET | PEGASUS_II )
-+ DEFAULT_GPIO_RESET | PEGASUS_II )
- PEGASUS_DEV( "Linksys USB10TX", VENDOR_LINKSYS, 0x200c,
-- LINKSYS_GPIO_RESET | PEGASUS_II )
-+ DEFAULT_GPIO_RESET | PEGASUS_II )
- PEGASUS_DEV( "MELCO/BUFFALO LUA-TX", VENDOR_MELCO, 0x0001,
- DEFAULT_GPIO_RESET )
- PEGASUS_DEV( "MELCO/BUFFALO LUA-TX", VENDOR_MELCO, 0x0005,
diff --git a/usb/usb-pl2303-and-tiocmiwait.patch b/usb/usb-pl2303-and-tiocmiwait.patch
deleted file mode 100644
index 5319796e1a8e5..0000000000000
--- a/usb/usb-pl2303-and-tiocmiwait.patch
+++ /dev/null
@@ -1,39 +0,0 @@
-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-remove-linux_version_code-macro-usage.patch b/usb/usb-remove-linux_version_code-macro-usage.patch
deleted file mode 100644
index 69cf4d0ed2bfa..0000000000000
--- a/usb/usb-remove-linux_version_code-macro-usage.patch
+++ /dev/null
@@ -1,82 +0,0 @@
-From penberg@cs.helsinki.fi Mon Jan 16 14:05:27 2006
-From: Pekka Enberg <penberg@cs.helsinki.fi>
-Subject: USB: remove LINUX_VERSION_CODE macro usage
-To: Greg KH <gregkh@suse.de>
-Date: Thu, 12 Jan 2006 20:35:25 +0200
-Message-Id: <1137090925.9933.0.camel@localhost>
-
-From: Pekka Enberg <penberg@cs.helsinki.fi>
-
-This patch removes unnecessary LINUX_VERSION_CODE macro usage from
-drivers/usb/.
-
-Signed-off-by: Pekka Enberg <penberg@cs.helsinki.fi>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
----
- drivers/usb/media/pwc/pwc-ctrl.c | 1 -
- drivers/usb/media/pwc/pwc-if.c | 6 +-----
- drivers/usb/misc/sisusbvga/sisusb.h | 8 --------
- 3 files changed, 1 insertion(+), 14 deletions(-)
-
---- gregkh-2.6.orig/drivers/usb/media/pwc/pwc-ctrl.c
-+++ gregkh-2.6/drivers/usb/media/pwc/pwc-ctrl.c
-@@ -41,7 +41,6 @@
- #include <asm/uaccess.h>
- #endif
- #include <asm/errno.h>
--#include <linux/version.h>
-
- #include "pwc.h"
- #include "pwc-ioctl.h"
---- gregkh-2.6.orig/drivers/usb/media/pwc/pwc-if.c
-+++ gregkh-2.6/drivers/usb/media/pwc/pwc-if.c
-@@ -62,7 +62,6 @@
- #include <linux/poll.h>
- #include <linux/slab.h>
- #include <linux/vmalloc.h>
--#include <linux/version.h>
- #include <asm/io.h>
-
- #include "pwc.h"
-@@ -827,13 +826,10 @@ static int pwc_isoc_init(struct pwc_devi
- /* Get the current alternate interface, adjust packet size */
- if (!udev->actconfig)
- return -EFAULT;
--#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,5)
-- idesc = &udev->actconfig->interface[0]->altsetting[pdev->valternate];
--#else
-+
- intf = usb_ifnum_to_if(udev, 0);
- if (intf)
- idesc = usb_altnum_to_altsetting(intf, pdev->valternate);
--#endif
-
- if (!idesc)
- return -EFAULT;
---- gregkh-2.6.orig/drivers/usb/misc/sisusbvga/sisusb.h
-+++ gregkh-2.6/drivers/usb/misc/sisusbvga/sisusb.h
-@@ -37,24 +37,16 @@
- #ifndef _SISUSB_H_
- #define _SISUSB_H_
-
--#include <linux/version.h>
- #ifdef CONFIG_COMPAT
--#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,10)
--#include <linux/ioctl32.h>
--#define SISUSB_OLD_CONFIG_COMPAT
--#else
- #define SISUSB_NEW_CONFIG_COMPAT
- #endif
--#endif
-
- /* For older kernels, support for text consoles is by default
- * off. To ensable text console support, change the following:
- */
- #if 0
--#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,13)
- #define CONFIG_USB_SISUSBVGA_CON
- #endif
--#endif
-
- /* Version Information */
-
diff --git a/usb/usb-remove-obsolete_oss_usb_driver-drivers.patch b/usb/usb-remove-obsolete_oss_usb_driver-drivers.patch
deleted file mode 100644
index 2f3e82d030d85..0000000000000
--- a/usb/usb-remove-obsolete_oss_usb_driver-drivers.patch
+++ /dev/null
@@ -1,6407 +0,0 @@
-From bunk@stusta.de Sat Feb 4 17:03:30 2006
-Date: Sun, 5 Feb 2006 00:03:28 +0100
-From: Adrian Bunk <bunk@stusta.de>
-To: greg@kroah.com
-Subject: USB: remove OBSOLETE_OSS_USB_DRIVER drivers
-Message-ID: <20060204230328.GE4528@stusta.de>
-Content-Disposition: inline
-
-This patch removes the obsolete USB_MIDI and USB_AUDIO drivers.
-
-Signed-off-by: Adrian Bunk <bunk@stusta.de>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-
----
- drivers/usb/Makefile | 2
- drivers/usb/class/Kconfig | 47
- drivers/usb/class/Makefile | 2
- drivers/usb/class/audio.c | 3869 -------------------------------------------
- drivers/usb/class/audio.h | 110 -
- drivers/usb/class/usb-midi.c | 2153 -----------------------
- drivers/usb/class/usb-midi.h | 164 -
- 7 files changed, 6347 deletions(-)
-
---- gregkh-2.6.orig/drivers/usb/Makefile
-+++ gregkh-2.6/drivers/usb/Makefile
-@@ -17,8 +17,6 @@ obj-$(CONFIG_USB_SL811_HCD) += host/
- obj-$(CONFIG_ETRAX_USB_HOST) += host/
-
- obj-$(CONFIG_USB_ACM) += class/
--obj-$(CONFIG_USB_AUDIO) += class/
--obj-$(CONFIG_USB_MIDI) += class/
- obj-$(CONFIG_USB_PRINTER) += class/
-
- obj-$(CONFIG_USB_STORAGE) += storage/
---- gregkh-2.6.orig/drivers/usb/class/Kconfig
-+++ gregkh-2.6/drivers/usb/class/Kconfig
-@@ -4,53 +4,6 @@
- comment "USB Device Class drivers"
- depends on USB
-
--config OBSOLETE_OSS_USB_DRIVER
-- bool "Obsolete OSS USB drivers"
-- depends on USB && SOUND
-- help
-- This option enables support for the obsolete USB Audio and Midi
-- drivers that are scheduled for removal in the near future since
-- there are ALSA drivers for the same hardware.
--
-- Please contact Adrian Bunk <bunk@stusta.de> if you had to
-- say Y here because of missing support in the ALSA drivers.
--
-- If unsure, say N.
--
--config USB_AUDIO
-- tristate "USB Audio support"
-- depends on USB && SOUND && OBSOLETE_OSS_USB_DRIVER
-- help
-- Say Y here if you want to connect USB audio equipment such as
-- speakers to your computer's USB port. You only need this if you use
-- the OSS sound driver; ALSA has its own option for usb audio support.
--
-- To compile this driver as a module, choose M here: the
-- module will be called audio.
--
--config USB_MIDI
-- tristate "USB MIDI support"
-- depends on USB && SOUND && OBSOLETE_OSS_USB_DRIVER
-- ---help---
-- Say Y here if you want to connect a USB MIDI device to your
-- computer's USB port. You only need this if you use the OSS
-- sound system; USB MIDI devices are supported by ALSA's USB
-- audio driver. This driver is for devices that comply with
-- 'Universal Serial Bus Device Class Definition for MIDI Device'.
--
-- The following devices are known to work:
-- * Steinberg USB2MIDI
-- * Roland MPU64
-- * Roland PC-300
-- * Roland SC8850
-- * Roland UM-1
-- * Roland UM-2
-- * Roland UA-100
-- * Yamaha MU1000
--
-- To compile this driver as a module, choose M here: the
-- module will be called usb-midi.
--
- config USB_ACM
- tristate "USB Modem (CDC ACM) support"
- depends on USB
---- gregkh-2.6.orig/drivers/usb/class/Makefile
-+++ gregkh-2.6/drivers/usb/class/Makefile
-@@ -4,6 +4,4 @@
- #
-
- obj-$(CONFIG_USB_ACM) += cdc-acm.o
--obj-$(CONFIG_USB_AUDIO) += audio.o
--obj-$(CONFIG_USB_MIDI) += usb-midi.o
- obj-$(CONFIG_USB_PRINTER) += usblp.o
---- gregkh-2.6.orig/drivers/usb/class/audio.c
-+++ /dev/null
-@@ -1,3869 +0,0 @@
--/*****************************************************************************/
--
--/*
-- * audio.c -- USB Audio Class driver
-- *
-- * Copyright (C) 1999, 2000, 2001, 2003, 2004
-- * Alan Cox (alan@lxorguk.ukuu.org.uk)
-- * Thomas Sailer (sailer@ife.ee.ethz.ch)
-- *
-- * 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.
-- *
-- * Debugging:
-- * Use the 'lsusb' utility to dump the descriptors.
-- *
-- * 1999-09-07: Alan Cox
-- * Parsing Audio descriptor patch
-- * 1999-09-08: Thomas Sailer
-- * Added OSS compatible data io functions; both parts of the
-- * driver remain to be glued together
-- * 1999-09-10: Thomas Sailer
-- * Beautified the driver. Added sample format conversions.
-- * Still not properly glued with the parsing code.
-- * The parsing code seems to have its problems btw,
-- * Since it parses all available configs but doesn't
-- * store which iface/altsetting belongs to which config.
-- * 1999-09-20: Thomas Sailer
-- * Threw out Alan's parsing code and implemented my own one.
-- * You cannot reasonnably linearly parse audio descriptors,
-- * especially the AudioClass descriptors have to be considered
-- * pointer lists. Mixer parsing untested, due to lack of device.
-- * First stab at synch pipe implementation, the Dallas USB DAC
-- * wants to use an Asynch out pipe. usb_audio_state now basically
-- * only contains lists of mixer and wave devices. We can therefore
-- * now have multiple mixer/wave devices per USB device.
-- * 1999-10-28: Thomas Sailer
-- * Converted to URB API. Fixed a taskstate/wakeup semantics mistake
-- * that made the driver consume all available CPU cycles.
-- * Now runs stable on UHCI-Acher/Fliegl/Sailer.
-- * 1999-10-31: Thomas Sailer
-- * Audio can now be unloaded if it is not in use by any mixer
-- * or dsp client (formerly you had to disconnect the audio devices
-- * from the USB port)
-- * Finally, about three months after ordering, my "Maxxtro SPK222"
-- * speakers arrived, isn't disdata a great mail order company 8-)
-- * Parse class specific endpoint descriptor of the audiostreaming
-- * interfaces and take the endpoint attributes from there.
-- * Unbelievably, the Philips USB DAC has a sampling rate range
-- * of over a decade, yet does not support the sampling rate control!
-- * No wonder it sounds so bad, has very audible sampling rate
-- * conversion distortion. Don't try to listen to it using
-- * decent headphones!
-- * "Let's make things better" -> but please Philips start with your
-- * own stuff!!!!
-- * 1999-11-02: Thomas Sailer
-- * It takes the Philips boxes several seconds to acquire synchronisation
-- * that means they won't play short sounds. Should probably maintain
-- * the ISO datastream even if there's nothing to play.
-- * Fix counting the total_bytes counter, RealPlayer G2 depends on it.
-- * 1999-12-20: Thomas Sailer
-- * Fix bad bug in conversion to per interface probing.
-- * disconnect was called multiple times for the audio device,
-- * leading to a premature freeing of the audio structures
-- * 2000-05-13: Thomas Sailer
-- * I don't remember who changed the find_format routine,
-- * but the change was completely broken for the Dallas
-- * chip. Anyway taking sampling rate into account in find_format
-- * is bad and should not be done unless there are devices with
-- * completely broken audio descriptors. Unless someone shows
-- * me such a descriptor, I will not allow find_format to
-- * take the sampling rate into account.
-- * Also, the former find_format made:
-- * - mpg123 play mono instead of stereo
-- * - sox completely fail for wav's with sample rates < 44.1kHz
-- * for the Dallas chip.
-- * Also fix a rather long standing problem with applications that
-- * use "small" writes producing no sound at all.
-- * 2000-05-15: Thomas Sailer
-- * My fears came true, the Philips camera indeed has pretty stupid
-- * audio descriptors.
-- * 2000-05-17: Thomas Sailer
-- * Nemsoft spotted my stupid last minute change, thanks
-- * 2000-05-19: Thomas Sailer
-- * Fixed FEATURE_UNIT thinkos found thanks to the KC Technology
-- * Xtend device. Basically the driver treated FEATURE_UNIT's sourced
-- * by mono terminals as stereo.
-- * 2000-05-20: Thomas Sailer
-- * SELECTOR support (and thus selecting record channels from the mixer).
-- * Somewhat peculiar due to OSS interface limitations. Only works
-- * for channels where a "slider" is already in front of it (i.e.
-- * a MIXER unit or a FEATURE unit with volume capability).
-- * 2000-11-26: Thomas Sailer
-- * Workaround for Dallas DS4201. The DS4201 uses PCM8 as format tag for
-- * its 8 bit modes, but expects signed data (and should therefore have used PCM).
-- * 2001-03-10: Thomas Sailer
-- * provide abs function, prevent picking up a bogus kernel macro
-- * for abs. Bug report by Andrew Morton <andrewm@uow.edu.au>
-- * 2001-06-16: Bryce Nesbitt <bryce@obviously.com>
-- * Fix SNDCTL_DSP_STEREO API violation
-- * 2003-04-08: Oliver Neukum (oliver@neukum.name):
-- * Setting a configuration is done by usbcore and must not be overridden
-- * 2004-02-27: Workaround for broken synch descriptors
-- * 2004-03-07: Alan Stern <stern@rowland.harvard.edu>
-- * Add usb_ifnum_to_if() and usb_altnum_to_altsetting() support.
-- * Use the in-memory descriptors instead of reading them from the device.
-- *
-- */
--
--/*
-- * Strategy:
-- *
-- * Alan Cox and Thomas Sailer are starting to dig at opposite ends and
-- * are hoping to meet in the middle, just like tunnel diggers :)
-- * Alan tackles the descriptor parsing, Thomas the actual data IO and the
-- * OSS compatible interface.
-- *
-- * Data IO implementation issues
-- *
-- * A mmap'able ring buffer per direction is implemented, because
-- * almost every OSS app expects it. It is however impractical to
-- * transmit/receive USB data directly into and out of the ring buffer,
-- * due to alignment and synchronisation issues. Instead, the ring buffer
-- * feeds a constant time delay line that handles the USB issues.
-- *
-- * Now we first try to find an alternate setting that exactly matches
-- * the sample format requested by the user. If we find one, we do not
-- * need to perform any sample rate conversions. If there is no matching
-- * altsetting, we choose the closest one and perform sample format
-- * conversions. We never do sample rate conversion; these are too
-- * expensive to be performed in the kernel.
-- *
-- * Current status: no known HCD-specific issues.
-- *
-- * Generally: Due to the brokenness of the Audio Class spec
-- * it seems generally impossible to write a generic Audio Class driver,
-- * so a reasonable driver should implement the features that are actually
-- * used.
-- *
-- * Parsing implementation issues
-- *
-- * One cannot reasonably parse the AudioClass descriptors linearly.
-- * Therefore the current implementation features routines to look
-- * for a specific descriptor in the descriptor list.
-- *
-- * How does the parsing work? First, all interfaces are searched
-- * for an AudioControl class interface. If found, the config descriptor
-- * that belongs to the current configuration is searched and
-- * the HEADER descriptor is found. It contains a list of
-- * all AudioStreaming and MIDIStreaming devices. This list is then walked,
-- * and all AudioStreaming interfaces are classified into input and output
-- * interfaces (according to the endpoint0 direction in altsetting1) (MIDIStreaming
-- * is currently not supported). The input & output list is then used
-- * to group inputs and outputs together and issued pairwise to the
-- * AudioStreaming class parser. Finally, all OUTPUT_TERMINAL descriptors
-- * are walked and issued to the mixer construction routine.
-- *
-- * The AudioStreaming parser simply enumerates all altsettings belonging
-- * to the specified interface. It looks for AS_GENERAL and FORMAT_TYPE
-- * class specific descriptors to extract the sample format/sample rate
-- * data. Only sample format types PCM and PCM8 are supported right now, and
-- * only FORMAT_TYPE_I is handled. The isochronous data endpoint needs to
-- * be the first endpoint of the interface, and the optional synchronisation
-- * isochronous endpoint the second one.
-- *
-- * Mixer construction works as follows: The various TERMINAL and UNIT
-- * descriptors span a tree from the root (OUTPUT_TERMINAL) through the
-- * intermediate nodes (UNITs) to the leaves (INPUT_TERMINAL). We walk
-- * that tree in a depth first manner. FEATURE_UNITs may contribute volume,
-- * bass and treble sliders to the mixer, MIXER_UNITs volume sliders.
-- * The terminal type encoded in the INPUT_TERMINALs feeds a heuristic
-- * to determine "meaningful" OSS slider numbers, however we will see
-- * how well this works in practice. Other features are not used at the
-- * moment, they seem less often used. Also, it seems difficult at least
-- * to construct recording source switches from SELECTOR_UNITs, but
-- * since there are not many USB ADC's available, we leave that for later.
-- */
--
--/*****************************************************************************/
--
--#include <linux/kernel.h>
--#include <linux/slab.h>
--#include <linux/string.h>
--#include <linux/timer.h>
--#include <linux/sched.h>
--#include <linux/smp_lock.h>
--#include <linux/module.h>
--#include <linux/sound.h>
--#include <linux/soundcard.h>
--#include <linux/list.h>
--#include <linux/vmalloc.h>
--#include <linux/init.h>
--#include <linux/poll.h>
--#include <linux/bitops.h>
--#include <asm/uaccess.h>
--#include <asm/io.h>
--#include <linux/usb.h>
--
--#include "audio.h"
--
--/*
-- * Version Information
-- */
--#define DRIVER_VERSION "v1.0.0"
--#define DRIVER_AUTHOR "Alan Cox <alan@lxorguk.ukuu.org.uk>, Thomas Sailer (sailer@ife.ee.ethz.ch)"
--#define DRIVER_DESC "USB Audio Class driver"
--
--#define AUDIO_DEBUG 1
--
--#define SND_DEV_DSP16 5
--
--#define dprintk(x)
--
--/* --------------------------------------------------------------------- */
--
--/*
-- * Linked list of all audio devices...
-- */
--static struct list_head audiodevs = LIST_HEAD_INIT(audiodevs);
--static DECLARE_MUTEX(open_sem);
--
--/*
-- * wait queue for processes wanting to open an USB audio device
-- */
--static DECLARE_WAIT_QUEUE_HEAD(open_wait);
--
--
--#define MAXFORMATS MAX_ALT
--#define DMABUFSHIFT 17 /* 128k worth of DMA buffer */
--#define NRSGBUF (1U<<(DMABUFSHIFT-PAGE_SHIFT))
--
--/*
-- * This influences:
-- * - Latency
-- * - Interrupt rate
-- * - Synchronisation behaviour
-- * Don't touch this if you don't understand all of the above.
-- */
--#define DESCFRAMES 5
--#define SYNCFRAMES DESCFRAMES
--
--#define MIXFLG_STEREOIN 1
--#define MIXFLG_STEREOOUT 2
--
--struct mixerchannel {
-- __u16 value;
-- __u16 osschannel; /* number of the OSS channel */
-- __s16 minval, maxval;
-- __u16 slctunitid;
-- __u8 unitid;
-- __u8 selector;
-- __u8 chnum;
-- __u8 flags;
--};
--
--struct audioformat {
-- unsigned int format;
-- unsigned int sratelo;
-- unsigned int sratehi;
-- unsigned char altsetting;
-- unsigned char attributes;
--};
--
--struct dmabuf {
-- /* buffer data format */
-- unsigned int format;
-- unsigned int srate;
-- /* physical buffer */
-- unsigned char *sgbuf[NRSGBUF];
-- unsigned bufsize;
-- unsigned numfrag;
-- unsigned fragshift;
-- unsigned wrptr, rdptr;
-- unsigned total_bytes;
-- int count;
-- unsigned error; /* over/underrun */
-- wait_queue_head_t wait;
-- /* redundant, but makes calculations easier */
-- unsigned fragsize;
-- unsigned dmasize;
-- /* OSS stuff */
-- unsigned mapped:1;
-- unsigned ready:1;
-- unsigned ossfragshift;
-- int ossmaxfrags;
-- unsigned subdivision;
--};
--
--struct usb_audio_state;
--
--#define FLG_URB0RUNNING 1
--#define FLG_URB1RUNNING 2
--#define FLG_SYNC0RUNNING 4
--#define FLG_SYNC1RUNNING 8
--#define FLG_RUNNING 16
--#define FLG_CONNECTED 32
--
--struct my_data_urb {
-- struct urb *urb;
--};
--
--struct my_sync_urb {
-- struct urb *urb;
--};
--
--
--struct usb_audiodev {
-- struct list_head list;
-- struct usb_audio_state *state;
--
-- /* soundcore stuff */
-- int dev_audio;
--
-- /* wave stuff */
-- mode_t open_mode;
-- spinlock_t lock; /* DMA buffer access spinlock */
--
-- struct usbin {
-- int interface; /* Interface number, -1 means not used */
-- unsigned int format; /* USB data format */
-- unsigned int datapipe; /* the data input pipe */
-- unsigned int syncpipe; /* the synchronisation pipe - 0 for anything but adaptive IN mode */
-- unsigned int syncinterval; /* P for adaptive IN mode, 0 otherwise */
-- unsigned int freqn; /* nominal sampling rate in USB format, i.e. fs/1000 in Q10.14 */
-- unsigned int freqmax; /* maximum sampling rate, used for buffer management */
-- unsigned int phase; /* phase accumulator */
-- unsigned int flags; /* see FLG_ defines */
--
-- struct my_data_urb durb[2]; /* ISO descriptors for the data endpoint */
-- struct my_sync_urb surb[2]; /* ISO sync pipe descriptor if needed */
--
-- struct dmabuf dma;
-- } usbin;
--
-- struct usbout {
-- int interface; /* Interface number, -1 means not used */
-- unsigned int format; /* USB data format */
-- unsigned int datapipe; /* the data input pipe */
-- unsigned int syncpipe; /* the synchronisation pipe - 0 for anything but asynchronous OUT mode */
-- unsigned int syncinterval; /* P for asynchronous OUT mode, 0 otherwise */
-- unsigned int freqn; /* nominal sampling rate in USB format, i.e. fs/1000 in Q10.14 */
-- unsigned int freqm; /* momentary sampling rate in USB format, i.e. fs/1000 in Q10.14 */
-- unsigned int freqmax; /* maximum sampling rate, used for buffer management */
-- unsigned int phase; /* phase accumulator */
-- unsigned int flags; /* see FLG_ defines */
--
-- struct my_data_urb durb[2]; /* ISO descriptors for the data endpoint */
-- struct my_sync_urb surb[2]; /* ISO sync pipe descriptor if needed */
--
-- struct dmabuf dma;
-- } usbout;
--
--
-- unsigned int numfmtin, numfmtout;
-- struct audioformat fmtin[MAXFORMATS];
-- struct audioformat fmtout[MAXFORMATS];
--};
--
--struct usb_mixerdev {
-- struct list_head list;
-- struct usb_audio_state *state;
--
-- /* soundcore stuff */
-- int dev_mixer;
--
-- unsigned char iface; /* interface number of the AudioControl interface */
--
-- /* USB format descriptions */
-- unsigned int numch, modcnt;
--
-- /* mixch is last and gets allocated dynamically */
-- struct mixerchannel ch[0];
--};
--
--struct usb_audio_state {
-- struct list_head audiodev;
--
-- /* USB device */
-- struct usb_device *usbdev;
--
-- struct list_head audiolist;
-- struct list_head mixerlist;
--
-- unsigned count; /* usage counter; NOTE: the usb stack is also considered a user */
--};
--
--/* private audio format extensions */
--#define AFMT_STEREO 0x80000000
--#define AFMT_ISSTEREO(x) ((x) & AFMT_STEREO)
--#define AFMT_IS16BIT(x) ((x) & (AFMT_S16_LE|AFMT_S16_BE|AFMT_U16_LE|AFMT_U16_BE))
--#define AFMT_ISUNSIGNED(x) ((x) & (AFMT_U8|AFMT_U16_LE|AFMT_U16_BE))
--#define AFMT_BYTESSHIFT(x) ((AFMT_ISSTEREO(x) ? 1 : 0) + (AFMT_IS16BIT(x) ? 1 : 0))
--#define AFMT_BYTES(x) (1<<AFMT_BYTESSHFIT(x))
--
--/* --------------------------------------------------------------------- */
--
--static inline unsigned ld2(unsigned int x)
--{
-- unsigned r = 0;
--
-- if (x >= 0x10000) {
-- x >>= 16;
-- r += 16;
-- }
-- if (x >= 0x100) {
-- x >>= 8;
-- r += 8;
-- }
-- if (x >= 0x10) {
-- x >>= 4;
-- r += 4;
-- }
-- if (x >= 4) {
-- x >>= 2;
-- r += 2;
-- }
-- if (x >= 2)
-- r++;
-- return r;
--}
--
--/* --------------------------------------------------------------------- */
--
--/*
-- * OSS compatible ring buffer management. The ring buffer may be mmap'ed into
-- * an application address space.
-- *
-- * I first used the rvmalloc stuff copied from bttv. Alan Cox did not like it, so
-- * we now use an array of pointers to a single page each. This saves us the
-- * kernel page table manipulations, but we have to do a page table alike mechanism
-- * (though only one indirection) in software.
-- */
--
--static void dmabuf_release(struct dmabuf *db)
--{
-- unsigned int nr;
-- void *p;
--
-- for(nr = 0; nr < NRSGBUF; nr++) {
-- if (!(p = db->sgbuf[nr]))
-- continue;
-- ClearPageReserved(virt_to_page(p));
-- free_page((unsigned long)p);
-- db->sgbuf[nr] = NULL;
-- }
-- db->mapped = db->ready = 0;
--}
--
--static int dmabuf_init(struct dmabuf *db)
--{
-- unsigned int nr, bytepersec, bufs;
-- void *p;
--
-- /* initialize some fields */
-- db->rdptr = db->wrptr = db->total_bytes = db->count = db->error = 0;
-- /* calculate required buffer size */
-- bytepersec = db->srate << AFMT_BYTESSHIFT(db->format);
-- bufs = 1U << DMABUFSHIFT;
-- if (db->ossfragshift) {
-- if ((1000 << db->ossfragshift) < bytepersec)
-- db->fragshift = ld2(bytepersec/1000);
-- else
-- db->fragshift = db->ossfragshift;
-- } else {
-- db->fragshift = ld2(bytepersec/100/(db->subdivision ? db->subdivision : 1));
-- if (db->fragshift < 3)
-- db->fragshift = 3;
-- }
-- db->numfrag = bufs >> db->fragshift;
-- while (db->numfrag < 4 && db->fragshift > 3) {
-- db->fragshift--;
-- db->numfrag = bufs >> db->fragshift;
-- }
-- db->fragsize = 1 << db->fragshift;
-- if (db->ossmaxfrags >= 4 && db->ossmaxfrags < db->numfrag)
-- db->numfrag = db->ossmaxfrags;
-- db->dmasize = db->numfrag << db->fragshift;
-- for(nr = 0; nr < NRSGBUF; nr++) {
-- if (!db->sgbuf[nr]) {
-- p = (void *)get_zeroed_page(GFP_KERNEL);
-- if (!p)
-- return -ENOMEM;
-- db->sgbuf[nr] = p;
-- SetPageReserved(virt_to_page(p));
-- }
-- memset(db->sgbuf[nr], AFMT_ISUNSIGNED(db->format) ? 0x80 : 0, PAGE_SIZE);
-- if ((nr << PAGE_SHIFT) >= db->dmasize)
-- break;
-- }
-- db->bufsize = nr << PAGE_SHIFT;
-- db->ready = 1;
-- dprintk((KERN_DEBUG "usbaudio: dmabuf_init bytepersec %d bufs %d ossfragshift %d ossmaxfrags %d "
-- "fragshift %d fragsize %d numfrag %d dmasize %d bufsize %d fmt 0x%x srate %d\n",
-- bytepersec, bufs, db->ossfragshift, db->ossmaxfrags, db->fragshift, db->fragsize,
-- db->numfrag, db->dmasize, db->bufsize, db->format, db->srate));
-- return 0;
--}
--
--static int dmabuf_mmap(struct vm_area_struct *vma, struct dmabuf *db, unsigned long start, unsigned long size, pgprot_t prot)
--{
-- unsigned int nr;
--
-- if (!db->ready || db->mapped || (start | size) & (PAGE_SIZE-1) || size > db->bufsize)
-- return -EINVAL;
-- size >>= PAGE_SHIFT;
-- for(nr = 0; nr < size; nr++)
-- if (!db->sgbuf[nr])
-- return -EINVAL;
-- db->mapped = 1;
-- for(nr = 0; nr < size; nr++) {
-- unsigned long pfn;
--
-- pfn = virt_to_phys(db->sgbuf[nr]) >> PAGE_SHIFT;
-- if (remap_pfn_range(vma, start, pfn, PAGE_SIZE, prot))
-- return -EAGAIN;
-- start += PAGE_SIZE;
-- }
-- return 0;
--}
--
--static void dmabuf_copyin(struct dmabuf *db, const void *buffer, unsigned int size)
--{
-- unsigned int pgrem, rem;
--
-- db->total_bytes += size;
-- for (;;) {
-- if (size <= 0)
-- return;
-- pgrem = ((~db->wrptr) & (PAGE_SIZE-1)) + 1;
-- if (pgrem > size)
-- pgrem = size;
-- rem = db->dmasize - db->wrptr;
-- if (pgrem > rem)
-- pgrem = rem;
-- memcpy((db->sgbuf[db->wrptr >> PAGE_SHIFT]) + (db->wrptr & (PAGE_SIZE-1)), buffer, pgrem);
-- size -= pgrem;
-- buffer += pgrem;
-- db->wrptr += pgrem;
-- if (db->wrptr >= db->dmasize)
-- db->wrptr = 0;
-- }
--}
--
--static void dmabuf_copyout(struct dmabuf *db, void *buffer, unsigned int size)
--{
-- unsigned int pgrem, rem;
--
-- db->total_bytes += size;
-- for (;;) {
-- if (size <= 0)
-- return;
-- pgrem = ((~db->rdptr) & (PAGE_SIZE-1)) + 1;
-- if (pgrem > size)
-- pgrem = size;
-- rem = db->dmasize - db->rdptr;
-- if (pgrem > rem)
-- pgrem = rem;
-- memcpy(buffer, (db->sgbuf[db->rdptr >> PAGE_SHIFT]) + (db->rdptr & (PAGE_SIZE-1)), pgrem);
-- size -= pgrem;
-- buffer += pgrem;
-- db->rdptr += pgrem;
-- if (db->rdptr >= db->dmasize)
-- db->rdptr = 0;
-- }
--}
--
--static int dmabuf_copyin_user(struct dmabuf *db, unsigned int ptr, const void __user *buffer, unsigned int size)
--{
-- unsigned int pgrem, rem;
--
-- if (!db->ready || db->mapped)
-- return -EINVAL;
-- for (;;) {
-- if (size <= 0)
-- return 0;
-- pgrem = ((~ptr) & (PAGE_SIZE-1)) + 1;
-- if (pgrem > size)
-- pgrem = size;
-- rem = db->dmasize - ptr;
-- if (pgrem > rem)
-- pgrem = rem;
-- if (copy_from_user((db->sgbuf[ptr >> PAGE_SHIFT]) + (ptr & (PAGE_SIZE-1)), buffer, pgrem))
-- return -EFAULT;
-- size -= pgrem;
-- buffer += pgrem;
-- ptr += pgrem;
-- if (ptr >= db->dmasize)
-- ptr = 0;
-- }
--}
--
--static int dmabuf_copyout_user(struct dmabuf *db, unsigned int ptr, void __user *buffer, unsigned int size)
--{
-- unsigned int pgrem, rem;
--
-- if (!db->ready || db->mapped)
-- return -EINVAL;
-- for (;;) {
-- if (size <= 0)
-- return 0;
-- pgrem = ((~ptr) & (PAGE_SIZE-1)) + 1;
-- if (pgrem > size)
-- pgrem = size;
-- rem = db->dmasize - ptr;
-- if (pgrem > rem)
-- pgrem = rem;
-- if (copy_to_user(buffer, (db->sgbuf[ptr >> PAGE_SHIFT]) + (ptr & (PAGE_SIZE-1)), pgrem))
-- return -EFAULT;
-- size -= pgrem;
-- buffer += pgrem;
-- ptr += pgrem;
-- if (ptr >= db->dmasize)
-- ptr = 0;
-- }
--}
--
--/* --------------------------------------------------------------------- */
--/*
-- * USB I/O code. We do sample format conversion if necessary
-- */
--
--static void usbin_stop(struct usb_audiodev *as)
--{
-- struct usbin *u = &as->usbin;
-- unsigned long flags;
-- unsigned int i, notkilled = 1;
--
-- spin_lock_irqsave(&as->lock, flags);
-- u->flags &= ~FLG_RUNNING;
-- i = u->flags;
-- spin_unlock_irqrestore(&as->lock, flags);
-- while (i & (FLG_URB0RUNNING|FLG_URB1RUNNING|FLG_SYNC0RUNNING|FLG_SYNC1RUNNING)) {
-- if (notkilled)
-- schedule_timeout_interruptible(1);
-- else
-- schedule_timeout_uninterruptible(1);
-- spin_lock_irqsave(&as->lock, flags);
-- i = u->flags;
-- spin_unlock_irqrestore(&as->lock, flags);
-- if (notkilled && signal_pending(current)) {
-- if (i & FLG_URB0RUNNING)
-- usb_kill_urb(u->durb[0].urb);
-- if (i & FLG_URB1RUNNING)
-- usb_kill_urb(u->durb[1].urb);
-- if (i & FLG_SYNC0RUNNING)
-- usb_kill_urb(u->surb[0].urb);
-- if (i & FLG_SYNC1RUNNING)
-- usb_kill_urb(u->surb[1].urb);
-- notkilled = 0;
-- }
-- }
-- set_current_state(TASK_RUNNING);
-- kfree(u->durb[0].urb->transfer_buffer);
-- kfree(u->durb[1].urb->transfer_buffer);
-- kfree(u->surb[0].urb->transfer_buffer);
-- kfree(u->surb[1].urb->transfer_buffer);
-- u->durb[0].urb->transfer_buffer = u->durb[1].urb->transfer_buffer =
-- u->surb[0].urb->transfer_buffer = u->surb[1].urb->transfer_buffer = NULL;
--}
--
--static inline void usbin_release(struct usb_audiodev *as)
--{
-- usbin_stop(as);
--}
--
--static void usbin_disc(struct usb_audiodev *as)
--{
-- struct usbin *u = &as->usbin;
--
-- unsigned long flags;
--
-- spin_lock_irqsave(&as->lock, flags);
-- u->flags &= ~(FLG_RUNNING | FLG_CONNECTED);
-- spin_unlock_irqrestore(&as->lock, flags);
-- usbin_stop(as);
--}
--
--static void conversion(const void *ibuf, unsigned int ifmt, void *obuf, unsigned int ofmt, void *tmp, unsigned int scnt)
--{
-- unsigned int cnt, i;
-- __s16 *sp, *sp2, s;
-- unsigned char *bp;
--
-- cnt = scnt;
-- if (AFMT_ISSTEREO(ifmt))
-- cnt <<= 1;
-- sp = ((__s16 *)tmp) + cnt;
-- switch (ifmt & ~AFMT_STEREO) {
-- case AFMT_U8:
-- for (bp = ((unsigned char *)ibuf)+cnt, i = 0; i < cnt; i++) {
-- bp--;
-- sp--;
-- *sp = (*bp ^ 0x80) << 8;
-- }
-- break;
--
-- case AFMT_S8:
-- for (bp = ((unsigned char *)ibuf)+cnt, i = 0; i < cnt; i++) {
-- bp--;
-- sp--;
-- *sp = *bp << 8;
-- }
-- break;
--
-- case AFMT_U16_LE:
-- for (bp = ((unsigned char *)ibuf)+2*cnt, i = 0; i < cnt; i++) {
-- bp -= 2;
-- sp--;
-- *sp = (bp[0] | (bp[1] << 8)) ^ 0x8000;
-- }
-- break;
--
-- case AFMT_U16_BE:
-- for (bp = ((unsigned char *)ibuf)+2*cnt, i = 0; i < cnt; i++) {
-- bp -= 2;
-- sp--;
-- *sp = (bp[1] | (bp[0] << 8)) ^ 0x8000;
-- }
-- break;
--
-- case AFMT_S16_LE:
-- for (bp = ((unsigned char *)ibuf)+2*cnt, i = 0; i < cnt; i++) {
-- bp -= 2;
-- sp--;
-- *sp = bp[0] | (bp[1] << 8);
-- }
-- break;
--
-- case AFMT_S16_BE:
-- for (bp = ((unsigned char *)ibuf)+2*cnt, i = 0; i < cnt; i++) {
-- bp -= 2;
-- sp--;
-- *sp = bp[1] | (bp[0] << 8);
-- }
-- break;
-- }
-- if (!AFMT_ISSTEREO(ifmt) && AFMT_ISSTEREO(ofmt)) {
-- /* expand from mono to stereo */
-- for (sp = ((__s16 *)tmp)+scnt, sp2 = ((__s16 *)tmp)+2*scnt, i = 0; i < scnt; i++) {
-- sp--;
-- sp2 -= 2;
-- sp2[0] = sp2[1] = sp[0];
-- }
-- }
-- if (AFMT_ISSTEREO(ifmt) && !AFMT_ISSTEREO(ofmt)) {
-- /* contract from stereo to mono */
-- for (sp = sp2 = ((__s16 *)tmp), i = 0; i < scnt; i++, sp++, sp2 += 2)
-- sp[0] = (sp2[0] + sp2[1]) >> 1;
-- }
-- cnt = scnt;
-- if (AFMT_ISSTEREO(ofmt))
-- cnt <<= 1;
-- sp = ((__s16 *)tmp);
-- bp = ((unsigned char *)obuf);
-- switch (ofmt & ~AFMT_STEREO) {
-- case AFMT_U8:
-- for (i = 0; i < cnt; i++, sp++, bp++)
-- *bp = (*sp >> 8) ^ 0x80;
-- break;
--
-- case AFMT_S8:
-- for (i = 0; i < cnt; i++, sp++, bp++)
-- *bp = *sp >> 8;
-- break;
--
-- case AFMT_U16_LE:
-- for (i = 0; i < cnt; i++, sp++, bp += 2) {
-- s = *sp;
-- bp[0] = s;
-- bp[1] = (s >> 8) ^ 0x80;
-- }
-- break;
--
-- case AFMT_U16_BE:
-- for (i = 0; i < cnt; i++, sp++, bp += 2) {
-- s = *sp;
-- bp[1] = s;
-- bp[0] = (s >> 8) ^ 0x80;
-- }
-- break;
--
-- case AFMT_S16_LE:
-- for (i = 0; i < cnt; i++, sp++, bp += 2) {
-- s = *sp;
-- bp[0] = s;
-- bp[1] = s >> 8;
-- }
-- break;
--
-- case AFMT_S16_BE:
-- for (i = 0; i < cnt; i++, sp++, bp += 2) {
-- s = *sp;
-- bp[1] = s;
-- bp[0] = s >> 8;
-- }
-- break;
-- }
--
--}
--
--static void usbin_convert(struct usbin *u, unsigned char *buffer, unsigned int samples)
--{
-- union {
-- __s16 s[64];
-- unsigned char b[0];
-- } tmp;
-- unsigned int scnt, maxs, ufmtsh, dfmtsh;
--
-- ufmtsh = AFMT_BYTESSHIFT(u->format);
-- dfmtsh = AFMT_BYTESSHIFT(u->dma.format);
-- maxs = (AFMT_ISSTEREO(u->dma.format | u->format)) ? 32 : 64;
-- while (samples > 0) {
-- scnt = samples;
-- if (scnt > maxs)
-- scnt = maxs;
-- conversion(buffer, u->format, tmp.b, u->dma.format, tmp.b, scnt);
-- dmabuf_copyin(&u->dma, tmp.b, scnt << dfmtsh);
-- buffer += scnt << ufmtsh;
-- samples -= scnt;
-- }
--}
--
--static int usbin_prepare_desc(struct usbin *u, struct urb *urb)
--{
-- unsigned int i, maxsize, offs;
--
-- maxsize = (u->freqmax + 0x3fff) >> (14 - AFMT_BYTESSHIFT(u->format));
-- //printk(KERN_DEBUG "usbin_prepare_desc: maxsize %d freq 0x%x format 0x%x\n", maxsize, u->freqn, u->format);
-- for (i = offs = 0; i < DESCFRAMES; i++, offs += maxsize) {
-- urb->iso_frame_desc[i].length = maxsize;
-- urb->iso_frame_desc[i].offset = offs;
-- }
-- urb->interval = 1;
-- return 0;
--}
--
--/*
-- * return value: 0 if descriptor should be restarted, -1 otherwise
-- * convert sample format on the fly if necessary
-- */
--static int usbin_retire_desc(struct usbin *u, struct urb *urb)
--{
-- unsigned int i, ufmtsh, dfmtsh, err = 0, cnt, scnt, dmafree;
-- unsigned char *cp;
--
-- ufmtsh = AFMT_BYTESSHIFT(u->format);
-- dfmtsh = AFMT_BYTESSHIFT(u->dma.format);
-- for (i = 0; i < DESCFRAMES; i++) {
-- cp = ((unsigned char *)urb->transfer_buffer) + urb->iso_frame_desc[i].offset;
-- if (urb->iso_frame_desc[i].status) {
-- dprintk((KERN_DEBUG "usbin_retire_desc: frame %u status %d\n", i, urb->iso_frame_desc[i].status));
-- continue;
-- }
-- scnt = urb->iso_frame_desc[i].actual_length >> ufmtsh;
-- if (!scnt)
-- continue;
-- cnt = scnt << dfmtsh;
-- if (!u->dma.mapped) {
-- dmafree = u->dma.dmasize - u->dma.count;
-- if (cnt > dmafree) {
-- scnt = dmafree >> dfmtsh;
-- cnt = scnt << dfmtsh;
-- err++;
-- }
-- }
-- u->dma.count += cnt;
-- if (u->format == u->dma.format) {
-- /* we do not need format conversion */
-- dprintk((KERN_DEBUG "usbaudio: no sample format conversion\n"));
-- dmabuf_copyin(&u->dma, cp, cnt);
-- } else {
-- /* we need sampling format conversion */
-- dprintk((KERN_DEBUG "usbaudio: sample format conversion %x != %x\n", u->format, u->dma.format));
-- usbin_convert(u, cp, scnt);
-- }
-- }
-- if (err)
-- u->dma.error++;
-- if (u->dma.count >= (signed)u->dma.fragsize)
-- wake_up(&u->dma.wait);
-- return err ? -1 : 0;
--}
--
--static void usbin_completed(struct urb *urb, struct pt_regs *regs)
--{
-- struct usb_audiodev *as = (struct usb_audiodev *)urb->context;
-- struct usbin *u = &as->usbin;
-- unsigned long flags;
-- unsigned int mask;
-- int suret = 0;
--
--#if 0
-- printk(KERN_DEBUG "usbin_completed: status %d errcnt %d flags 0x%x\n", urb->status, urb->error_count, u->flags);
--#endif
-- if (urb == u->durb[0].urb)
-- mask = FLG_URB0RUNNING;
-- else if (urb == u->durb[1].urb)
-- mask = FLG_URB1RUNNING;
-- else {
-- mask = 0;
-- printk(KERN_ERR "usbin_completed: panic: unknown URB\n");
-- }
-- urb->dev = as->state->usbdev;
-- spin_lock_irqsave(&as->lock, flags);
-- if (!usbin_retire_desc(u, urb) &&
-- u->flags & FLG_RUNNING &&
-- !usbin_prepare_desc(u, urb) &&
-- (suret = usb_submit_urb(urb, GFP_ATOMIC)) == 0) {
-- u->flags |= mask;
-- } else {
-- u->flags &= ~(mask | FLG_RUNNING);
-- wake_up(&u->dma.wait);
-- printk(KERN_DEBUG "usbin_completed: descriptor not restarted (usb_submit_urb: %d)\n", suret);
-- }
-- spin_unlock_irqrestore(&as->lock, flags);
--}
--
--/*
-- * we output sync data
-- */
--static int usbin_sync_prepare_desc(struct usbin *u, struct urb *urb)
--{
-- unsigned char *cp = urb->transfer_buffer;
-- unsigned int i, offs;
--
-- for (i = offs = 0; i < SYNCFRAMES; i++, offs += 3, cp += 3) {
-- urb->iso_frame_desc[i].length = 3;
-- urb->iso_frame_desc[i].offset = offs;
-- cp[0] = u->freqn;
-- cp[1] = u->freqn >> 8;
-- cp[2] = u->freqn >> 16;
-- }
-- urb->interval = 1;
-- return 0;
--}
--
--/*
-- * return value: 0 if descriptor should be restarted, -1 otherwise
-- */
--static int usbin_sync_retire_desc(struct usbin *u, struct urb *urb)
--{
-- unsigned int i;
--
-- for (i = 0; i < SYNCFRAMES; i++)
-- if (urb->iso_frame_desc[0].status)
-- dprintk((KERN_DEBUG "usbin_sync_retire_desc: frame %u status %d\n", i, urb->iso_frame_desc[i].status));
-- return 0;
--}
--
--static void usbin_sync_completed(struct urb *urb, struct pt_regs *regs)
--{
-- struct usb_audiodev *as = (struct usb_audiodev *)urb->context;
-- struct usbin *u = &as->usbin;
-- unsigned long flags;
-- unsigned int mask;
-- int suret = 0;
--
--#if 0
-- printk(KERN_DEBUG "usbin_sync_completed: status %d errcnt %d flags 0x%x\n", urb->status, urb->error_count, u->flags);
--#endif
-- if (urb == u->surb[0].urb)
-- mask = FLG_SYNC0RUNNING;
-- else if (urb == u->surb[1].urb)
-- mask = FLG_SYNC1RUNNING;
-- else {
-- mask = 0;
-- printk(KERN_ERR "usbin_sync_completed: panic: unknown URB\n");
-- }
-- urb->dev = as->state->usbdev;
-- spin_lock_irqsave(&as->lock, flags);
-- if (!usbin_sync_retire_desc(u, urb) &&
-- u->flags & FLG_RUNNING &&
-- !usbin_sync_prepare_desc(u, urb) &&
-- (suret = usb_submit_urb(urb, GFP_ATOMIC)) == 0) {
-- u->flags |= mask;
-- } else {
-- u->flags &= ~(mask | FLG_RUNNING);
-- wake_up(&u->dma.wait);
-- dprintk((KERN_DEBUG "usbin_sync_completed: descriptor not restarted (usb_submit_urb: %d)\n", suret));
-- }
-- spin_unlock_irqrestore(&as->lock, flags);
--}
--
--static int usbin_start(struct usb_audiodev *as)
--{
-- struct usb_device *dev = as->state->usbdev;
-- struct usbin *u = &as->usbin;
-- struct urb *urb;
-- unsigned long flags;
-- unsigned int maxsze, bufsz;
--
--#if 0
-- printk(KERN_DEBUG "usbin_start: device %d ufmt 0x%08x dfmt 0x%08x srate %d\n",
-- dev->devnum, u->format, u->dma.format, u->dma.srate);
--#endif
-- /* allocate USB storage if not already done */
-- spin_lock_irqsave(&as->lock, flags);
-- if (!(u->flags & FLG_CONNECTED)) {
-- spin_unlock_irqrestore(&as->lock, flags);
-- return -EIO;
-- }
-- if (!(u->flags & FLG_RUNNING)) {
-- spin_unlock_irqrestore(&as->lock, flags);
-- u->freqn = ((u->dma.srate << 11) + 62) / 125; /* this will overflow at approx 2MSPS */
-- u->freqmax = u->freqn + (u->freqn >> 2);
-- u->phase = 0;
-- maxsze = (u->freqmax + 0x3fff) >> (14 - AFMT_BYTESSHIFT(u->format));
-- bufsz = DESCFRAMES * maxsze;
-- kfree(u->durb[0].urb->transfer_buffer);
-- u->durb[0].urb->transfer_buffer = kmalloc(bufsz, GFP_KERNEL);
-- u->durb[0].urb->transfer_buffer_length = bufsz;
-- kfree(u->durb[1].urb->transfer_buffer);
-- u->durb[1].urb->transfer_buffer = kmalloc(bufsz, GFP_KERNEL);
-- u->durb[1].urb->transfer_buffer_length = bufsz;
-- if (u->syncpipe) {
-- kfree(u->surb[0].urb->transfer_buffer);
-- u->surb[0].urb->transfer_buffer = kmalloc(3*SYNCFRAMES, GFP_KERNEL);
-- u->surb[0].urb->transfer_buffer_length = 3*SYNCFRAMES;
-- kfree(u->surb[1].urb->transfer_buffer);
-- u->surb[1].urb->transfer_buffer = kmalloc(3*SYNCFRAMES, GFP_KERNEL);
-- u->surb[1].urb->transfer_buffer_length = 3*SYNCFRAMES;
-- }
-- if (!u->durb[0].urb->transfer_buffer || !u->durb[1].urb->transfer_buffer ||
-- (u->syncpipe && (!u->surb[0].urb->transfer_buffer || !u->surb[1].urb->transfer_buffer))) {
-- printk(KERN_ERR "usbaudio: cannot start playback device %d\n", dev->devnum);
-- return 0;
-- }
-- spin_lock_irqsave(&as->lock, flags);
-- }
-- if (u->dma.count >= u->dma.dmasize && !u->dma.mapped) {
-- spin_unlock_irqrestore(&as->lock, flags);
-- return 0;
-- }
-- u->flags |= FLG_RUNNING;
-- if (!(u->flags & FLG_URB0RUNNING)) {
-- urb = u->durb[0].urb;
-- urb->dev = dev;
-- urb->pipe = u->datapipe;
-- urb->transfer_flags = URB_ISO_ASAP;
-- urb->number_of_packets = DESCFRAMES;
-- urb->context = as;
-- urb->complete = usbin_completed;
-- if (!usbin_prepare_desc(u, urb) && !usb_submit_urb(urb, GFP_KERNEL))
-- u->flags |= FLG_URB0RUNNING;
-- else
-- u->flags &= ~FLG_RUNNING;
-- }
-- if (u->flags & FLG_RUNNING && !(u->flags & FLG_URB1RUNNING)) {
-- urb = u->durb[1].urb;
-- urb->dev = dev;
-- urb->pipe = u->datapipe;
-- urb->transfer_flags = URB_ISO_ASAP;
-- urb->number_of_packets = DESCFRAMES;
-- urb->context = as;
-- urb->complete = usbin_completed;
-- if (!usbin_prepare_desc(u, urb) && !usb_submit_urb(urb, GFP_KERNEL))
-- u->flags |= FLG_URB1RUNNING;
-- else
-- u->flags &= ~FLG_RUNNING;
-- }
-- if (u->syncpipe) {
-- if (u->flags & FLG_RUNNING && !(u->flags & FLG_SYNC0RUNNING)) {
-- urb = u->surb[0].urb;
-- urb->dev = dev;
-- urb->pipe = u->syncpipe;
-- urb->transfer_flags = URB_ISO_ASAP;
-- urb->number_of_packets = SYNCFRAMES;
-- urb->context = as;
-- urb->complete = usbin_sync_completed;
-- /* stride: u->syncinterval */
-- if (!usbin_sync_prepare_desc(u, urb) && !usb_submit_urb(urb, GFP_KERNEL))
-- u->flags |= FLG_SYNC0RUNNING;
-- else
-- u->flags &= ~FLG_RUNNING;
-- }
-- if (u->flags & FLG_RUNNING && !(u->flags & FLG_SYNC1RUNNING)) {
-- urb = u->surb[1].urb;
-- urb->dev = dev;
-- urb->pipe = u->syncpipe;
-- urb->transfer_flags = URB_ISO_ASAP;
-- urb->number_of_packets = SYNCFRAMES;
-- urb->context = as;
-- urb->complete = usbin_sync_completed;
-- /* stride: u->syncinterval */
-- if (!usbin_sync_prepare_desc(u, urb) && !usb_submit_urb(urb, GFP_KERNEL))
-- u->flags |= FLG_SYNC1RUNNING;
-- else
-- u->flags &= ~FLG_RUNNING;
-- }
-- }
-- spin_unlock_irqrestore(&as->lock, flags);
-- return 0;
--}
--
--static void usbout_stop(struct usb_audiodev *as)
--{
-- struct usbout *u = &as->usbout;
-- unsigned long flags;
-- unsigned int i, notkilled = 1;
--
-- spin_lock_irqsave(&as->lock, flags);
-- u->flags &= ~FLG_RUNNING;
-- i = u->flags;
-- spin_unlock_irqrestore(&as->lock, flags);
-- while (i & (FLG_URB0RUNNING|FLG_URB1RUNNING|FLG_SYNC0RUNNING|FLG_SYNC1RUNNING)) {
-- if (notkilled)
-- schedule_timeout_interruptible(1);
-- else
-- schedule_timeout_uninterruptible(1);
-- spin_lock_irqsave(&as->lock, flags);
-- i = u->flags;
-- spin_unlock_irqrestore(&as->lock, flags);
-- if (notkilled && signal_pending(current)) {
-- if (i & FLG_URB0RUNNING)
-- usb_kill_urb(u->durb[0].urb);
-- if (i & FLG_URB1RUNNING)
-- usb_kill_urb(u->durb[1].urb);
-- if (i & FLG_SYNC0RUNNING)
-- usb_kill_urb(u->surb[0].urb);
-- if (i & FLG_SYNC1RUNNING)
-- usb_kill_urb(u->surb[1].urb);
-- notkilled = 0;
-- }
-- }
-- set_current_state(TASK_RUNNING);
-- kfree(u->durb[0].urb->transfer_buffer);
-- kfree(u->durb[1].urb->transfer_buffer);
-- kfree(u->surb[0].urb->transfer_buffer);
-- kfree(u->surb[1].urb->transfer_buffer);
-- u->durb[0].urb->transfer_buffer = u->durb[1].urb->transfer_buffer =
-- u->surb[0].urb->transfer_buffer = u->surb[1].urb->transfer_buffer = NULL;
--}
--
--static inline void usbout_release(struct usb_audiodev *as)
--{
-- usbout_stop(as);
--}
--
--static void usbout_disc(struct usb_audiodev *as)
--{
-- struct usbout *u = &as->usbout;
-- unsigned long flags;
--
-- spin_lock_irqsave(&as->lock, flags);
-- u->flags &= ~(FLG_RUNNING | FLG_CONNECTED);
-- spin_unlock_irqrestore(&as->lock, flags);
-- usbout_stop(as);
--}
--
--static void usbout_convert(struct usbout *u, unsigned char *buffer, unsigned int samples)
--{
-- union {
-- __s16 s[64];
-- unsigned char b[0];
-- } tmp;
-- unsigned int scnt, maxs, ufmtsh, dfmtsh;
--
-- ufmtsh = AFMT_BYTESSHIFT(u->format);
-- dfmtsh = AFMT_BYTESSHIFT(u->dma.format);
-- maxs = (AFMT_ISSTEREO(u->dma.format | u->format)) ? 32 : 64;
-- while (samples > 0) {
-- scnt = samples;
-- if (scnt > maxs)
-- scnt = maxs;
-- dmabuf_copyout(&u->dma, tmp.b, scnt << dfmtsh);
-- conversion(tmp.b, u->dma.format, buffer, u->format, tmp.b, scnt);
-- buffer += scnt << ufmtsh;
-- samples -= scnt;
-- }
--}
--
--static int usbout_prepare_desc(struct usbout *u, struct urb *urb)
--{
-- unsigned int i, ufmtsh, dfmtsh, err = 0, cnt, scnt, offs;
-- unsigned char *cp = urb->transfer_buffer;
--
-- ufmtsh = AFMT_BYTESSHIFT(u->format);
-- dfmtsh = AFMT_BYTESSHIFT(u->dma.format);
-- for (i = offs = 0; i < DESCFRAMES; i++) {
-- urb->iso_frame_desc[i].offset = offs;
-- u->phase = (u->phase & 0x3fff) + u->freqm;
-- scnt = u->phase >> 14;
-- if (!scnt) {
-- urb->iso_frame_desc[i].length = 0;
-- continue;
-- }
-- cnt = scnt << dfmtsh;
-- if (!u->dma.mapped) {
-- if (cnt > u->dma.count) {
-- scnt = u->dma.count >> dfmtsh;
-- cnt = scnt << dfmtsh;
-- err++;
-- }
-- u->dma.count -= cnt;
-- } else
-- u->dma.count += cnt;
-- if (u->format == u->dma.format) {
-- /* we do not need format conversion */
-- dmabuf_copyout(&u->dma, cp, cnt);
-- } else {
-- /* we need sampling format conversion */
-- usbout_convert(u, cp, scnt);
-- }
-- cnt = scnt << ufmtsh;
-- urb->iso_frame_desc[i].length = cnt;
-- offs += cnt;
-- cp += cnt;
-- }
-- urb->interval = 1;
-- if (err)
-- u->dma.error++;
-- if (u->dma.mapped) {
-- if (u->dma.count >= (signed)u->dma.fragsize)
-- wake_up(&u->dma.wait);
-- } else {
-- if ((signed)u->dma.dmasize >= u->dma.count + (signed)u->dma.fragsize)
-- wake_up(&u->dma.wait);
-- }
-- return err ? -1 : 0;
--}
--
--/*
-- * return value: 0 if descriptor should be restarted, -1 otherwise
-- */
--static int usbout_retire_desc(struct usbout *u, struct urb *urb)
--{
-- unsigned int i;
--
-- for (i = 0; i < DESCFRAMES; i++) {
-- if (urb->iso_frame_desc[i].status) {
-- dprintk((KERN_DEBUG "usbout_retire_desc: frame %u status %d\n", i, urb->iso_frame_desc[i].status));
-- continue;
-- }
-- }
-- return 0;
--}
--
--static void usbout_completed(struct urb *urb, struct pt_regs *regs)
--{
-- struct usb_audiodev *as = (struct usb_audiodev *)urb->context;
-- struct usbout *u = &as->usbout;
-- unsigned long flags;
-- unsigned int mask;
-- int suret = 0;
--
--#if 0
-- printk(KERN_DEBUG "usbout_completed: status %d errcnt %d flags 0x%x\n", urb->status, urb->error_count, u->flags);
--#endif
-- if (urb == u->durb[0].urb)
-- mask = FLG_URB0RUNNING;
-- else if (urb == u->durb[1].urb)
-- mask = FLG_URB1RUNNING;
-- else {
-- mask = 0;
-- printk(KERN_ERR "usbout_completed: panic: unknown URB\n");
-- }
-- urb->dev = as->state->usbdev;
-- spin_lock_irqsave(&as->lock, flags);
-- if (!usbout_retire_desc(u, urb) &&
-- u->flags & FLG_RUNNING &&
-- !usbout_prepare_desc(u, urb) &&
-- (suret = usb_submit_urb(urb, GFP_ATOMIC)) == 0) {
-- u->flags |= mask;
-- } else {
-- u->flags &= ~(mask | FLG_RUNNING);
-- wake_up(&u->dma.wait);
-- dprintk((KERN_DEBUG "usbout_completed: descriptor not restarted (usb_submit_urb: %d)\n", suret));
-- }
-- spin_unlock_irqrestore(&as->lock, flags);
--}
--
--static int usbout_sync_prepare_desc(struct usbout *u, struct urb *urb)
--{
-- unsigned int i, offs;
--
-- for (i = offs = 0; i < SYNCFRAMES; i++, offs += 3) {
-- urb->iso_frame_desc[i].length = 3;
-- urb->iso_frame_desc[i].offset = offs;
-- }
-- urb->interval = 1;
-- return 0;
--}
--
--/*
-- * return value: 0 if descriptor should be restarted, -1 otherwise
-- */
--static int usbout_sync_retire_desc(struct usbout *u, struct urb *urb)
--{
-- unsigned char *cp = urb->transfer_buffer;
-- unsigned int f, i;
--
-- for (i = 0; i < SYNCFRAMES; i++, cp += 3) {
-- if (urb->iso_frame_desc[i].status) {
-- dprintk((KERN_DEBUG "usbout_sync_retire_desc: frame %u status %d\n", i, urb->iso_frame_desc[i].status));
-- continue;
-- }
-- if (urb->iso_frame_desc[i].actual_length < 3) {
-- dprintk((KERN_DEBUG "usbout_sync_retire_desc: frame %u length %d\n", i, urb->iso_frame_desc[i].actual_length));
-- continue;
-- }
-- f = cp[0] | (cp[1] << 8) | (cp[2] << 16);
-- if (abs(f - u->freqn) > (u->freqn >> 3) || f > u->freqmax) {
-- printk(KERN_WARNING "usbout_sync_retire_desc: requested frequency %u (nominal %u) out of range!\n", f, u->freqn);
-- continue;
-- }
-- u->freqm = f;
-- }
-- return 0;
--}
--
--static void usbout_sync_completed(struct urb *urb, struct pt_regs *regs)
--{
-- struct usb_audiodev *as = (struct usb_audiodev *)urb->context;
-- struct usbout *u = &as->usbout;
-- unsigned long flags;
-- unsigned int mask;
-- int suret = 0;
--
--#if 0
-- printk(KERN_DEBUG "usbout_sync_completed: status %d errcnt %d flags 0x%x\n", urb->status, urb->error_count, u->flags);
--#endif
-- if (urb == u->surb[0].urb)
-- mask = FLG_SYNC0RUNNING;
-- else if (urb == u->surb[1].urb)
-- mask = FLG_SYNC1RUNNING;
-- else {
-- mask = 0;
-- printk(KERN_ERR "usbout_sync_completed: panic: unknown URB\n");
-- }
-- urb->dev = as->state->usbdev;
-- spin_lock_irqsave(&as->lock, flags);
-- if (!usbout_sync_retire_desc(u, urb) &&
-- u->flags & FLG_RUNNING &&
-- !usbout_sync_prepare_desc(u, urb) &&
-- (suret = usb_submit_urb(urb, GFP_ATOMIC)) == 0) {
-- u->flags |= mask;
-- } else {
-- u->flags &= ~(mask | FLG_RUNNING);
-- wake_up(&u->dma.wait);
-- dprintk((KERN_DEBUG "usbout_sync_completed: descriptor not restarted (usb_submit_urb: %d)\n", suret));
-- }
-- spin_unlock_irqrestore(&as->lock, flags);
--}
--
--static int usbout_start(struct usb_audiodev *as)
--{
-- struct usb_device *dev = as->state->usbdev;
-- struct usbout *u = &as->usbout;
-- struct urb *urb;
-- unsigned long flags;
-- unsigned int maxsze, bufsz;
--
--#if 0
-- printk(KERN_DEBUG "usbout_start: device %d ufmt 0x%08x dfmt 0x%08x srate %d\n",
-- dev->devnum, u->format, u->dma.format, u->dma.srate);
--#endif
-- /* allocate USB storage if not already done */
-- spin_lock_irqsave(&as->lock, flags);
-- if (!(u->flags & FLG_CONNECTED)) {
-- spin_unlock_irqrestore(&as->lock, flags);
-- return -EIO;
-- }
-- if (!(u->flags & FLG_RUNNING)) {
-- spin_unlock_irqrestore(&as->lock, flags);
-- u->freqn = u->freqm = ((u->dma.srate << 11) + 62) / 125; /* this will overflow at approx 2MSPS */
-- u->freqmax = u->freqn + (u->freqn >> 2);
-- u->phase = 0;
-- maxsze = (u->freqmax + 0x3fff) >> (14 - AFMT_BYTESSHIFT(u->format));
-- bufsz = DESCFRAMES * maxsze;
-- kfree(u->durb[0].urb->transfer_buffer);
-- u->durb[0].urb->transfer_buffer = kmalloc(bufsz, GFP_KERNEL);
-- u->durb[0].urb->transfer_buffer_length = bufsz;
-- kfree(u->durb[1].urb->transfer_buffer);
-- u->durb[1].urb->transfer_buffer = kmalloc(bufsz, GFP_KERNEL);
-- u->durb[1].urb->transfer_buffer_length = bufsz;
-- if (u->syncpipe) {
-- kfree(u->surb[0].urb->transfer_buffer);
-- u->surb[0].urb->transfer_buffer = kmalloc(3*SYNCFRAMES, GFP_KERNEL);
-- u->surb[0].urb->transfer_buffer_length = 3*SYNCFRAMES;
-- kfree(u->surb[1].urb->transfer_buffer);
-- u->surb[1].urb->transfer_buffer = kmalloc(3*SYNCFRAMES, GFP_KERNEL);
-- u->surb[1].urb->transfer_buffer_length = 3*SYNCFRAMES;
-- }
-- if (!u->durb[0].urb->transfer_buffer || !u->durb[1].urb->transfer_buffer ||
-- (u->syncpipe && (!u->surb[0].urb->transfer_buffer || !u->surb[1].urb->transfer_buffer))) {
-- printk(KERN_ERR "usbaudio: cannot start playback device %d\n", dev->devnum);
-- return 0;
-- }
-- spin_lock_irqsave(&as->lock, flags);
-- }
-- if (u->dma.count <= 0 && !u->dma.mapped) {
-- spin_unlock_irqrestore(&as->lock, flags);
-- return 0;
-- }
-- u->flags |= FLG_RUNNING;
-- if (!(u->flags & FLG_URB0RUNNING)) {
-- urb = u->durb[0].urb;
-- urb->dev = dev;
-- urb->pipe = u->datapipe;
-- urb->transfer_flags = URB_ISO_ASAP;
-- urb->number_of_packets = DESCFRAMES;
-- urb->context = as;
-- urb->complete = usbout_completed;
-- if (!usbout_prepare_desc(u, urb) && !usb_submit_urb(urb, GFP_ATOMIC))
-- u->flags |= FLG_URB0RUNNING;
-- else
-- u->flags &= ~FLG_RUNNING;
-- }
-- if (u->flags & FLG_RUNNING && !(u->flags & FLG_URB1RUNNING)) {
-- urb = u->durb[1].urb;
-- urb->dev = dev;
-- urb->pipe = u->datapipe;
-- urb->transfer_flags = URB_ISO_ASAP;
-- urb->number_of_packets = DESCFRAMES;
-- urb->context = as;
-- urb->complete = usbout_completed;
-- if (!usbout_prepare_desc(u, urb) && !usb_submit_urb(urb, GFP_ATOMIC))
-- u->flags |= FLG_URB1RUNNING;
-- else
-- u->flags &= ~FLG_RUNNING;
-- }
-- if (u->syncpipe) {
-- if (u->flags & FLG_RUNNING && !(u->flags & FLG_SYNC0RUNNING)) {
-- urb = u->surb[0].urb;
-- urb->dev = dev;
-- urb->pipe = u->syncpipe;
-- urb->transfer_flags = URB_ISO_ASAP;
-- urb->number_of_packets = SYNCFRAMES;
-- urb->context = as;
-- urb->complete = usbout_sync_completed;
-- /* stride: u->syncinterval */
-- if (!usbout_sync_prepare_desc(u, urb) && !usb_submit_urb(urb, GFP_ATOMIC))
-- u->flags |= FLG_SYNC0RUNNING;
-- else
-- u->flags &= ~FLG_RUNNING;
-- }
-- if (u->flags & FLG_RUNNING && !(u->flags & FLG_SYNC1RUNNING)) {
-- urb = u->surb[1].urb;
-- urb->dev = dev;
-- urb->pipe = u->syncpipe;
-- urb->transfer_flags = URB_ISO_ASAP;
-- urb->number_of_packets = SYNCFRAMES;
-- urb->context = as;
-- urb->complete = usbout_sync_completed;
-- /* stride: u->syncinterval */
-- if (!usbout_sync_prepare_desc(u, urb) && !usb_submit_urb(urb, GFP_ATOMIC))
-- u->flags |= FLG_SYNC1RUNNING;
-- else
-- u->flags &= ~FLG_RUNNING;
-- }
-- }
-- spin_unlock_irqrestore(&as->lock, flags);
-- return 0;
--}
--
--/* --------------------------------------------------------------------- */
--
--static unsigned int format_goodness(struct audioformat *afp, unsigned int fmt, unsigned int srate)
--{
-- unsigned int g = 0;
--
-- if (srate < afp->sratelo)
-- g += afp->sratelo - srate;
-- if (srate > afp->sratehi)
-- g += srate - afp->sratehi;
-- if (AFMT_ISSTEREO(afp->format) && !AFMT_ISSTEREO(fmt))
-- g += 0x100000;
-- if (!AFMT_ISSTEREO(afp->format) && AFMT_ISSTEREO(fmt))
-- g += 0x400000;
-- if (AFMT_IS16BIT(afp->format) && !AFMT_IS16BIT(fmt))
-- g += 0x100000;
-- if (!AFMT_IS16BIT(afp->format) && AFMT_IS16BIT(fmt))
-- g += 0x400000;
-- return g;
--}
--
--static int find_format(struct audioformat *afp, unsigned int nr, unsigned int fmt, unsigned int srate)
--{
-- unsigned int i, g, gb = ~0;
-- int j = -1; /* default to failure */
--
-- /* find "best" format (according to format_goodness) */
-- for (i = 0; i < nr; i++) {
-- g = format_goodness(&afp[i], fmt, srate);
-- if (g >= gb)
-- continue;
-- j = i;
-- gb = g;
-- }
-- return j;
--}
--
--static int set_format_in(struct usb_audiodev *as)
--{
-- struct usb_device *dev = as->state->usbdev;
-- struct usb_host_interface *alts;
-- struct usb_interface *iface;
-- struct usbin *u = &as->usbin;
-- struct dmabuf *d = &u->dma;
-- struct audioformat *fmt;
-- unsigned int ep;
-- unsigned char data[3];
-- int fmtnr, ret;
--
-- iface = usb_ifnum_to_if(dev, u->interface);
-- if (!iface)
-- return 0;
--
-- fmtnr = find_format(as->fmtin, as->numfmtin, d->format, d->srate);
-- if (fmtnr < 0) {
-- printk(KERN_ERR "usbaudio: set_format_in(): failed to find desired format/speed combination.\n");
-- return -1;
-- }
--
-- fmt = as->fmtin + fmtnr;
-- alts = usb_altnum_to_altsetting(iface, fmt->altsetting);
-- u->format = fmt->format;
-- u->datapipe = usb_rcvisocpipe(dev, alts->endpoint[0].desc.bEndpointAddress & 0xf);
-- u->syncpipe = u->syncinterval = 0;
-- if ((alts->endpoint[0].desc.bmAttributes & 0x0c) == 0x08) {
-- if (alts->desc.bNumEndpoints < 2 ||
-- alts->endpoint[1].desc.bmAttributes != 0x01 ||
-- alts->endpoint[1].desc.bSynchAddress != 0 ||
-- alts->endpoint[1].desc.bEndpointAddress != (alts->endpoint[0].desc.bSynchAddress & 0x7f)) {
-- printk(KERN_WARNING "usbaudio: device %d interface %d altsetting %d claims adaptive in "
-- "but has invalid synch pipe; treating as asynchronous in\n",
-- dev->devnum, u->interface, fmt->altsetting);
-- } else {
-- u->syncpipe = usb_sndisocpipe(dev, alts->endpoint[1].desc.bEndpointAddress & 0xf);
-- u->syncinterval = alts->endpoint[1].desc.bRefresh;
-- }
-- }
-- if (d->srate < fmt->sratelo)
-- d->srate = fmt->sratelo;
-- if (d->srate > fmt->sratehi)
-- d->srate = fmt->sratehi;
-- dprintk((KERN_DEBUG "usbaudio: set_format_in: usb_set_interface %u %u\n",
-- u->interface, fmt->altsetting));
-- if (usb_set_interface(dev, alts->desc.bInterfaceNumber, fmt->altsetting) < 0) {
-- printk(KERN_WARNING "usbaudio: usb_set_interface failed, device %d interface %d altsetting %d\n",
-- dev->devnum, u->interface, fmt->altsetting);
-- return -1;
-- }
-- if (fmt->sratelo == fmt->sratehi)
-- return 0;
-- ep = usb_pipeendpoint(u->datapipe) | (u->datapipe & USB_DIR_IN);
-- /* if endpoint has pitch control, enable it */
-- if (fmt->attributes & 0x02) {
-- data[0] = 1;
-- if ((ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR, USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT,
-- PITCH_CONTROL << 8, ep, data, 1, 1000)) < 0) {
-- printk(KERN_ERR "usbaudio: failure (error %d) to set output pitch control device %d interface %u endpoint 0x%x to %u\n",
-- ret, dev->devnum, u->interface, ep, d->srate);
-- return -1;
-- }
-- }
-- /* if endpoint has sampling rate control, set it */
-- if (fmt->attributes & 0x01) {
-- data[0] = d->srate;
-- data[1] = d->srate >> 8;
-- data[2] = d->srate >> 16;
-- if ((ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR, USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT,
-- SAMPLING_FREQ_CONTROL << 8, ep, data, 3, 1000)) < 0) {
-- printk(KERN_ERR "usbaudio: failure (error %d) to set input sampling frequency device %d interface %u endpoint 0x%x to %u\n",
-- ret, dev->devnum, u->interface, ep, d->srate);
-- return -1;
-- }
-- if ((ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), GET_CUR, USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_IN,
-- SAMPLING_FREQ_CONTROL << 8, ep, data, 3, 1000)) < 0) {
-- printk(KERN_ERR "usbaudio: failure (error %d) to get input sampling frequency device %d interface %u endpoint 0x%x\n",
-- ret, dev->devnum, u->interface, ep);
-- return -1;
-- }
-- dprintk((KERN_DEBUG "usbaudio: set_format_in: device %d interface %d altsetting %d srate req: %u real %u\n",
-- dev->devnum, u->interface, fmt->altsetting, d->srate, data[0] | (data[1] << 8) | (data[2] << 16)));
-- d->srate = data[0] | (data[1] << 8) | (data[2] << 16);
-- }
-- dprintk((KERN_DEBUG "usbaudio: set_format_in: USB format 0x%x, DMA format 0x%x srate %u\n", u->format, d->format, d->srate));
-- return 0;
--}
--
--static int set_format_out(struct usb_audiodev *as)
--{
-- struct usb_device *dev = as->state->usbdev;
-- struct usb_host_interface *alts;
-- struct usb_interface *iface;
-- struct usbout *u = &as->usbout;
-- struct dmabuf *d = &u->dma;
-- struct audioformat *fmt;
-- unsigned int ep;
-- unsigned char data[3];
-- int fmtnr, ret;
--
-- iface = usb_ifnum_to_if(dev, u->interface);
-- if (!iface)
-- return 0;
--
-- fmtnr = find_format(as->fmtout, as->numfmtout, d->format, d->srate);
-- if (fmtnr < 0) {
-- printk(KERN_ERR "usbaudio: set_format_out(): failed to find desired format/speed combination.\n");
-- return -1;
-- }
--
-- fmt = as->fmtout + fmtnr;
-- u->format = fmt->format;
-- alts = usb_altnum_to_altsetting(iface, fmt->altsetting);
-- u->datapipe = usb_sndisocpipe(dev, alts->endpoint[0].desc.bEndpointAddress & 0xf);
-- u->syncpipe = u->syncinterval = 0;
-- if ((alts->endpoint[0].desc.bmAttributes & 0x0c) == 0x04) {
--#if 0
-- printk(KERN_DEBUG "bNumEndpoints 0x%02x endpoint[1].bmAttributes 0x%02x\n"
-- KERN_DEBUG "endpoint[1].bSynchAddress 0x%02x endpoint[1].bEndpointAddress 0x%02x\n"
-- KERN_DEBUG "endpoint[0].bSynchAddress 0x%02x\n", alts->bNumEndpoints,
-- alts->endpoint[1].bmAttributes, alts->endpoint[1].bSynchAddress,
-- alts->endpoint[1].bEndpointAddress, alts->endpoint[0].bSynchAddress);
--#endif
-- if (alts->desc.bNumEndpoints < 2 ||
-- alts->endpoint[1].desc.bmAttributes != 0x01 ||
-- alts->endpoint[1].desc.bSynchAddress != 0 ||
-- alts->endpoint[1].desc.bEndpointAddress != (alts->endpoint[0].desc.bSynchAddress | 0x80)) {
-- printk(KERN_WARNING "usbaudio: device %d interface %d altsetting %d claims asynch out "
-- "but has invalid synch pipe; treating as adaptive out\n",
-- dev->devnum, u->interface, fmt->altsetting);
-- } else {
-- u->syncpipe = usb_rcvisocpipe(dev, alts->endpoint[1].desc.bEndpointAddress & 0xf);
-- u->syncinterval = alts->endpoint[1].desc.bRefresh;
-- }
-- }
-- if (d->srate < fmt->sratelo)
-- d->srate = fmt->sratelo;
-- if (d->srate > fmt->sratehi)
-- d->srate = fmt->sratehi;
-- dprintk((KERN_DEBUG "usbaudio: set_format_out: usb_set_interface %u %u\n",
-- u->interface, fmt->altsetting));
-- if (usb_set_interface(dev, u->interface, fmt->altsetting) < 0) {
-- printk(KERN_WARNING "usbaudio: usb_set_interface failed, device %d interface %d altsetting %d\n",
-- dev->devnum, u->interface, fmt->altsetting);
-- return -1;
-- }
-- if (fmt->sratelo == fmt->sratehi)
-- return 0;
-- ep = usb_pipeendpoint(u->datapipe) | (u->datapipe & USB_DIR_IN);
-- /* if endpoint has pitch control, enable it */
-- if (fmt->attributes & 0x02) {
-- data[0] = 1;
-- if ((ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR, USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT,
-- PITCH_CONTROL << 8, ep, data, 1, 1000)) < 0) {
-- printk(KERN_ERR "usbaudio: failure (error %d) to set output pitch control device %d interface %u endpoint 0x%x to %u\n",
-- ret, dev->devnum, u->interface, ep, d->srate);
-- return -1;
-- }
-- }
-- /* if endpoint has sampling rate control, set it */
-- if (fmt->attributes & 0x01) {
-- data[0] = d->srate;
-- data[1] = d->srate >> 8;
-- data[2] = d->srate >> 16;
-- if ((ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR, USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT,
-- SAMPLING_FREQ_CONTROL << 8, ep, data, 3, 1000)) < 0) {
-- printk(KERN_ERR "usbaudio: failure (error %d) to set output sampling frequency device %d interface %u endpoint 0x%x to %u\n",
-- ret, dev->devnum, u->interface, ep, d->srate);
-- return -1;
-- }
-- if ((ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), GET_CUR, USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_IN,
-- SAMPLING_FREQ_CONTROL << 8, ep, data, 3, 1000)) < 0) {
-- printk(KERN_ERR "usbaudio: failure (error %d) to get output sampling frequency device %d interface %u endpoint 0x%x\n",
-- ret, dev->devnum, u->interface, ep);
-- return -1;
-- }
-- dprintk((KERN_DEBUG "usbaudio: set_format_out: device %d interface %d altsetting %d srate req: %u real %u\n",
-- dev->devnum, u->interface, fmt->altsetting, d->srate, data[0] | (data[1] << 8) | (data[2] << 16)));
-- d->srate = data[0] | (data[1] << 8) | (data[2] << 16);
-- }
-- dprintk((KERN_DEBUG "usbaudio: set_format_out: USB format 0x%x, DMA format 0x%x srate %u\n", u->format, d->format, d->srate));
-- return 0;
--}
--
--static int set_format(struct usb_audiodev *s, unsigned int fmode, unsigned int fmt, unsigned int srate)
--{
-- int ret1 = 0, ret2 = 0;
--
-- if (!(fmode & (FMODE_READ|FMODE_WRITE)))
-- return -EINVAL;
-- if (fmode & FMODE_READ) {
-- usbin_stop(s);
-- s->usbin.dma.ready = 0;
-- if (fmt == AFMT_QUERY)
-- fmt = s->usbin.dma.format;
-- else
-- s->usbin.dma.format = fmt;
-- if (!srate)
-- srate = s->usbin.dma.srate;
-- else
-- s->usbin.dma.srate = srate;
-- }
-- if (fmode & FMODE_WRITE) {
-- usbout_stop(s);
-- s->usbout.dma.ready = 0;
-- if (fmt == AFMT_QUERY)
-- fmt = s->usbout.dma.format;
-- else
-- s->usbout.dma.format = fmt;
-- if (!srate)
-- srate = s->usbout.dma.srate;
-- else
-- s->usbout.dma.srate = srate;
-- }
-- if (fmode & FMODE_READ)
-- ret1 = set_format_in(s);
-- if (fmode & FMODE_WRITE)
-- ret2 = set_format_out(s);
-- return ret1 ? ret1 : ret2;
--}
--
--/* --------------------------------------------------------------------- */
--
--static int wrmixer(struct usb_mixerdev *ms, unsigned mixch, unsigned value)
--{
-- struct usb_device *dev = ms->state->usbdev;
-- unsigned char data[2];
-- struct mixerchannel *ch;
-- int v1, v2, v3;
--
-- if (mixch >= ms->numch)
-- return -1;
-- ch = &ms->ch[mixch];
-- v3 = ch->maxval - ch->minval;
-- v1 = value & 0xff;
-- v2 = (value >> 8) & 0xff;
-- if (v1 > 100)
-- v1 = 100;
-- if (v2 > 100)
-- v2 = 100;
-- if (!(ch->flags & (MIXFLG_STEREOIN | MIXFLG_STEREOOUT)))
-- v2 = v1;
-- ch->value = v1 | (v2 << 8);
-- v1 = (v1 * v3) / 100 + ch->minval;
-- v2 = (v2 * v3) / 100 + ch->minval;
-- switch (ch->selector) {
-- case 0: /* mixer unit request */
-- data[0] = v1;
-- data[1] = v1 >> 8;
-- if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT,
-- (ch->chnum << 8) | 1, ms->iface | (ch->unitid << 8), data, 2, 1000) < 0)
-- goto err;
-- if (!(ch->flags & (MIXFLG_STEREOIN | MIXFLG_STEREOOUT)))
-- return 0;
-- data[0] = v2;
-- data[1] = v2 >> 8;
-- if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT,
-- ((ch->chnum + !!(ch->flags & MIXFLG_STEREOIN)) << 8) | (1 + !!(ch->flags & MIXFLG_STEREOOUT)),
-- ms->iface | (ch->unitid << 8), data, 2, 1000) < 0)
-- goto err;
-- return 0;
--
-- /* various feature unit controls */
-- case VOLUME_CONTROL:
-- data[0] = v1;
-- data[1] = v1 >> 8;
-- if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT,
-- (ch->selector << 8) | ch->chnum, ms->iface | (ch->unitid << 8), data, 2, 1000) < 0)
-- goto err;
-- if (!(ch->flags & (MIXFLG_STEREOIN | MIXFLG_STEREOOUT)))
-- return 0;
-- data[0] = v2;
-- data[1] = v2 >> 8;
-- if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT,
-- (ch->selector << 8) | (ch->chnum + 1), ms->iface | (ch->unitid << 8), data, 2, 1000) < 0)
-- goto err;
-- return 0;
--
-- case BASS_CONTROL:
-- case MID_CONTROL:
-- case TREBLE_CONTROL:
-- data[0] = v1 >> 8;
-- if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT,
-- (ch->selector << 8) | ch->chnum, ms->iface | (ch->unitid << 8), data, 1, 1000) < 0)
-- goto err;
-- if (!(ch->flags & (MIXFLG_STEREOIN | MIXFLG_STEREOOUT)))
-- return 0;
-- data[0] = v2 >> 8;
-- if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT,
-- (ch->selector << 8) | (ch->chnum + 1), ms->iface | (ch->unitid << 8), data, 1, 1000) < 0)
-- goto err;
-- return 0;
--
-- default:
-- return -1;
-- }
-- return 0;
--
-- err:
-- printk(KERN_ERR "usbaudio: mixer request device %u if %u unit %u ch %u selector %u failed\n",
-- dev->devnum, ms->iface, ch->unitid, ch->chnum, ch->selector);
-- return -1;
--}
--
--static int get_rec_src(struct usb_mixerdev *ms)
--{
-- struct usb_device *dev = ms->state->usbdev;
-- unsigned int mask = 0, retmask = 0;
-- unsigned int i, j;
-- unsigned char buf;
-- int err = 0;
--
-- for (i = 0; i < ms->numch; i++) {
-- if (!ms->ch[i].slctunitid || (mask & (1 << i)))
-- continue;
-- if (usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), GET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
-- 0, ms->iface | (ms->ch[i].slctunitid << 8), &buf, 1, 1000) < 0) {
-- err = -EIO;
-- printk(KERN_ERR "usbaudio: selector read request device %u if %u unit %u failed\n",
-- dev->devnum, ms->iface, ms->ch[i].slctunitid & 0xff);
-- continue;
-- }
-- for (j = i; j < ms->numch; j++) {
-- if ((ms->ch[i].slctunitid ^ ms->ch[j].slctunitid) & 0xff)
-- continue;
-- mask |= 1 << j;
-- if (buf == (ms->ch[j].slctunitid >> 8))
-- retmask |= 1 << ms->ch[j].osschannel;
-- }
-- }
-- if (err)
-- return -EIO;
-- return retmask;
--}
--
--static int set_rec_src(struct usb_mixerdev *ms, int srcmask)
--{
-- struct usb_device *dev = ms->state->usbdev;
-- unsigned int mask = 0, smask, bmask;
-- unsigned int i, j;
-- unsigned char buf;
-- int err = 0;
--
-- for (i = 0; i < ms->numch; i++) {
-- if (!ms->ch[i].slctunitid || (mask & (1 << i)))
-- continue;
-- if (usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), GET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
-- 0, ms->iface | (ms->ch[i].slctunitid << 8), &buf, 1, 1000) < 0) {
-- err = -EIO;
-- printk(KERN_ERR "usbaudio: selector read request device %u if %u unit %u failed\n",
-- dev->devnum, ms->iface, ms->ch[i].slctunitid & 0xff);
-- continue;
-- }
-- /* first generate smask */
-- smask = bmask = 0;
-- for (j = i; j < ms->numch; j++) {
-- if ((ms->ch[i].slctunitid ^ ms->ch[j].slctunitid) & 0xff)
-- continue;
-- smask |= 1 << ms->ch[j].osschannel;
-- if (buf == (ms->ch[j].slctunitid >> 8))
-- bmask |= 1 << ms->ch[j].osschannel;
-- mask |= 1 << j;
-- }
-- /* check for multiple set sources */
-- j = hweight32(srcmask & smask);
-- if (j == 0)
-- continue;
-- if (j > 1)
-- srcmask &= ~bmask;
-- for (j = i; j < ms->numch; j++) {
-- if ((ms->ch[i].slctunitid ^ ms->ch[j].slctunitid) & 0xff)
-- continue;
-- if (!(srcmask & (1 << ms->ch[j].osschannel)))
-- continue;
-- buf = ms->ch[j].slctunitid >> 8;
-- if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT,
-- 0, ms->iface | (ms->ch[j].slctunitid << 8), &buf, 1, 1000) < 0) {
-- err = -EIO;
-- printk(KERN_ERR "usbaudio: selector write request device %u if %u unit %u failed\n",
-- dev->devnum, ms->iface, ms->ch[j].slctunitid & 0xff);
-- continue;
-- }
-- }
-- }
-- return err ? -EIO : 0;
--}
--
--/* --------------------------------------------------------------------- */
--
--/*
-- * should be called with open_sem hold, so that no new processes
-- * look at the audio device to be destroyed
-- */
--
--static void release(struct usb_audio_state *s)
--{
-- struct usb_audiodev *as;
-- struct usb_mixerdev *ms;
--
-- s->count--;
-- if (s->count) {
-- up(&open_sem);
-- return;
-- }
-- up(&open_sem);
-- wake_up(&open_wait);
-- while (!list_empty(&s->audiolist)) {
-- as = list_entry(s->audiolist.next, struct usb_audiodev, list);
-- list_del(&as->list);
-- usbin_release(as);
-- usbout_release(as);
-- dmabuf_release(&as->usbin.dma);
-- dmabuf_release(&as->usbout.dma);
-- usb_free_urb(as->usbin.durb[0].urb);
-- usb_free_urb(as->usbin.durb[1].urb);
-- usb_free_urb(as->usbin.surb[0].urb);
-- usb_free_urb(as->usbin.surb[1].urb);
-- usb_free_urb(as->usbout.durb[0].urb);
-- usb_free_urb(as->usbout.durb[1].urb);
-- usb_free_urb(as->usbout.surb[0].urb);
-- usb_free_urb(as->usbout.surb[1].urb);
-- kfree(as);
-- }
-- while (!list_empty(&s->mixerlist)) {
-- ms = list_entry(s->mixerlist.next, struct usb_mixerdev, list);
-- list_del(&ms->list);
-- kfree(ms);
-- }
-- kfree(s);
--}
--
--static inline int prog_dmabuf_in(struct usb_audiodev *as)
--{
-- usbin_stop(as);
-- return dmabuf_init(&as->usbin.dma);
--}
--
--static inline int prog_dmabuf_out(struct usb_audiodev *as)
--{
-- usbout_stop(as);
-- return dmabuf_init(&as->usbout.dma);
--}
--
--/* --------------------------------------------------------------------- */
--
--static int usb_audio_open_mixdev(struct inode *inode, struct file *file)
--{
-- unsigned int minor = iminor(inode);
-- struct usb_mixerdev *ms;
-- struct usb_audio_state *s;
--
-- down(&open_sem);
-- list_for_each_entry(s, &audiodevs, audiodev) {
-- list_for_each_entry(ms, &s->mixerlist, list) {
-- if (ms->dev_mixer == minor)
-- goto mixer_found;
-- }
-- }
-- up(&open_sem);
-- return -ENODEV;
--
-- mixer_found:
-- if (!s->usbdev) {
-- up(&open_sem);
-- return -EIO;
-- }
-- file->private_data = ms;
-- s->count++;
--
-- up(&open_sem);
-- return nonseekable_open(inode, file);
--}
--
--static int usb_audio_release_mixdev(struct inode *inode, struct file *file)
--{
-- struct usb_mixerdev *ms = (struct usb_mixerdev *)file->private_data;
-- struct usb_audio_state *s;
--
-- lock_kernel();
-- s = ms->state;
-- down(&open_sem);
-- release(s);
-- unlock_kernel();
-- return 0;
--}
--
--static int usb_audio_ioctl_mixdev(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
--{
-- struct usb_mixerdev *ms = (struct usb_mixerdev *)file->private_data;
-- int i, j, val;
-- int __user *user_arg = (int __user *)arg;
--
-- if (!ms->state->usbdev)
-- return -ENODEV;
--
-- if (cmd == SOUND_MIXER_INFO) {
-- mixer_info info;
--
-- memset(&info, 0, sizeof(info));
-- strncpy(info.id, "USB_AUDIO", sizeof(info.id));
-- strncpy(info.name, "USB Audio Class Driver", sizeof(info.name));
-- info.modify_counter = ms->modcnt;
-- if (copy_to_user((void __user *)arg, &info, sizeof(info)))
-- return -EFAULT;
-- return 0;
-- }
-- if (cmd == SOUND_OLD_MIXER_INFO) {
-- _old_mixer_info info;
--
-- memset(&info, 0, sizeof(info));
-- strncpy(info.id, "USB_AUDIO", sizeof(info.id));
-- strncpy(info.name, "USB Audio Class Driver", sizeof(info.name));
-- if (copy_to_user((void __user *)arg, &info, sizeof(info)))
-- return -EFAULT;
-- return 0;
-- }
-- if (cmd == OSS_GETVERSION)
-- return put_user(SOUND_VERSION, user_arg);
-- if (_IOC_TYPE(cmd) != 'M' || _IOC_SIZE(cmd) != sizeof(int))
-- return -EINVAL;
-- if (_IOC_DIR(cmd) == _IOC_READ) {
-- switch (_IOC_NR(cmd)) {
-- case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */
-- val = get_rec_src(ms);
-- if (val < 0)
-- return val;
-- return put_user(val, user_arg);
--
-- case SOUND_MIXER_DEVMASK: /* Arg contains a bit for each supported device */
-- for (val = i = 0; i < ms->numch; i++)
-- val |= 1 << ms->ch[i].osschannel;
-- return put_user(val, user_arg);
--
-- case SOUND_MIXER_RECMASK: /* Arg contains a bit for each supported recording source */
-- for (val = i = 0; i < ms->numch; i++)
-- if (ms->ch[i].slctunitid)
-- val |= 1 << ms->ch[i].osschannel;
-- return put_user(val, user_arg);
--
-- case SOUND_MIXER_STEREODEVS: /* Mixer channels supporting stereo */
-- for (val = i = 0; i < ms->numch; i++)
-- if (ms->ch[i].flags & (MIXFLG_STEREOIN | MIXFLG_STEREOOUT))
-- val |= 1 << ms->ch[i].osschannel;
-- return put_user(val, user_arg);
--
-- case SOUND_MIXER_CAPS:
-- return put_user(SOUND_CAP_EXCL_INPUT, user_arg);
--
-- default:
-- i = _IOC_NR(cmd);
-- if (i >= SOUND_MIXER_NRDEVICES)
-- return -EINVAL;
-- for (j = 0; j < ms->numch; j++) {
-- if (ms->ch[j].osschannel == i) {
-- return put_user(ms->ch[j].value, user_arg);
-- }
-- }
-- return -EINVAL;
-- }
-- }
-- if (_IOC_DIR(cmd) != (_IOC_READ|_IOC_WRITE))
-- return -EINVAL;
-- ms->modcnt++;
-- switch (_IOC_NR(cmd)) {
-- case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */
-- if (get_user(val, user_arg))
-- return -EFAULT;
-- return set_rec_src(ms, val);
--
-- default:
-- i = _IOC_NR(cmd);
-- if (i >= SOUND_MIXER_NRDEVICES)
-- return -EINVAL;
-- for (j = 0; j < ms->numch && ms->ch[j].osschannel != i; j++);
-- if (j >= ms->numch)
-- return -EINVAL;
-- if (get_user(val, user_arg))
-- return -EFAULT;
-- if (wrmixer(ms, j, val))
-- return -EIO;
-- return put_user(ms->ch[j].value, user_arg);
-- }
--}
--
--static /*const*/ struct file_operations usb_mixer_fops = {
-- .owner = THIS_MODULE,
-- .llseek = no_llseek,
-- .ioctl = usb_audio_ioctl_mixdev,
-- .open = usb_audio_open_mixdev,
-- .release = usb_audio_release_mixdev,
--};
--
--/* --------------------------------------------------------------------- */
--
--static int drain_out(struct usb_audiodev *as, int nonblock)
--{
-- DECLARE_WAITQUEUE(wait, current);
-- unsigned long flags;
-- int count, tmo;
--
-- if (as->usbout.dma.mapped || !as->usbout.dma.ready)
-- return 0;
-- usbout_start(as);
-- add_wait_queue(&as->usbout.dma.wait, &wait);
-- for (;;) {
-- __set_current_state(TASK_INTERRUPTIBLE);
-- spin_lock_irqsave(&as->lock, flags);
-- count = as->usbout.dma.count;
-- spin_unlock_irqrestore(&as->lock, flags);
-- if (count <= 0)
-- break;
-- if (signal_pending(current))
-- break;
-- if (nonblock) {
-- remove_wait_queue(&as->usbout.dma.wait, &wait);
-- set_current_state(TASK_RUNNING);
-- return -EBUSY;
-- }
-- tmo = 3 * HZ * count / as->usbout.dma.srate;
-- tmo >>= AFMT_BYTESSHIFT(as->usbout.dma.format);
-- if (!schedule_timeout(tmo + 1)) {
-- printk(KERN_DEBUG "usbaudio: dma timed out??\n");
-- break;
-- }
-- }
-- remove_wait_queue(&as->usbout.dma.wait, &wait);
-- set_current_state(TASK_RUNNING);
-- if (signal_pending(current))
-- return -ERESTARTSYS;
-- return 0;
--}
--
--/* --------------------------------------------------------------------- */
--
--static ssize_t usb_audio_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
--{
-- struct usb_audiodev *as = (struct usb_audiodev *)file->private_data;
-- DECLARE_WAITQUEUE(wait, current);
-- ssize_t ret = 0;
-- unsigned long flags;
-- unsigned int ptr;
-- int cnt, err;
--
-- if (as->usbin.dma.mapped)
-- return -ENXIO;
-- if (!as->usbin.dma.ready && (ret = prog_dmabuf_in(as)))
-- return ret;
-- if (!access_ok(VERIFY_WRITE, buffer, count))
-- return -EFAULT;
-- add_wait_queue(&as->usbin.dma.wait, &wait);
-- while (count > 0) {
-- spin_lock_irqsave(&as->lock, flags);
-- ptr = as->usbin.dma.rdptr;
-- cnt = as->usbin.dma.count;
-- /* set task state early to avoid wakeup races */
-- if (cnt <= 0)
-- __set_current_state(TASK_INTERRUPTIBLE);
-- spin_unlock_irqrestore(&as->lock, flags);
-- if (cnt > count)
-- cnt = count;
-- if (cnt <= 0) {
-- if (usbin_start(as)) {
-- if (!ret)
-- ret = -ENODEV;
-- break;
-- }
-- if (file->f_flags & O_NONBLOCK) {
-- if (!ret)
-- ret = -EAGAIN;
-- break;
-- }
-- schedule();
-- if (signal_pending(current)) {
-- if (!ret)
-- ret = -ERESTARTSYS;
-- break;
-- }
-- continue;
-- }
-- if ((err = dmabuf_copyout_user(&as->usbin.dma, ptr, buffer, cnt))) {
-- if (!ret)
-- ret = err;
-- break;
-- }
-- ptr += cnt;
-- if (ptr >= as->usbin.dma.dmasize)
-- ptr -= as->usbin.dma.dmasize;
-- spin_lock_irqsave(&as->lock, flags);
-- as->usbin.dma.rdptr = ptr;
-- as->usbin.dma.count -= cnt;
-- spin_unlock_irqrestore(&as->lock, flags);
-- count -= cnt;
-- buffer += cnt;
-- ret += cnt;
-- }
-- __set_current_state(TASK_RUNNING);
-- remove_wait_queue(&as->usbin.dma.wait, &wait);
-- return ret;
--}
--
--static ssize_t usb_audio_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
--{
-- struct usb_audiodev *as = (struct usb_audiodev *)file->private_data;
-- DECLARE_WAITQUEUE(wait, current);
-- ssize_t ret = 0;
-- unsigned long flags;
-- unsigned int ptr;
-- unsigned int start_thr;
-- int cnt, err;
--
-- if (as->usbout.dma.mapped)
-- return -ENXIO;
-- if (!as->usbout.dma.ready && (ret = prog_dmabuf_out(as)))
-- return ret;
-- if (!access_ok(VERIFY_READ, buffer, count))
-- return -EFAULT;
-- start_thr = (as->usbout.dma.srate << AFMT_BYTESSHIFT(as->usbout.dma.format)) / (1000 / (3 * DESCFRAMES));
-- add_wait_queue(&as->usbout.dma.wait, &wait);
-- while (count > 0) {
--#if 0
-- printk(KERN_DEBUG "usb_audio_write: count %u dma: count %u rdptr %u wrptr %u dmasize %u fragsize %u flags 0x%02x taskst 0x%lx\n",
-- count, as->usbout.dma.count, as->usbout.dma.rdptr, as->usbout.dma.wrptr, as->usbout.dma.dmasize, as->usbout.dma.fragsize,
-- as->usbout.flags, current->state);
--#endif
-- spin_lock_irqsave(&as->lock, flags);
-- if (as->usbout.dma.count < 0) {
-- as->usbout.dma.count = 0;
-- as->usbout.dma.rdptr = as->usbout.dma.wrptr;
-- }
-- ptr = as->usbout.dma.wrptr;
-- cnt = as->usbout.dma.dmasize - as->usbout.dma.count;
-- /* set task state early to avoid wakeup races */
-- if (cnt <= 0)
-- __set_current_state(TASK_INTERRUPTIBLE);
-- spin_unlock_irqrestore(&as->lock, flags);
-- if (cnt > count)
-- cnt = count;
-- if (cnt <= 0) {
-- if (usbout_start(as)) {
-- if (!ret)
-- ret = -ENODEV;
-- break;
-- }
-- if (file->f_flags & O_NONBLOCK) {
-- if (!ret)
-- ret = -EAGAIN;
-- break;
-- }
-- schedule();
-- if (signal_pending(current)) {
-- if (!ret)
-- ret = -ERESTARTSYS;
-- break;
-- }
-- continue;
-- }
-- if ((err = dmabuf_copyin_user(&as->usbout.dma, ptr, buffer, cnt))) {
-- if (!ret)
-- ret = err;
-- break;
-- }
-- ptr += cnt;
-- if (ptr >= as->usbout.dma.dmasize)
-- ptr -= as->usbout.dma.dmasize;
-- spin_lock_irqsave(&as->lock, flags);
-- as->usbout.dma.wrptr = ptr;
-- as->usbout.dma.count += cnt;
-- spin_unlock_irqrestore(&as->lock, flags);
-- count -= cnt;
-- buffer += cnt;
-- ret += cnt;
-- if (as->usbout.dma.count >= start_thr && usbout_start(as)) {
-- if (!ret)
-- ret = -ENODEV;
-- break;
-- }
-- }
-- __set_current_state(TASK_RUNNING);
-- remove_wait_queue(&as->usbout.dma.wait, &wait);
-- return ret;
--}
--
--/* Called without the kernel lock - fine */
--static unsigned int usb_audio_poll(struct file *file, struct poll_table_struct *wait)
--{
-- struct usb_audiodev *as = (struct usb_audiodev *)file->private_data;
-- unsigned long flags;
-- unsigned int mask = 0;
--
-- if (file->f_mode & FMODE_WRITE) {
-- if (!as->usbout.dma.ready)
-- prog_dmabuf_out(as);
-- poll_wait(file, &as->usbout.dma.wait, wait);
-- }
-- if (file->f_mode & FMODE_READ) {
-- if (!as->usbin.dma.ready)
-- prog_dmabuf_in(as);
-- poll_wait(file, &as->usbin.dma.wait, wait);
-- }
-- spin_lock_irqsave(&as->lock, flags);
-- if (file->f_mode & FMODE_READ) {
-- if (as->usbin.dma.count >= (signed)as->usbin.dma.fragsize)
-- mask |= POLLIN | POLLRDNORM;
-- }
-- if (file->f_mode & FMODE_WRITE) {
-- if (as->usbout.dma.mapped) {
-- if (as->usbout.dma.count >= (signed)as->usbout.dma.fragsize)
-- mask |= POLLOUT | POLLWRNORM;
-- } else {
-- if ((signed)as->usbout.dma.dmasize >= as->usbout.dma.count + (signed)as->usbout.dma.fragsize)
-- mask |= POLLOUT | POLLWRNORM;
-- }
-- }
-- spin_unlock_irqrestore(&as->lock, flags);
-- return mask;
--}
--
--static int usb_audio_mmap(struct file *file, struct vm_area_struct *vma)
--{
-- struct usb_audiodev *as = (struct usb_audiodev *)file->private_data;
-- struct dmabuf *db;
-- int ret = -EINVAL;
--
-- lock_kernel();
-- if (vma->vm_flags & VM_WRITE) {
-- if ((ret = prog_dmabuf_out(as)) != 0)
-- goto out;
-- db = &as->usbout.dma;
-- } else if (vma->vm_flags & VM_READ) {
-- if ((ret = prog_dmabuf_in(as)) != 0)
-- goto out;
-- db = &as->usbin.dma;
-- } else
-- goto out;
--
-- ret = -EINVAL;
-- if (vma->vm_pgoff != 0)
-- goto out;
--
-- ret = dmabuf_mmap(vma, db, vma->vm_start, vma->vm_end - vma->vm_start, vma->vm_page_prot);
--out:
-- unlock_kernel();
-- return ret;
--}
--
--static int usb_audio_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
--{
-- struct usb_audiodev *as = (struct usb_audiodev *)file->private_data;
-- struct usb_audio_state *s = as->state;
-- int __user *user_arg = (int __user *)arg;
-- unsigned long flags;
-- audio_buf_info abinfo;
-- count_info cinfo;
-- int val = 0;
-- int val2, mapped, ret;
--
-- if (!s->usbdev)
-- return -EIO;
-- mapped = ((file->f_mode & FMODE_WRITE) && as->usbout.dma.mapped) ||
-- ((file->f_mode & FMODE_READ) && as->usbin.dma.mapped);
--#if 0
-- if (arg)
-- get_user(val, (int *)arg);
-- printk(KERN_DEBUG "usbaudio: usb_audio_ioctl cmd=%x arg=%lx *arg=%d\n", cmd, arg, val)
--#endif
-- switch (cmd) {
-- case OSS_GETVERSION:
-- return put_user(SOUND_VERSION, user_arg);
--
-- case SNDCTL_DSP_SYNC:
-- if (file->f_mode & FMODE_WRITE)
-- return drain_out(as, 0/*file->f_flags & O_NONBLOCK*/);
-- return 0;
--
-- case SNDCTL_DSP_SETDUPLEX:
-- return 0;
--
-- case SNDCTL_DSP_GETCAPS:
-- return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER |
-- DSP_CAP_MMAP | DSP_CAP_BATCH, user_arg);
--
-- case SNDCTL_DSP_RESET:
-- if (file->f_mode & FMODE_WRITE) {
-- usbout_stop(as);
-- as->usbout.dma.rdptr = as->usbout.dma.wrptr = as->usbout.dma.count = as->usbout.dma.total_bytes = 0;
-- }
-- if (file->f_mode & FMODE_READ) {
-- usbin_stop(as);
-- as->usbin.dma.rdptr = as->usbin.dma.wrptr = as->usbin.dma.count = as->usbin.dma.total_bytes = 0;
-- }
-- return 0;
--
-- case SNDCTL_DSP_SPEED:
-- if (get_user(val, user_arg))
-- return -EFAULT;
-- if (val >= 0) {
-- if (val < 4000)
-- val = 4000;
-- if (val > 100000)
-- val = 100000;
-- if (set_format(as, file->f_mode, AFMT_QUERY, val))
-- return -EIO;
-- }
-- return put_user((file->f_mode & FMODE_READ) ?
-- as->usbin.dma.srate : as->usbout.dma.srate,
-- user_arg);
--
-- case SNDCTL_DSP_STEREO:
-- if (get_user(val, user_arg))
-- return -EFAULT;
-- val2 = (file->f_mode & FMODE_READ) ? as->usbin.dma.format : as->usbout.dma.format;
-- if (val)
-- val2 |= AFMT_STEREO;
-- else
-- val2 &= ~AFMT_STEREO;
-- if (set_format(as, file->f_mode, val2, 0))
-- return -EIO;
-- return 0;
--
-- case SNDCTL_DSP_CHANNELS:
-- if (get_user(val, user_arg))
-- return -EFAULT;
-- if (val != 0) {
-- val2 = (file->f_mode & FMODE_READ) ? as->usbin.dma.format : as->usbout.dma.format;
-- if (val == 1)
-- val2 &= ~AFMT_STEREO;
-- else
-- val2 |= AFMT_STEREO;
-- if (set_format(as, file->f_mode, val2, 0))
-- return -EIO;
-- }
-- val2 = (file->f_mode & FMODE_READ) ? as->usbin.dma.format : as->usbout.dma.format;
-- return put_user(AFMT_ISSTEREO(val2) ? 2 : 1, user_arg);
--
-- case SNDCTL_DSP_GETFMTS: /* Returns a mask */
-- return put_user(AFMT_U8 | AFMT_U16_LE | AFMT_U16_BE |
-- AFMT_S8 | AFMT_S16_LE | AFMT_S16_BE, user_arg);
--
-- case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
-- if (get_user(val, user_arg))
-- return -EFAULT;
-- if (val != AFMT_QUERY) {
-- if (hweight32(val) != 1)
-- return -EINVAL;
-- if (!(val & (AFMT_U8 | AFMT_U16_LE | AFMT_U16_BE |
-- AFMT_S8 | AFMT_S16_LE | AFMT_S16_BE)))
-- return -EINVAL;
-- val2 = (file->f_mode & FMODE_READ) ? as->usbin.dma.format : as->usbout.dma.format;
-- val |= val2 & AFMT_STEREO;
-- if (set_format(as, file->f_mode, val, 0))
-- return -EIO;
-- }
-- val2 = (file->f_mode & FMODE_READ) ? as->usbin.dma.format : as->usbout.dma.format;
-- return put_user(val2 & ~AFMT_STEREO, user_arg);
--
-- case SNDCTL_DSP_POST:
-- return 0;
--
-- case SNDCTL_DSP_GETTRIGGER:
-- val = 0;
-- if (file->f_mode & FMODE_READ && as->usbin.flags & FLG_RUNNING)
-- val |= PCM_ENABLE_INPUT;
-- if (file->f_mode & FMODE_WRITE && as->usbout.flags & FLG_RUNNING)
-- val |= PCM_ENABLE_OUTPUT;
-- return put_user(val, user_arg);
--
-- case SNDCTL_DSP_SETTRIGGER:
-- if (get_user(val, user_arg))
-- return -EFAULT;
-- if (file->f_mode & FMODE_READ) {
-- if (val & PCM_ENABLE_INPUT) {
-- if (!as->usbin.dma.ready && (ret = prog_dmabuf_in(as)))
-- return ret;
-- if (usbin_start(as))
-- return -ENODEV;
-- } else
-- usbin_stop(as);
-- }
-- if (file->f_mode & FMODE_WRITE) {
-- if (val & PCM_ENABLE_OUTPUT) {
-- if (!as->usbout.dma.ready && (ret = prog_dmabuf_out(as)))
-- return ret;
-- if (usbout_start(as))
-- return -ENODEV;
-- } else
-- usbout_stop(as);
-- }
-- return 0;
--
-- case SNDCTL_DSP_GETOSPACE:
-- if (!(file->f_mode & FMODE_WRITE))
-- return -EINVAL;
-- if (!(as->usbout.flags & FLG_RUNNING) && (val = prog_dmabuf_out(as)) != 0)
-- return val;
-- spin_lock_irqsave(&as->lock, flags);
-- abinfo.fragsize = as->usbout.dma.fragsize;
-- abinfo.bytes = as->usbout.dma.dmasize - as->usbout.dma.count;
-- abinfo.fragstotal = as->usbout.dma.numfrag;
-- abinfo.fragments = abinfo.bytes >> as->usbout.dma.fragshift;
-- spin_unlock_irqrestore(&as->lock, flags);
-- return copy_to_user((void __user *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
--
-- case SNDCTL_DSP_GETISPACE:
-- if (!(file->f_mode & FMODE_READ))
-- return -EINVAL;
-- if (!(as->usbin.flags & FLG_RUNNING) && (val = prog_dmabuf_in(as)) != 0)
-- return val;
-- spin_lock_irqsave(&as->lock, flags);
-- abinfo.fragsize = as->usbin.dma.fragsize;
-- abinfo.bytes = as->usbin.dma.count;
-- abinfo.fragstotal = as->usbin.dma.numfrag;
-- abinfo.fragments = abinfo.bytes >> as->usbin.dma.fragshift;
-- spin_unlock_irqrestore(&as->lock, flags);
-- return copy_to_user((void __user *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
--
-- case SNDCTL_DSP_NONBLOCK:
-- file->f_flags |= O_NONBLOCK;
-- return 0;
--
-- case SNDCTL_DSP_GETODELAY:
-- if (!(file->f_mode & FMODE_WRITE))
-- return -EINVAL;
-- spin_lock_irqsave(&as->lock, flags);
-- val = as->usbout.dma.count;
-- spin_unlock_irqrestore(&as->lock, flags);
-- return put_user(val, user_arg);
--
-- case SNDCTL_DSP_GETIPTR:
-- if (!(file->f_mode & FMODE_READ))
-- return -EINVAL;
-- spin_lock_irqsave(&as->lock, flags);
-- cinfo.bytes = as->usbin.dma.total_bytes;
-- cinfo.blocks = as->usbin.dma.count >> as->usbin.dma.fragshift;
-- cinfo.ptr = as->usbin.dma.wrptr;
-- if (as->usbin.dma.mapped)
-- as->usbin.dma.count &= as->usbin.dma.fragsize-1;
-- spin_unlock_irqrestore(&as->lock, flags);
-- if (copy_to_user((void __user *)arg, &cinfo, sizeof(cinfo)))
-- return -EFAULT;
-- return 0;
--
-- case SNDCTL_DSP_GETOPTR:
-- if (!(file->f_mode & FMODE_WRITE))
-- return -EINVAL;
-- spin_lock_irqsave(&as->lock, flags);
-- cinfo.bytes = as->usbout.dma.total_bytes;
-- cinfo.blocks = as->usbout.dma.count >> as->usbout.dma.fragshift;
-- cinfo.ptr = as->usbout.dma.rdptr;
-- if (as->usbout.dma.mapped)
-- as->usbout.dma.count &= as->usbout.dma.fragsize-1;
-- spin_unlock_irqrestore(&as->lock, flags);
-- if (copy_to_user((void __user *)arg, &cinfo, sizeof(cinfo)))
-- return -EFAULT;
-- return 0;
--
-- case SNDCTL_DSP_GETBLKSIZE:
-- if (file->f_mode & FMODE_WRITE) {
-- if ((val = prog_dmabuf_out(as)))
-- return val;
-- return put_user(as->usbout.dma.fragsize, user_arg);
-- }
-- if ((val = prog_dmabuf_in(as)))
-- return val;
-- return put_user(as->usbin.dma.fragsize, user_arg);
--
-- case SNDCTL_DSP_SETFRAGMENT:
-- if (get_user(val, user_arg))
-- return -EFAULT;
-- if (file->f_mode & FMODE_READ) {
-- as->usbin.dma.ossfragshift = val & 0xffff;
-- as->usbin.dma.ossmaxfrags = (val >> 16) & 0xffff;
-- if (as->usbin.dma.ossfragshift < 4)
-- as->usbin.dma.ossfragshift = 4;
-- if (as->usbin.dma.ossfragshift > 15)
-- as->usbin.dma.ossfragshift = 15;
-- if (as->usbin.dma.ossmaxfrags < 4)
-- as->usbin.dma.ossmaxfrags = 4;
-- }
-- if (file->f_mode & FMODE_WRITE) {
-- as->usbout.dma.ossfragshift = val & 0xffff;
-- as->usbout.dma.ossmaxfrags = (val >> 16) & 0xffff;
-- if (as->usbout.dma.ossfragshift < 4)
-- as->usbout.dma.ossfragshift = 4;
-- if (as->usbout.dma.ossfragshift > 15)
-- as->usbout.dma.ossfragshift = 15;
-- if (as->usbout.dma.ossmaxfrags < 4)
-- as->usbout.dma.ossmaxfrags = 4;
-- }
-- return 0;
--
-- case SNDCTL_DSP_SUBDIVIDE:
-- if ((file->f_mode & FMODE_READ && as->usbin.dma.subdivision) ||
-- (file->f_mode & FMODE_WRITE && as->usbout.dma.subdivision))
-- return -EINVAL;
-- if (get_user(val, user_arg))
-- return -EFAULT;
-- if (val != 1 && val != 2 && val != 4)
-- return -EINVAL;
-- if (file->f_mode & FMODE_READ)
-- as->usbin.dma.subdivision = val;
-- if (file->f_mode & FMODE_WRITE)
-- as->usbout.dma.subdivision = val;
-- return 0;
--
-- case SOUND_PCM_READ_RATE:
-- return put_user((file->f_mode & FMODE_READ) ?
-- as->usbin.dma.srate : as->usbout.dma.srate,
-- user_arg);
--
-- case SOUND_PCM_READ_CHANNELS:
-- val2 = (file->f_mode & FMODE_READ) ? as->usbin.dma.format : as->usbout.dma.format;
-- return put_user(AFMT_ISSTEREO(val2) ? 2 : 1, user_arg);
--
-- case SOUND_PCM_READ_BITS:
-- val2 = (file->f_mode & FMODE_READ) ? as->usbin.dma.format : as->usbout.dma.format;
-- return put_user(AFMT_IS16BIT(val2) ? 16 : 8, user_arg);
--
-- case SOUND_PCM_WRITE_FILTER:
-- case SNDCTL_DSP_SETSYNCRO:
-- case SOUND_PCM_READ_FILTER:
-- return -EINVAL;
-- }
-- dprintk((KERN_DEBUG "usbaudio: usb_audio_ioctl - no command found\n"));
-- return -ENOIOCTLCMD;
--}
--
--static int usb_audio_open(struct inode *inode, struct file *file)
--{
-- unsigned int minor = iminor(inode);
-- DECLARE_WAITQUEUE(wait, current);
-- struct usb_audiodev *as;
-- struct usb_audio_state *s;
--
-- for (;;) {
-- down(&open_sem);
-- list_for_each_entry(s, &audiodevs, audiodev) {
-- list_for_each_entry(as, &s->audiolist, list) {
-- if (!((as->dev_audio ^ minor) & ~0xf))
-- goto device_found;
-- }
-- }
-- up(&open_sem);
-- return -ENODEV;
--
-- device_found:
-- if (!s->usbdev) {
-- up(&open_sem);
-- return -EIO;
-- }
-- /* wait for device to become free */
-- if (!(as->open_mode & file->f_mode))
-- break;
-- if (file->f_flags & O_NONBLOCK) {
-- up(&open_sem);
-- return -EBUSY;
-- }
-- __set_current_state(TASK_INTERRUPTIBLE);
-- add_wait_queue(&open_wait, &wait);
-- up(&open_sem);
-- schedule();
-- __set_current_state(TASK_RUNNING);
-- remove_wait_queue(&open_wait, &wait);
-- if (signal_pending(current))
-- return -ERESTARTSYS;
-- }
-- if (file->f_mode & FMODE_READ)
-- as->usbin.dma.ossfragshift = as->usbin.dma.ossmaxfrags = as->usbin.dma.subdivision = 0;
-- if (file->f_mode & FMODE_WRITE)
-- as->usbout.dma.ossfragshift = as->usbout.dma.ossmaxfrags = as->usbout.dma.subdivision = 0;
-- if (set_format(as, file->f_mode, ((minor & 0xf) == SND_DEV_DSP16) ? AFMT_S16_LE : AFMT_U8 /* AFMT_ULAW */, 8000)) {
-- up(&open_sem);
-- return -EIO;
-- }
-- file->private_data = as;
-- as->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
-- s->count++;
-- up(&open_sem);
-- return nonseekable_open(inode, file);
--}
--
--static int usb_audio_release(struct inode *inode, struct file *file)
--{
-- struct usb_audiodev *as = (struct usb_audiodev *)file->private_data;
-- struct usb_audio_state *s;
-- struct usb_device *dev;
--
-- lock_kernel();
-- s = as->state;
-- dev = s->usbdev;
-- if (file->f_mode & FMODE_WRITE)
-- drain_out(as, file->f_flags & O_NONBLOCK);
-- down(&open_sem);
-- if (file->f_mode & FMODE_WRITE) {
-- usbout_stop(as);
-- if (dev && as->usbout.interface >= 0)
-- usb_set_interface(dev, as->usbout.interface, 0);
-- dmabuf_release(&as->usbout.dma);
-- usbout_release(as);
-- }
-- if (file->f_mode & FMODE_READ) {
-- usbin_stop(as);
-- if (dev && as->usbin.interface >= 0)
-- usb_set_interface(dev, as->usbin.interface, 0);
-- dmabuf_release(&as->usbin.dma);
-- usbin_release(as);
-- }
-- as->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE);
-- release(s);
-- wake_up(&open_wait);
-- unlock_kernel();
-- return 0;
--}
--
--static /*const*/ struct file_operations usb_audio_fops = {
-- .owner = THIS_MODULE,
-- .llseek = no_llseek,
-- .read = usb_audio_read,
-- .write = usb_audio_write,
-- .poll = usb_audio_poll,
-- .ioctl = usb_audio_ioctl,
-- .mmap = usb_audio_mmap,
-- .open = usb_audio_open,
-- .release = usb_audio_release,
--};
--
--/* --------------------------------------------------------------------- */
--
--static int usb_audio_probe(struct usb_interface *iface,
-- const struct usb_device_id *id);
--static void usb_audio_disconnect(struct usb_interface *iface);
--
--static struct usb_device_id usb_audio_ids [] = {
-- { .match_flags = (USB_DEVICE_ID_MATCH_INT_CLASS | USB_DEVICE_ID_MATCH_INT_SUBCLASS),
-- .bInterfaceClass = USB_CLASS_AUDIO, .bInterfaceSubClass = 1},
-- { } /* Terminating entry */
--};
--
--MODULE_DEVICE_TABLE (usb, usb_audio_ids);
--
--static struct usb_driver usb_audio_driver = {
-- .name = "audio",
-- .probe = usb_audio_probe,
-- .disconnect = usb_audio_disconnect,
-- .id_table = usb_audio_ids,
--};
--
--static void *find_descriptor(void *descstart, unsigned int desclen, void *after,
-- u8 dtype, int iface, int altsetting)
--{
-- u8 *p, *end, *next;
-- int ifc = -1, as = -1;
--
-- p = descstart;
-- end = p + desclen;
-- for (; p < end;) {
-- if (p[0] < 2)
-- return NULL;
-- next = p + p[0];
-- if (next > end)
-- return NULL;
-- if (p[1] == USB_DT_INTERFACE) {
-- /* minimum length of interface descriptor */
-- if (p[0] < 9)
-- return NULL;
-- ifc = p[2];
-- as = p[3];
-- }
-- if (p[1] == dtype && (!after || (void *)p > after) &&
-- (iface == -1 || iface == ifc) && (altsetting == -1 || altsetting == as)) {
-- return p;
-- }
-- p = next;
-- }
-- return NULL;
--}
--
--static void *find_csinterface_descriptor(void *descstart, unsigned int desclen, void *after, u8 dsubtype, int iface, int altsetting)
--{
-- unsigned char *p;
--
-- p = find_descriptor(descstart, desclen, after, USB_DT_CS_INTERFACE, iface, altsetting);
-- while (p) {
-- if (p[0] >= 3 && p[2] == dsubtype)
-- return p;
-- p = find_descriptor(descstart, desclen, p, USB_DT_CS_INTERFACE, iface, altsetting);
-- }
-- return NULL;
--}
--
--static void *find_audiocontrol_unit(void *descstart, unsigned int desclen, void *after, u8 unit, int iface)
--{
-- unsigned char *p;
--
-- p = find_descriptor(descstart, desclen, after, USB_DT_CS_INTERFACE, iface, -1);
-- while (p) {
-- if (p[0] >= 4 && p[2] >= INPUT_TERMINAL && p[2] <= EXTENSION_UNIT && p[3] == unit)
-- return p;
-- p = find_descriptor(descstart, desclen, p, USB_DT_CS_INTERFACE, iface, -1);
-- }
-- return NULL;
--}
--
--static void usb_audio_parsestreaming(struct usb_audio_state *s, unsigned char *buffer, unsigned int buflen, int asifin, int asifout)
--{
-- struct usb_device *dev = s->usbdev;
-- struct usb_audiodev *as;
-- struct usb_host_interface *alts;
-- struct usb_interface *iface;
-- struct audioformat *fp;
-- unsigned char *fmt, *csep;
-- unsigned int i, j, k, format, idx;
--
-- if (!(as = kmalloc(sizeof(struct usb_audiodev), GFP_KERNEL)))
-- return;
-- memset(as, 0, sizeof(struct usb_audiodev));
-- init_waitqueue_head(&as->usbin.dma.wait);
-- init_waitqueue_head(&as->usbout.dma.wait);
-- spin_lock_init(&as->lock);
-- as->usbin.durb[0].urb = usb_alloc_urb (DESCFRAMES, GFP_KERNEL);
-- as->usbin.durb[1].urb = usb_alloc_urb (DESCFRAMES, GFP_KERNEL);
-- as->usbin.surb[0].urb = usb_alloc_urb (SYNCFRAMES, GFP_KERNEL);
-- as->usbin.surb[1].urb = usb_alloc_urb (SYNCFRAMES, GFP_KERNEL);
-- as->usbout.durb[0].urb = usb_alloc_urb (DESCFRAMES, GFP_KERNEL);
-- as->usbout.durb[1].urb = usb_alloc_urb (DESCFRAMES, GFP_KERNEL);
-- as->usbout.surb[0].urb = usb_alloc_urb (SYNCFRAMES, GFP_KERNEL);
-- as->usbout.surb[1].urb = usb_alloc_urb (SYNCFRAMES, GFP_KERNEL);
-- if ((!as->usbin.durb[0].urb) ||
-- (!as->usbin.durb[1].urb) ||
-- (!as->usbin.surb[0].urb) ||
-- (!as->usbin.surb[1].urb) ||
-- (!as->usbout.durb[0].urb) ||
-- (!as->usbout.durb[1].urb) ||
-- (!as->usbout.surb[0].urb) ||
-- (!as->usbout.surb[1].urb)) {
-- usb_free_urb(as->usbin.durb[0].urb);
-- usb_free_urb(as->usbin.durb[1].urb);
-- usb_free_urb(as->usbin.surb[0].urb);
-- usb_free_urb(as->usbin.surb[1].urb);
-- usb_free_urb(as->usbout.durb[0].urb);
-- usb_free_urb(as->usbout.durb[1].urb);
-- usb_free_urb(as->usbout.surb[0].urb);
-- usb_free_urb(as->usbout.surb[1].urb);
-- kfree(as);
-- return;
-- }
-- as->state = s;
-- as->usbin.interface = asifin;
-- as->usbout.interface = asifout;
-- /* search for input formats */
-- if (asifin >= 0) {
-- as->usbin.flags = FLG_CONNECTED;
-- iface = usb_ifnum_to_if(dev, asifin);
-- for (idx = 0; idx < iface->num_altsetting; idx++) {
-- alts = &iface->altsetting[idx];
-- i = alts->desc.bAlternateSetting;
-- if (alts->desc.bInterfaceClass != USB_CLASS_AUDIO || alts->desc.bInterfaceSubClass != 2)
-- continue;
-- if (alts->desc.bNumEndpoints < 1) {
-- if (i != 0) { /* altsetting 0 has no endpoints (Section B.3.4.1) */
-- printk(KERN_ERR "usbaudio: device %u interface %u altsetting %u does not have an endpoint\n",
-- dev->devnum, asifin, i);
-- }
-- continue;
-- }
-- if ((alts->endpoint[0].desc.bmAttributes & 0x03) != 0x01 ||
-- !(alts->endpoint[0].desc.bEndpointAddress & 0x80)) {
-- printk(KERN_ERR "usbaudio: device %u interface %u altsetting %u first endpoint not isochronous in\n",
-- dev->devnum, asifin, i);
-- continue;
-- }
-- fmt = find_csinterface_descriptor(buffer, buflen, NULL, AS_GENERAL, asifin, i);
-- if (!fmt) {
-- printk(KERN_ERR "usbaudio: device %u interface %u altsetting %u FORMAT_TYPE descriptor not found\n",
-- dev->devnum, asifin, i);
-- continue;
-- }
-- if (fmt[0] < 7 || fmt[6] != 0 || (fmt[5] != 1 && fmt[5] != 2)) {
-- printk(KERN_ERR "usbaudio: device %u interface %u altsetting %u format not supported\n",
-- dev->devnum, asifin, i);
-- continue;
-- }
-- format = (fmt[5] == 2) ? (AFMT_U16_LE | AFMT_U8) : (AFMT_S16_LE | AFMT_S8);
-- fmt = find_csinterface_descriptor(buffer, buflen, NULL, FORMAT_TYPE, asifin, i);
-- if (!fmt) {
-- printk(KERN_ERR "usbaudio: device %u interface %u altsetting %u FORMAT_TYPE descriptor not found\n",
-- dev->devnum, asifin, i);
-- continue;
-- }
-- if (fmt[0] < 8+3*(fmt[7] ? fmt[7] : 2) || fmt[3] != 1) {
-- printk(KERN_ERR "usbaudio: device %u interface %u altsetting %u FORMAT_TYPE descriptor not supported\n",
-- dev->devnum, asifin, i);
-- continue;
-- }
-- if (fmt[4] < 1 || fmt[4] > 2 || fmt[5] < 1 || fmt[5] > 2) {
-- printk(KERN_ERR "usbaudio: device %u interface %u altsetting %u unsupported channels %u framesize %u\n",
-- dev->devnum, asifin, i, fmt[4], fmt[5]);
-- continue;
-- }
-- csep = find_descriptor(buffer, buflen, NULL, USB_DT_CS_ENDPOINT, asifin, i);
-- if (!csep || csep[0] < 7 || csep[2] != EP_GENERAL) {
-- printk(KERN_ERR "usbaudio: device %u interface %u altsetting %u no or invalid class specific endpoint descriptor\n",
-- dev->devnum, asifin, i);
-- continue;
-- }
-- if (as->numfmtin >= MAXFORMATS)
-- continue;
-- fp = &as->fmtin[as->numfmtin++];
-- if (fmt[5] == 2)
-- format &= (AFMT_U16_LE | AFMT_S16_LE);
-- else
-- format &= (AFMT_U8 | AFMT_S8);
-- if (fmt[4] == 2)
-- format |= AFMT_STEREO;
-- fp->format = format;
-- fp->altsetting = i;
-- fp->sratelo = fp->sratehi = fmt[8] | (fmt[9] << 8) | (fmt[10] << 16);
-- printk(KERN_INFO "usbaudio: valid input sample rate %u\n", fp->sratelo);
-- for (j = fmt[7] ? (fmt[7]-1) : 1; j > 0; j--) {
-- k = fmt[8+3*j] | (fmt[9+3*j] << 8) | (fmt[10+3*j] << 16);
-- printk(KERN_INFO "usbaudio: valid input sample rate %u\n", k);
-- if (k > fp->sratehi)
-- fp->sratehi = k;
-- if (k < fp->sratelo)
-- fp->sratelo = k;
-- }
-- fp->attributes = csep[3];
-- printk(KERN_INFO "usbaudio: device %u interface %u altsetting %u: format 0x%08x sratelo %u sratehi %u attributes 0x%02x\n",
-- dev->devnum, asifin, i, fp->format, fp->sratelo, fp->sratehi, fp->attributes);
-- }
-- }
-- /* search for output formats */
-- if (asifout >= 0) {
-- as->usbout.flags = FLG_CONNECTED;
-- iface = usb_ifnum_to_if(dev, asifout);
-- for (idx = 0; idx < iface->num_altsetting; idx++) {
-- alts = &iface->altsetting[idx];
-- i = alts->desc.bAlternateSetting;
-- if (alts->desc.bInterfaceClass != USB_CLASS_AUDIO || alts->desc.bInterfaceSubClass != 2)
-- continue;
-- if (alts->desc.bNumEndpoints < 1) {
-- /* altsetting 0 should never have iso EPs */
-- if (i != 0)
-- printk(KERN_ERR "usbaudio: device %u interface %u altsetting %u does not have an endpoint\n",
-- dev->devnum, asifout, i);
-- continue;
-- }
-- if ((alts->endpoint[0].desc.bmAttributes & 0x03) != 0x01 ||
-- (alts->endpoint[0].desc.bEndpointAddress & 0x80)) {
-- printk(KERN_ERR "usbaudio: device %u interface %u altsetting %u first endpoint not isochronous out\n",
-- dev->devnum, asifout, i);
-- continue;
-- }
-- /* See USB audio formats manual, section 2 */
-- fmt = find_csinterface_descriptor(buffer, buflen, NULL, AS_GENERAL, asifout, i);
-- if (!fmt) {
-- printk(KERN_ERR "usbaudio: device %u interface %u altsetting %u FORMAT_TYPE descriptor not found\n",
-- dev->devnum, asifout, i);
-- continue;
-- }
-- if (fmt[0] < 7 || fmt[6] != 0 || (fmt[5] != 1 && fmt[5] != 2)) {
-- printk(KERN_ERR "usbaudio: device %u interface %u altsetting %u format not supported\n",
-- dev->devnum, asifout, i);
-- continue;
-- }
-- format = (fmt[5] == 2) ? (AFMT_U16_LE | AFMT_U8) : (AFMT_S16_LE | AFMT_S8);
-- /* Dallas DS4201 workaround */
-- if (le16_to_cpu(dev->descriptor.idVendor) == 0x04fa &&
-- le16_to_cpu(dev->descriptor.idProduct) == 0x4201)
-- format = (AFMT_S16_LE | AFMT_S8);
-- fmt = find_csinterface_descriptor(buffer, buflen, NULL, FORMAT_TYPE, asifout, i);
-- if (!fmt) {
-- printk(KERN_ERR "usbaudio: device %u interface %u altsetting %u FORMAT_TYPE descriptor not found\n",
-- dev->devnum, asifout, i);
-- continue;
-- }
-- if (fmt[0] < 8+3*(fmt[7] ? fmt[7] : 2) || fmt[3] != 1) {
-- printk(KERN_ERR "usbaudio: device %u interface %u altsetting %u FORMAT_TYPE descriptor not supported\n",
-- dev->devnum, asifout, i);
-- continue;
-- }
-- if (fmt[4] < 1 || fmt[4] > 2 || fmt[5] < 1 || fmt[5] > 2) {
-- printk(KERN_ERR "usbaudio: device %u interface %u altsetting %u unsupported channels %u framesize %u\n",
-- dev->devnum, asifout, i, fmt[4], fmt[5]);
-- continue;
-- }
-- csep = find_descriptor(buffer, buflen, NULL, USB_DT_CS_ENDPOINT, asifout, i);
-- if (!csep || csep[0] < 7 || csep[2] != EP_GENERAL) {
-- printk(KERN_ERR "usbaudio: device %u interface %u altsetting %u no or invalid class specific endpoint descriptor\n",
-- dev->devnum, asifout, i);
-- continue;
-- }
-- if (as->numfmtout >= MAXFORMATS)
-- continue;
-- fp = &as->fmtout[as->numfmtout++];
-- if (fmt[5] == 2)
-- format &= (AFMT_U16_LE | AFMT_S16_LE);
-- else
-- format &= (AFMT_U8 | AFMT_S8);
-- if (fmt[4] == 2)
-- format |= AFMT_STEREO;
-- fp->format = format;
-- fp->altsetting = i;
-- fp->sratelo = fp->sratehi = fmt[8] | (fmt[9] << 8) | (fmt[10] << 16);
-- printk(KERN_INFO "usbaudio: valid output sample rate %u\n", fp->sratelo);
-- for (j = fmt[7] ? (fmt[7]-1) : 1; j > 0; j--) {
-- k = fmt[8+3*j] | (fmt[9+3*j] << 8) | (fmt[10+3*j] << 16);
-- printk(KERN_INFO "usbaudio: valid output sample rate %u\n", k);
-- if (k > fp->sratehi)
-- fp->sratehi = k;
-- if (k < fp->sratelo)
-- fp->sratelo = k;
-- }
-- fp->attributes = csep[3];
-- printk(KERN_INFO "usbaudio: device %u interface %u altsetting %u: format 0x%08x sratelo %u sratehi %u attributes 0x%02x\n",
-- dev->devnum, asifout, i, fp->format, fp->sratelo, fp->sratehi, fp->attributes);
-- }
-- }
-- if (as->numfmtin == 0 && as->numfmtout == 0) {
-- usb_free_urb(as->usbin.durb[0].urb);
-- usb_free_urb(as->usbin.durb[1].urb);
-- usb_free_urb(as->usbin.surb[0].urb);
-- usb_free_urb(as->usbin.surb[1].urb);
-- usb_free_urb(as->usbout.durb[0].urb);
-- usb_free_urb(as->usbout.durb[1].urb);
-- usb_free_urb(as->usbout.surb[0].urb);
-- usb_free_urb(as->usbout.surb[1].urb);
-- kfree(as);
-- return;
-- }
-- if ((as->dev_audio = register_sound_dsp(&usb_audio_fops, -1)) < 0) {
-- printk(KERN_ERR "usbaudio: cannot register dsp\n");
-- usb_free_urb(as->usbin.durb[0].urb);
-- usb_free_urb(as->usbin.durb[1].urb);
-- usb_free_urb(as->usbin.surb[0].urb);
-- usb_free_urb(as->usbin.surb[1].urb);
-- usb_free_urb(as->usbout.durb[0].urb);
-- usb_free_urb(as->usbout.durb[1].urb);
-- usb_free_urb(as->usbout.surb[0].urb);
-- usb_free_urb(as->usbout.surb[1].urb);
-- kfree(as);
-- return;
-- }
-- printk(KERN_INFO "usbaudio: registered dsp 14,%d\n", as->dev_audio);
-- /* everything successful */
-- list_add_tail(&as->list, &s->audiolist);
--}
--
--struct consmixstate {
-- struct usb_audio_state *s;
-- unsigned char *buffer;
-- unsigned int buflen;
-- unsigned int ctrlif;
-- struct mixerchannel mixch[SOUND_MIXER_NRDEVICES];
-- unsigned int nrmixch;
-- unsigned int mixchmask;
-- unsigned long unitbitmap[32/sizeof(unsigned long)];
-- /* return values */
-- unsigned int nrchannels;
-- unsigned int termtype;
-- unsigned int chconfig;
--};
--
--static struct mixerchannel *getmixchannel(struct consmixstate *state, unsigned int nr)
--{
-- struct mixerchannel *c;
--
-- if (nr >= SOUND_MIXER_NRDEVICES) {
-- printk(KERN_ERR "usbaudio: invalid OSS mixer channel %u\n", nr);
-- return NULL;
-- }
-- if (!(state->mixchmask & (1 << nr))) {
-- printk(KERN_WARNING "usbaudio: OSS mixer channel %u already in use\n", nr);
-- return NULL;
-- }
-- c = &state->mixch[state->nrmixch++];
-- c->osschannel = nr;
-- state->mixchmask &= ~(1 << nr);
-- return c;
--}
--
--static unsigned int getvolchannel(struct consmixstate *state)
--{
-- unsigned int u;
--
-- if ((state->termtype & 0xff00) == 0x0000 && (state->mixchmask & SOUND_MASK_VOLUME))
-- return SOUND_MIXER_VOLUME;
-- if ((state->termtype & 0xff00) == 0x0100) {
-- if (state->mixchmask & SOUND_MASK_PCM)
-- return SOUND_MIXER_PCM;
-- if (state->mixchmask & SOUND_MASK_ALTPCM)
-- return SOUND_MIXER_ALTPCM;
-- }
-- if ((state->termtype & 0xff00) == 0x0200 && (state->mixchmask & SOUND_MASK_MIC))
-- return SOUND_MIXER_MIC;
-- if ((state->termtype & 0xff00) == 0x0300 && (state->mixchmask & SOUND_MASK_SPEAKER))
-- return SOUND_MIXER_SPEAKER;
-- if ((state->termtype & 0xff00) == 0x0500) {
-- if (state->mixchmask & SOUND_MASK_PHONEIN)
-- return SOUND_MIXER_PHONEIN;
-- if (state->mixchmask & SOUND_MASK_PHONEOUT)
-- return SOUND_MIXER_PHONEOUT;
-- }
-- if (state->termtype >= 0x710 && state->termtype <= 0x711 && (state->mixchmask & SOUND_MASK_RADIO))
-- return SOUND_MIXER_RADIO;
-- if (state->termtype >= 0x709 && state->termtype <= 0x70f && (state->mixchmask & SOUND_MASK_VIDEO))
-- return SOUND_MIXER_VIDEO;
-- u = ffs(state->mixchmask & (SOUND_MASK_LINE | SOUND_MASK_CD | SOUND_MASK_LINE1 | SOUND_MASK_LINE2 | SOUND_MASK_LINE3 |
-- SOUND_MASK_DIGITAL1 | SOUND_MASK_DIGITAL2 | SOUND_MASK_DIGITAL3));
-- return u-1;
--}
--
--static void prepmixch(struct consmixstate *state)
--{
-- struct usb_device *dev = state->s->usbdev;
-- struct mixerchannel *ch;
-- unsigned char *buf;
-- __s16 v1;
-- unsigned int v2, v3;
--
-- if (!state->nrmixch || state->nrmixch > SOUND_MIXER_NRDEVICES)
-- return;
-- buf = kmalloc(sizeof(*buf) * 2, GFP_KERNEL);
-- if (!buf) {
-- printk(KERN_ERR "prepmixch: out of memory\n") ;
-- return;
-- }
--
-- ch = &state->mixch[state->nrmixch-1];
-- switch (ch->selector) {
-- case 0: /* mixer unit request */
-- if (usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), GET_MIN, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
-- (ch->chnum << 8) | 1, state->ctrlif | (ch->unitid << 8), buf, 2, 1000) < 0)
-- goto err;
-- ch->minval = buf[0] | (buf[1] << 8);
-- if (usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), GET_MAX, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
-- (ch->chnum << 8) | 1, state->ctrlif | (ch->unitid << 8), buf, 2, 1000) < 0)
-- goto err;
-- ch->maxval = buf[0] | (buf[1] << 8);
-- v2 = ch->maxval - ch->minval;
-- if (!v2)
-- v2 = 1;
-- if (usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), GET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
-- (ch->chnum << 8) | 1, state->ctrlif | (ch->unitid << 8), buf, 2, 1000) < 0)
-- goto err;
-- v1 = buf[0] | (buf[1] << 8);
-- v3 = v1 - ch->minval;
-- v3 = 100 * v3 / v2;
-- if (v3 > 100)
-- v3 = 100;
-- ch->value = v3;
-- if (ch->flags & (MIXFLG_STEREOIN | MIXFLG_STEREOOUT)) {
-- if (usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), GET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
-- ((ch->chnum + !!(ch->flags & MIXFLG_STEREOIN)) << 8) | (1 + !!(ch->flags & MIXFLG_STEREOOUT)),
-- state->ctrlif | (ch->unitid << 8), buf, 2, 1000) < 0)
-- goto err;
-- v1 = buf[0] | (buf[1] << 8);
-- v3 = v1 - ch->minval;
-- v3 = 100 * v3 / v2;
-- if (v3 > 100)
-- v3 = 100;
-- }
-- ch->value |= v3 << 8;
-- break;
--
-- /* various feature unit controls */
-- case VOLUME_CONTROL:
-- if (usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), GET_MIN, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
-- (ch->selector << 8) | ch->chnum, state->ctrlif | (ch->unitid << 8), buf, 2, 1000) < 0)
-- goto err;
-- ch->minval = buf[0] | (buf[1] << 8);
-- if (usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), GET_MAX, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
-- (ch->selector << 8) | ch->chnum, state->ctrlif | (ch->unitid << 8), buf, 2, 1000) < 0)
-- goto err;
-- ch->maxval = buf[0] | (buf[1] << 8);
-- if (usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), GET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
-- (ch->selector << 8) | ch->chnum, state->ctrlif | (ch->unitid << 8), buf, 2, 1000) < 0)
-- goto err;
-- v1 = buf[0] | (buf[1] << 8);
-- v2 = ch->maxval - ch->minval;
-- v3 = v1 - ch->minval;
-- if (!v2)
-- v2 = 1;
-- v3 = 100 * v3 / v2;
-- if (v3 > 100)
-- v3 = 100;
-- ch->value = v3;
-- if (ch->flags & (MIXFLG_STEREOIN | MIXFLG_STEREOOUT)) {
-- if (usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), GET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
-- (ch->selector << 8) | (ch->chnum + 1), state->ctrlif | (ch->unitid << 8), buf, 2, 1000) < 0)
-- goto err;
-- v1 = buf[0] | (buf[1] << 8);
-- v3 = v1 - ch->minval;
-- v3 = 100 * v3 / v2;
-- if (v3 > 100)
-- v3 = 100;
-- }
-- ch->value |= v3 << 8;
-- break;
--
-- case BASS_CONTROL:
-- case MID_CONTROL:
-- case TREBLE_CONTROL:
-- if (usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), GET_MIN, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
-- (ch->selector << 8) | ch->chnum, state->ctrlif | (ch->unitid << 8), buf, 1, 1000) < 0)
-- goto err;
-- ch->minval = buf[0] << 8;
-- if (usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), GET_MAX, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
-- (ch->selector << 8) | ch->chnum, state->ctrlif | (ch->unitid << 8), buf, 1, 1000) < 0)
-- goto err;
-- ch->maxval = buf[0] << 8;
-- if (usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), GET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
-- (ch->selector << 8) | ch->chnum, state->ctrlif | (ch->unitid << 8), buf, 1, 1000) < 0)
-- goto err;
-- v1 = buf[0] << 8;
-- v2 = ch->maxval - ch->minval;
-- v3 = v1 - ch->minval;
-- if (!v2)
-- v2 = 1;
-- v3 = 100 * v3 / v2;
-- if (v3 > 100)
-- v3 = 100;
-- ch->value = v3;
-- if (ch->flags & (MIXFLG_STEREOIN | MIXFLG_STEREOOUT)) {
-- if (usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), GET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
-- (ch->selector << 8) | (ch->chnum + 1), state->ctrlif | (ch->unitid << 8), buf, 1, 1000) < 0)
-- goto err;
-- v1 = buf[0] << 8;
-- v3 = v1 - ch->minval;
-- v3 = 100 * v3 / v2;
-- if (v3 > 100)
-- v3 = 100;
-- }
-- ch->value |= v3 << 8;
-- break;
--
-- default:
-- goto err;
-- }
--
-- freebuf:
-- kfree(buf);
-- return;
-- err:
-- printk(KERN_ERR "usbaudio: mixer request device %u if %u unit %u ch %u selector %u failed\n",
-- dev->devnum, state->ctrlif, ch->unitid, ch->chnum, ch->selector);
-- if (state->nrmixch)
-- state->nrmixch--;
-- goto freebuf;
--}
--
--
--static void usb_audio_recurseunit(struct consmixstate *state, unsigned char unitid);
--
--static inline int checkmixbmap(unsigned char *bmap, unsigned char flg, unsigned int inidx, unsigned int numoch)
--{
-- unsigned int idx;
--
-- idx = inidx*numoch;
-- if (!(bmap[-(idx >> 3)] & (0x80 >> (idx & 7))))
-- return 0;
-- if (!(flg & (MIXFLG_STEREOIN | MIXFLG_STEREOOUT)))
-- return 1;
-- idx = (inidx+!!(flg & MIXFLG_STEREOIN))*numoch+!!(flg & MIXFLG_STEREOOUT);
-- if (!(bmap[-(idx >> 3)] & (0x80 >> (idx & 7))))
-- return 0;
-- return 1;
--}
--
--static void usb_audio_mixerunit(struct consmixstate *state, unsigned char *mixer)
--{
-- unsigned int nroutch = mixer[5+mixer[4]];
-- unsigned int chidx[SOUND_MIXER_NRDEVICES+1];
-- unsigned int termt[SOUND_MIXER_NRDEVICES];
-- unsigned char flg = (nroutch >= 2) ? MIXFLG_STEREOOUT : 0;
-- unsigned char *bmap = &mixer[9+mixer[4]];
-- unsigned int bmapsize;
-- struct mixerchannel *ch;
-- unsigned int i;
--
-- if (!mixer[4]) {
-- printk(KERN_ERR "usbaudio: unit %u invalid MIXER_UNIT descriptor\n", mixer[3]);
-- return;
-- }
-- if (mixer[4] > SOUND_MIXER_NRDEVICES) {
-- printk(KERN_ERR "usbaudio: mixer unit %u: too many input pins\n", mixer[3]);
-- return;
-- }
-- chidx[0] = 0;
-- for (i = 0; i < mixer[4]; i++) {
-- usb_audio_recurseunit(state, mixer[5+i]);
-- chidx[i+1] = chidx[i] + state->nrchannels;
-- termt[i] = state->termtype;
-- }
-- state->termtype = 0;
-- state->chconfig = mixer[6+mixer[4]] | (mixer[7+mixer[4]] << 8);
-- bmapsize = (nroutch * chidx[mixer[4]] + 7) >> 3;
-- bmap += bmapsize - 1;
-- if (mixer[0] < 10+mixer[4]+bmapsize) {
-- printk(KERN_ERR "usbaudio: unit %u invalid MIXER_UNIT descriptor (bitmap too small)\n", mixer[3]);
-- return;
-- }
-- for (i = 0; i < mixer[4]; i++) {
-- state->termtype = termt[i];
-- if (chidx[i+1]-chidx[i] >= 2) {
-- flg |= MIXFLG_STEREOIN;
-- if (checkmixbmap(bmap, flg, chidx[i], nroutch)) {
-- ch = getmixchannel(state, getvolchannel(state));
-- if (ch) {
-- ch->unitid = mixer[3];
-- ch->selector = 0;
-- ch->chnum = chidx[i]+1;
-- ch->flags = flg;
-- prepmixch(state);
-- }
-- continue;
-- }
-- }
-- flg &= ~MIXFLG_STEREOIN;
-- if (checkmixbmap(bmap, flg, chidx[i], nroutch)) {
-- ch = getmixchannel(state, getvolchannel(state));
-- if (ch) {
-- ch->unitid = mixer[3];
-- ch->selector = 0;
-- ch->chnum = chidx[i]+1;
-- ch->flags = flg;
-- prepmixch(state);
-- }
-- }
-- }
-- state->termtype = 0;
--}
--
--static struct mixerchannel *slctsrc_findunit(struct consmixstate *state, __u8 unitid)
--{
-- unsigned int i;
--
-- for (i = 0; i < state->nrmixch; i++)
-- if (state->mixch[i].unitid == unitid)
-- return &state->mixch[i];
-- return NULL;
--}
--
--static void usb_audio_selectorunit(struct consmixstate *state, unsigned char *selector)
--{
-- unsigned int chnum, i, mixch;
-- struct mixerchannel *mch;
--
-- if (!selector[4]) {
-- printk(KERN_ERR "usbaudio: unit %u invalid SELECTOR_UNIT descriptor\n", selector[3]);
-- return;
-- }
-- mixch = state->nrmixch;
-- usb_audio_recurseunit(state, selector[5]);
-- if (state->nrmixch != mixch) {
-- mch = &state->mixch[state->nrmixch-1];
-- mch->slctunitid = selector[3] | (1 << 8);
-- } else if ((mch = slctsrc_findunit(state, selector[5]))) {
-- mch->slctunitid = selector[3] | (1 << 8);
-- } else {
-- printk(KERN_INFO "usbaudio: selector unit %u: ignoring channel 1\n", selector[3]);
-- }
-- chnum = state->nrchannels;
-- for (i = 1; i < selector[4]; i++) {
-- mixch = state->nrmixch;
-- usb_audio_recurseunit(state, selector[5+i]);
-- if (chnum != state->nrchannels) {
-- printk(KERN_ERR "usbaudio: selector unit %u: input pins with varying channel numbers\n", selector[3]);
-- state->termtype = 0;
-- state->chconfig = 0;
-- state->nrchannels = 0;
-- return;
-- }
-- if (state->nrmixch != mixch) {
-- mch = &state->mixch[state->nrmixch-1];
-- mch->slctunitid = selector[3] | ((i + 1) << 8);
-- } else if ((mch = slctsrc_findunit(state, selector[5+i]))) {
-- mch->slctunitid = selector[3] | ((i + 1) << 8);
-- } else {
-- printk(KERN_INFO "usbaudio: selector unit %u: ignoring channel %u\n", selector[3], i+1);
-- }
-- }
-- state->termtype = 0;
-- state->chconfig = 0;
--}
--
--/* in the future we might try to handle 3D etc. effect units */
--
--static void usb_audio_processingunit(struct consmixstate *state, unsigned char *proc)
--{
-- unsigned int i;
--
-- for (i = 0; i < proc[6]; i++)
-- usb_audio_recurseunit(state, proc[7+i]);
-- state->nrchannels = proc[7+proc[6]];
-- state->termtype = 0;
-- state->chconfig = proc[8+proc[6]] | (proc[9+proc[6]] << 8);
--}
--
--
--/* See Audio Class Spec, section 4.3.2.5 */
--static void usb_audio_featureunit(struct consmixstate *state, unsigned char *ftr)
--{
-- struct mixerchannel *ch;
-- unsigned short chftr, mchftr;
--#if 0
-- struct usb_device *dev = state->s->usbdev;
-- unsigned char data[1];
--#endif
-- unsigned char nr_logical_channels, i;
--
-- usb_audio_recurseunit(state, ftr[4]);
--
-- if (ftr[5] == 0 ) {
-- printk(KERN_ERR "usbaudio: wrong controls size in feature unit %u\n",ftr[3]);
-- return;
-- }
--
-- if (state->nrchannels == 0) {
-- printk(KERN_ERR "usbaudio: feature unit %u source has no channels\n", ftr[3]);
-- return;
-- }
-- if (state->nrchannels > 2)
-- printk(KERN_WARNING "usbaudio: feature unit %u: OSS mixer interface does not support more than 2 channels\n", ftr[3]);
--
-- nr_logical_channels=(ftr[0]-7)/ftr[5]-1;
--
-- if (nr_logical_channels != state->nrchannels) {
-- printk(KERN_WARNING "usbaudio: warning: found %d of %d logical channels.\n", state->nrchannels,nr_logical_channels);
--
-- if (state->nrchannels == 1 && nr_logical_channels==0) {
-- printk(KERN_INFO "usbaudio: assuming the channel found is the master channel (got a Philips camera?). Should be fine.\n");
-- } else if (state->nrchannels == 1 && nr_logical_channels==2) {
-- printk(KERN_INFO "usbaudio: assuming that a stereo channel connected directly to a mixer is missing in search (got Labtec headset?). Should be fine.\n");
-- state->nrchannels=nr_logical_channels;
-- } else {
-- printk(KERN_WARNING "usbaudio: no idea what's going on..., contact linux-usb-devel@lists.sourceforge.net\n");
-- }
-- }
--
-- /* There is always a master channel */
-- mchftr = ftr[6];
-- /* Binary AND over logical channels if they exist */
-- if (nr_logical_channels) {
-- chftr = ftr[6+ftr[5]];
-- for (i = 2; i <= nr_logical_channels; i++)
-- chftr &= ftr[6+i*ftr[5]];
-- } else {
-- chftr = 0;
-- }
--
-- /* volume control */
-- if (chftr & 2) {
-- ch = getmixchannel(state, getvolchannel(state));
-- if (ch) {
-- ch->unitid = ftr[3];
-- ch->selector = VOLUME_CONTROL;
-- ch->chnum = 1;
-- ch->flags = (state->nrchannels > 1) ? (MIXFLG_STEREOIN | MIXFLG_STEREOOUT) : 0;
-- prepmixch(state);
-- }
-- } else if (mchftr & 2) {
-- ch = getmixchannel(state, getvolchannel(state));
-- if (ch) {
-- ch->unitid = ftr[3];
-- ch->selector = VOLUME_CONTROL;
-- ch->chnum = 0;
-- ch->flags = 0;
-- prepmixch(state);
-- }
-- }
-- /* bass control */
-- if (chftr & 4) {
-- ch = getmixchannel(state, SOUND_MIXER_BASS);
-- if (ch) {
-- ch->unitid = ftr[3];
-- ch->selector = BASS_CONTROL;
-- ch->chnum = 1;
-- ch->flags = (state->nrchannels > 1) ? (MIXFLG_STEREOIN | MIXFLG_STEREOOUT) : 0;
-- prepmixch(state);
-- }
-- } else if (mchftr & 4) {
-- ch = getmixchannel(state, SOUND_MIXER_BASS);
-- if (ch) {
-- ch->unitid = ftr[3];
-- ch->selector = BASS_CONTROL;
-- ch->chnum = 0;
-- ch->flags = 0;
-- prepmixch(state);
-- }
-- }
-- /* treble control */
-- if (chftr & 16) {
-- ch = getmixchannel(state, SOUND_MIXER_TREBLE);
-- if (ch) {
-- ch->unitid = ftr[3];
-- ch->selector = TREBLE_CONTROL;
-- ch->chnum = 1;
-- ch->flags = (state->nrchannels > 1) ? (MIXFLG_STEREOIN | MIXFLG_STEREOOUT) : 0;
-- prepmixch(state);
-- }
-- } else if (mchftr & 16) {
-- ch = getmixchannel(state, SOUND_MIXER_TREBLE);
-- if (ch) {
-- ch->unitid = ftr[3];
-- ch->selector = TREBLE_CONTROL;
-- ch->chnum = 0;
-- ch->flags = 0;
-- prepmixch(state);
-- }
-- }
--#if 0
-- /* if there are mute controls, unmute them */
-- /* does not seem to be necessary, and the Dallas chip does not seem to support the "all" channel (255) */
-- if ((chftr & 1) || (mchftr & 1)) {
-- printk(KERN_DEBUG "usbaudio: unmuting feature unit %u interface %u\n", ftr[3], state->ctrlif);
-- data[0] = 0;
-- if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT,
-- (MUTE_CONTROL << 8) | 0xff, state->ctrlif | (ftr[3] << 8), data, 1, 1000) < 0)
-- printk(KERN_WARNING "usbaudio: failure to unmute feature unit %u interface %u\n", ftr[3], state->ctrlif);
-- }
--#endif
--}
--
--static void usb_audio_recurseunit(struct consmixstate *state, unsigned char unitid)
--{
-- unsigned char *p1;
-- unsigned int i, j;
--
-- if (test_and_set_bit(unitid, state->unitbitmap)) {
-- printk(KERN_INFO "usbaudio: mixer path revisits unit %d\n", unitid);
-- return;
-- }
-- p1 = find_audiocontrol_unit(state->buffer, state->buflen, NULL, unitid, state->ctrlif);
-- if (!p1) {
-- printk(KERN_ERR "usbaudio: unit %d not found!\n", unitid);
-- return;
-- }
-- state->nrchannels = 0;
-- state->termtype = 0;
-- state->chconfig = 0;
-- switch (p1[2]) {
-- case INPUT_TERMINAL:
-- if (p1[0] < 12) {
-- printk(KERN_ERR "usbaudio: unit %u: invalid INPUT_TERMINAL descriptor\n", unitid);
-- return;
-- }
-- state->nrchannels = p1[7];
-- state->termtype = p1[4] | (p1[5] << 8);
-- state->chconfig = p1[8] | (p1[9] << 8);
-- return;
--
-- case MIXER_UNIT:
-- if (p1[0] < 10 || p1[0] < 10+p1[4]) {
-- printk(KERN_ERR "usbaudio: unit %u: invalid MIXER_UNIT descriptor\n", unitid);
-- return;
-- }
-- usb_audio_mixerunit(state, p1);
-- return;
--
-- case SELECTOR_UNIT:
-- if (p1[0] < 6 || p1[0] < 6+p1[4]) {
-- printk(KERN_ERR "usbaudio: unit %u: invalid SELECTOR_UNIT descriptor\n", unitid);
-- return;
-- }
-- usb_audio_selectorunit(state, p1);
-- return;
--
-- case FEATURE_UNIT: /* See USB Audio Class Spec 4.3.2.5 */
-- if (p1[0] < 7 || p1[0] < 7+p1[5]) {
-- printk(KERN_ERR "usbaudio: unit %u: invalid FEATURE_UNIT descriptor\n", unitid);
-- return;
-- }
-- usb_audio_featureunit(state, p1);
-- return;
--
-- case PROCESSING_UNIT:
-- if (p1[0] < 13 || p1[0] < 13+p1[6] || p1[0] < 13+p1[6]+p1[11+p1[6]]) {
-- printk(KERN_ERR "usbaudio: unit %u: invalid PROCESSING_UNIT descriptor\n", unitid);
-- return;
-- }
-- usb_audio_processingunit(state, p1);
-- return;
--
-- case EXTENSION_UNIT:
-- if (p1[0] < 13 || p1[0] < 13+p1[6] || p1[0] < 13+p1[6]+p1[11+p1[6]]) {
-- printk(KERN_ERR "usbaudio: unit %u: invalid EXTENSION_UNIT descriptor\n", unitid);
-- return;
-- }
-- for (j = i = 0; i < p1[6]; i++) {
-- usb_audio_recurseunit(state, p1[7+i]);
-- if (!i)
-- j = state->termtype;
-- else if (j != state->termtype)
-- j = 0;
-- }
-- state->nrchannels = p1[7+p1[6]];
-- state->chconfig = p1[8+p1[6]] | (p1[9+p1[6]] << 8);
-- state->termtype = j;
-- return;
--
-- default:
-- printk(KERN_ERR "usbaudio: unit %u: unexpected type 0x%02x\n", unitid, p1[2]);
-- return;
-- }
--}
--
--static void usb_audio_constructmixer(struct usb_audio_state *s, unsigned char *buffer, unsigned int buflen, unsigned int ctrlif, unsigned char *oterm)
--{
-- struct usb_mixerdev *ms;
-- struct consmixstate state;
--
-- memset(&state, 0, sizeof(state));
-- state.s = s;
-- state.nrmixch = 0;
-- state.mixchmask = ~0;
-- state.buffer = buffer;
-- state.buflen = buflen;
-- state.ctrlif = ctrlif;
-- set_bit(oterm[3], state.unitbitmap); /* mark terminal ID as visited */
-- printk(KERN_DEBUG "usbaudio: constructing mixer for Terminal %u type 0x%04x\n",
-- oterm[3], oterm[4] | (oterm[5] << 8));
-- usb_audio_recurseunit(&state, oterm[7]);
-- if (!state.nrmixch) {
-- printk(KERN_INFO "usbaudio: no mixer controls found for Terminal %u\n", oterm[3]);
-- return;
-- }
-- if (!(ms = kmalloc(sizeof(struct usb_mixerdev)+state.nrmixch*sizeof(struct mixerchannel), GFP_KERNEL)))
-- return;
-- memset(ms, 0, sizeof(struct usb_mixerdev));
-- memcpy(&ms->ch, &state.mixch, state.nrmixch*sizeof(struct mixerchannel));
-- ms->state = s;
-- ms->iface = ctrlif;
-- ms->numch = state.nrmixch;
-- if ((ms->dev_mixer = register_sound_mixer(&usb_mixer_fops, -1)) < 0) {
-- printk(KERN_ERR "usbaudio: cannot register mixer\n");
-- kfree(ms);
-- return;
-- }
-- printk(KERN_INFO "usbaudio: registered mixer 14,%d\n", ms->dev_mixer);
-- list_add_tail(&ms->list, &s->mixerlist);
--}
--
--/* arbitrary limit, we won't check more interfaces than this */
--#define USB_MAXINTERFACES 32
--
--static struct usb_audio_state *usb_audio_parsecontrol(struct usb_device *dev, unsigned char *buffer, unsigned int buflen, unsigned int ctrlif)
--{
-- struct usb_audio_state *s;
-- struct usb_interface *iface;
-- struct usb_host_interface *alt;
-- unsigned char ifin[USB_MAXINTERFACES], ifout[USB_MAXINTERFACES];
-- unsigned char *p1;
-- unsigned int i, j, k, numifin = 0, numifout = 0;
--
-- if (!(s = kmalloc(sizeof(struct usb_audio_state), GFP_KERNEL)))
-- return NULL;
-- memset(s, 0, sizeof(struct usb_audio_state));
-- INIT_LIST_HEAD(&s->audiolist);
-- INIT_LIST_HEAD(&s->mixerlist);
-- s->usbdev = dev;
-- s->count = 1;
--
-- /* find audiocontrol interface */
-- if (!(p1 = find_csinterface_descriptor(buffer, buflen, NULL, HEADER, ctrlif, -1))) {
-- printk(KERN_ERR "usbaudio: device %d audiocontrol interface %u no HEADER found\n",
-- dev->devnum, ctrlif);
-- goto ret;
-- }
-- if (p1[0] < 8 + p1[7]) {
-- printk(KERN_ERR "usbaudio: device %d audiocontrol interface %u HEADER error\n",
-- dev->devnum, ctrlif);
-- goto ret;
-- }
-- if (!p1[7])
-- printk(KERN_INFO "usbaudio: device %d audiocontrol interface %u has no AudioStreaming and MidiStreaming interfaces\n",
-- dev->devnum, ctrlif);
-- for (i = 0; i < p1[7]; i++) {
-- j = p1[8+i];
-- iface = usb_ifnum_to_if(dev, j);
-- if (!iface) {
-- printk(KERN_ERR "usbaudio: device %d audiocontrol interface %u interface %u does not exist\n",
-- dev->devnum, ctrlif, j);
-- continue;
-- }
-- if (iface->num_altsetting == 1) {
-- printk(KERN_ERR "usbaudio: device %d audiocontrol interface %u has only 1 altsetting.\n", dev->devnum, ctrlif);
-- continue;
-- }
-- alt = usb_altnum_to_altsetting(iface, 0);
-- if (!alt) {
-- printk(KERN_ERR "usbaudio: device %d audiocontrol interface %u interface %u has no altsetting 0\n",
-- dev->devnum, ctrlif, j);
-- continue;
-- }
-- if (alt->desc.bInterfaceClass != USB_CLASS_AUDIO) {
-- printk(KERN_ERR "usbaudio: device %d audiocontrol interface %u interface %u is not an AudioClass interface\n",
-- dev->devnum, ctrlif, j);
-- continue;
-- }
-- if (alt->desc.bInterfaceSubClass == 3) {
-- printk(KERN_INFO "usbaudio: device %d audiocontrol interface %u interface %u MIDIStreaming not supported\n",
-- dev->devnum, ctrlif, j);
-- continue;
-- }
-- if (alt->desc.bInterfaceSubClass != 2) {
-- printk(KERN_ERR "usbaudio: device %d audiocontrol interface %u interface %u invalid AudioClass subtype\n",
-- dev->devnum, ctrlif, j);
-- continue;
-- }
-- if (alt->desc.bNumEndpoints > 0) {
-- /* Check all endpoints; should they all have a bandwidth of 0 ? */
-- for (k = 0; k < alt->desc.bNumEndpoints; k++) {
-- if (le16_to_cpu(alt->endpoint[k].desc.wMaxPacketSize) > 0) {
-- printk(KERN_ERR "usbaudio: device %d audiocontrol interface %u endpoint %d does not have 0 bandwidth at alt[0]\n", dev->devnum, ctrlif, k);
-- break;
-- }
-- }
-- if (k < alt->desc.bNumEndpoints)
-- continue;
-- }
--
-- alt = usb_altnum_to_altsetting(iface, 1);
-- if (!alt) {
-- printk(KERN_ERR "usbaudio: device %d audiocontrol interface %u interface %u has no altsetting 1\n",
-- dev->devnum, ctrlif, j);
-- continue;
-- }
-- if (alt->desc.bNumEndpoints < 1) {
-- printk(KERN_ERR "usbaudio: device %d audiocontrol interface %u interface %u has no endpoint\n",
-- dev->devnum, ctrlif, j);
-- continue;
-- }
-- /* note: this requires the data endpoint to be ep0 and the optional sync
-- ep to be ep1, which seems to be the case */
-- if (alt->endpoint[0].desc.bEndpointAddress & USB_DIR_IN) {
-- if (numifin < USB_MAXINTERFACES) {
-- ifin[numifin++] = j;
-- usb_driver_claim_interface(&usb_audio_driver, iface, (void *)-1);
-- }
-- } else {
-- if (numifout < USB_MAXINTERFACES) {
-- ifout[numifout++] = j;
-- usb_driver_claim_interface(&usb_audio_driver, iface, (void *)-1);
-- }
-- }
-- }
-- printk(KERN_INFO "usbaudio: device %d audiocontrol interface %u has %u input and %u output AudioStreaming interfaces\n",
-- dev->devnum, ctrlif, numifin, numifout);
-- for (i = 0; i < numifin && i < numifout; i++)
-- usb_audio_parsestreaming(s, buffer, buflen, ifin[i], ifout[i]);
-- for (j = i; j < numifin; j++)
-- usb_audio_parsestreaming(s, buffer, buflen, ifin[i], -1);
-- for (j = i; j < numifout; j++)
-- usb_audio_parsestreaming(s, buffer, buflen, -1, ifout[i]);
-- /* now walk through all OUTPUT_TERMINAL descriptors to search for mixers */
-- p1 = find_csinterface_descriptor(buffer, buflen, NULL, OUTPUT_TERMINAL, ctrlif, -1);
-- while (p1) {
-- if (p1[0] >= 9)
-- usb_audio_constructmixer(s, buffer, buflen, ctrlif, p1);
-- p1 = find_csinterface_descriptor(buffer, buflen, p1, OUTPUT_TERMINAL, ctrlif, -1);
-- }
--
--ret:
-- if (list_empty(&s->audiolist) && list_empty(&s->mixerlist)) {
-- kfree(s);
-- return NULL;
-- }
-- /* everything successful */
-- down(&open_sem);
-- list_add_tail(&s->audiodev, &audiodevs);
-- up(&open_sem);
-- printk(KERN_DEBUG "usb_audio_parsecontrol: usb_audio_state at %p\n", s);
-- return s;
--}
--
--/* we only care for the currently active configuration */
--
--static int usb_audio_probe(struct usb_interface *intf,
-- const struct usb_device_id *id)
--{
-- struct usb_device *dev = interface_to_usbdev (intf);
-- struct usb_audio_state *s;
-- unsigned char *buffer;
-- unsigned int buflen;
--
--#if 0
-- printk(KERN_DEBUG "usbaudio: Probing if %i: IC %x, ISC %x\n", ifnum,
-- config->interface[ifnum].altsetting[0].desc.bInterfaceClass,
-- config->interface[ifnum].altsetting[0].desc.bInterfaceSubClass);
--#endif
--
-- /*
-- * audiocontrol interface found
-- * find which configuration number is active
-- */
-- buffer = dev->rawdescriptors[dev->actconfig - dev->config];
-- buflen = le16_to_cpu(dev->actconfig->desc.wTotalLength);
-- s = usb_audio_parsecontrol(dev, buffer, buflen, intf->altsetting->desc.bInterfaceNumber);
-- if (s) {
-- usb_set_intfdata (intf, s);
-- return 0;
-- }
-- return -ENODEV;
--}
--
--
--/* a revoke facility would make things simpler */
--
--static void usb_audio_disconnect(struct usb_interface *intf)
--{
-- struct usb_audio_state *s = usb_get_intfdata (intf);
-- struct usb_audiodev *as;
-- struct usb_mixerdev *ms;
--
-- if (!s)
-- return;
--
-- /* we get called with -1 for every audiostreaming interface registered */
-- if (s == (struct usb_audio_state *)-1) {
-- dprintk((KERN_DEBUG "usbaudio: note, usb_audio_disconnect called with -1\n"));
-- return;
-- }
-- if (!s->usbdev) {
-- dprintk((KERN_DEBUG "usbaudio: error, usb_audio_disconnect already called for %p!\n", s));
-- return;
-- }
-- down(&open_sem);
-- list_del_init(&s->audiodev);
-- s->usbdev = NULL;
-- usb_set_intfdata (intf, NULL);
--
-- /* deregister all audio and mixer devices, so no new processes can open this device */
-- list_for_each_entry(as, &s->audiolist, list) {
-- usbin_disc(as);
-- usbout_disc(as);
-- wake_up(&as->usbin.dma.wait);
-- wake_up(&as->usbout.dma.wait);
-- if (as->dev_audio >= 0) {
-- unregister_sound_dsp(as->dev_audio);
-- printk(KERN_INFO "usbaudio: unregister dsp 14,%d\n", as->dev_audio);
-- }
-- as->dev_audio = -1;
-- }
-- list_for_each_entry(ms, &s->mixerlist, list) {
-- if (ms->dev_mixer >= 0) {
-- unregister_sound_mixer(ms->dev_mixer);
-- printk(KERN_INFO "usbaudio: unregister mixer 14,%d\n", ms->dev_mixer);
-- }
-- ms->dev_mixer = -1;
-- }
-- release(s);
-- wake_up(&open_wait);
--}
--
--static int __init usb_audio_init(void)
--{
-- int result = usb_register(&usb_audio_driver);
-- if (result == 0)
-- info(DRIVER_VERSION ":" DRIVER_DESC);
-- return result;
--}
--
--
--static void __exit usb_audio_cleanup(void)
--{
-- usb_deregister(&usb_audio_driver);
--}
--
--module_init(usb_audio_init);
--module_exit(usb_audio_cleanup);
--
--MODULE_AUTHOR( DRIVER_AUTHOR );
--MODULE_DESCRIPTION( DRIVER_DESC );
--MODULE_LICENSE("GPL");
--
---- gregkh-2.6.orig/drivers/usb/class/audio.h
-+++ /dev/null
-@@ -1,110 +0,0 @@
--#define CS_AUDIO_UNDEFINED 0x20
--#define CS_AUDIO_DEVICE 0x21
--#define CS_AUDIO_CONFIGURATION 0x22
--#define CS_AUDIO_STRING 0x23
--#define CS_AUDIO_INTERFACE 0x24
--#define CS_AUDIO_ENDPOINT 0x25
--
--#define HEADER 0x01
--#define INPUT_TERMINAL 0x02
--#define OUTPUT_TERMINAL 0x03
--#define MIXER_UNIT 0x04
--#define SELECTOR_UNIT 0x05
--#define FEATURE_UNIT 0x06
--#define PROCESSING_UNIT 0x07
--#define EXTENSION_UNIT 0x08
--
--#define AS_GENERAL 0x01
--#define FORMAT_TYPE 0x02
--#define FORMAT_SPECIFIC 0x03
--
--#define EP_GENERAL 0x01
--
--#define MAX_CHAN 9
--#define MAX_FREQ 16
--#define MAX_IFACE 8
--#define MAX_FORMAT 8
--#define MAX_ALT 32 /* Sorry, we need quite a few for the Philips webcams */
--
--struct usb_audio_terminal
--{
-- u8 flags;
-- u8 assoc;
-- u16 type; /* Mic etc */
-- u8 channels;
-- u8 source;
-- u16 chancfg;
--};
--
--struct usb_audio_format
--{
-- u8 type;
-- u8 channels;
-- u8 num_freq;
-- u8 sfz;
-- u8 bits;
-- u16 freq[MAX_FREQ];
--};
--
--struct usb_audio_interface
--{
-- u8 terminal;
-- u8 delay;
-- u16 num_formats;
-- u16 format_type;
-- u8 flags;
-- u8 idleconf; /* Idle config */
--#define AU_IFACE_FOUND 1
-- struct usb_audio_format format[MAX_FORMAT];
--};
--
--struct usb_audio_device
--{
-- struct list_head list;
-- u8 mixer;
-- u8 selector;
-- void *irq_handle;
-- u8 num_channels;
-- u8 num_dsp_iface;
-- u8 channel_map[MAX_CHAN];
-- struct usb_audio_terminal terminal[MAX_CHAN];
-- struct usb_audio_interface interface[MAX_IFACE][MAX_ALT];
--};
--
--
--
--/* Audio Class specific Request Codes */
--
--#define SET_CUR 0x01
--#define GET_CUR 0x81
--#define SET_MIN 0x02
--#define GET_MIN 0x82
--#define SET_MAX 0x03
--#define GET_MAX 0x83
--#define SET_RES 0x04
--#define GET_RES 0x84
--#define SET_MEM 0x05
--#define GET_MEM 0x85
--#define GET_STAT 0xff
--
--/* Terminal Control Selectors */
--
--#define COPY_PROTECT_CONTROL 0x01
--
--/* Feature Unit Control Selectors */
--
--#define MUTE_CONTROL 0x01
--#define VOLUME_CONTROL 0x02
--#define BASS_CONTROL 0x03
--#define MID_CONTROL 0x04
--#define TREBLE_CONTROL 0x05
--#define GRAPHIC_EQUALIZER_CONTROL 0x06
--#define AUTOMATIC_GAIN_CONTROL 0x07
--#define DELAY_CONTROL 0x08
--#define BASS_BOOST_CONTROL 0x09
--#define LOUDNESS_CONTROL 0x0a
--
--/* Endpoint Control Selectors */
--
--#define SAMPLING_FREQ_CONTROL 0x01
--#define PITCH_CONTROL 0x02
---- gregkh-2.6.orig/drivers/usb/class/usb-midi.c
-+++ /dev/null
-@@ -1,2153 +0,0 @@
--/*
-- usb-midi.c -- USB-MIDI driver
--
-- Copyright (C) 2001
-- NAGANO Daisuke <breeze.nagano@nifty.ne.jp>
--
-- 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, 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.
--
-- This driver is based on:
-- - 'Universal Serial Bus Device Class Definition for MIDI Device'
-- - linux/drivers/sound/es1371.c, linux/drivers/usb/audio.c
-- - alsa/lowlevel/pci/cs64xx.c
-- - umidi.c for NetBSD
-- */
--
--/* ------------------------------------------------------------------------- */
--
--
--#include <linux/module.h>
--#include <linux/kernel.h>
--#include <linux/sched.h>
--#include <linux/list.h>
--#include <linux/slab.h>
--#include <linux/usb.h>
--#include <linux/poll.h>
--#include <linux/sound.h>
--#include <linux/init.h>
--#include <asm/semaphore.h>
--
--#include "usb-midi.h"
--
--/* ------------------------------------------------------------------------- */
--
--/* More verbose on syslog */
--#undef MIDI_DEBUG
--
--#define MIDI_IN_BUFSIZ 1024
--
--#define HAVE_SUPPORT_USB_MIDI_CLASS
--
--#undef HAVE_SUPPORT_ALSA
--
--/* ------------------------------------------------------------------------- */
--
--static int singlebyte = 0;
--module_param(singlebyte, int, 0);
--MODULE_PARM_DESC(singlebyte,"Enable sending MIDI messages with single message packet");
--
--static int maxdevices = 4;
--module_param(maxdevices, int, 0);
--MODULE_PARM_DESC(maxdevices,"Max number of allocatable MIDI device");
--
--static int uvendor = -1;
--module_param(uvendor, int, 0);
--MODULE_PARM_DESC(uvendor, "The USB Vendor ID of a semi-compliant interface");
--
--static int uproduct = -1;
--module_param(uproduct, int, 0);
--MODULE_PARM_DESC(uproduct, "The USB Product ID of a semi-compliant interface");
--
--static int uinterface = -1;
--module_param(uinterface, int, 0);
--MODULE_PARM_DESC(uinterface, "The Interface number of a semi-compliant interface");
--
--static int ualt = -1;
--module_param(ualt, int, 0);
--MODULE_PARM_DESC(ualt, "The optional alternative setting of a semi-compliant interface");
--
--static int umin = -1;
--module_param(umin, int, 0);
--MODULE_PARM_DESC(umin, "The input endpoint of a semi-compliant interface");
--
--static int umout = -1;
--module_param(umout, int, 0);
--MODULE_PARM_DESC(umout, "The output endpoint of a semi-compliant interface");
--
--static int ucable = -1;
--module_param(ucable, int, 0);
--MODULE_PARM_DESC(ucable, "The cable number used for a semi-compliant interface");
--
--/** Note -- the usb_string() returns only Latin-1 characters.
-- * (unicode chars <= 255). To support Japanese, a unicode16LE-to-EUC or
-- * unicode16LE-to-JIS routine is needed to wrap around usb_get_string().
-- **/
--static unsigned short ulangid = 0x0409; /** 0x0411 for Japanese **/
--module_param(ulangid, ushort, 0);
--MODULE_PARM_DESC(ulangid, "The optional preferred USB Language ID for all devices");
--
--MODULE_AUTHOR("NAGANO Daisuke <breeze.nagano@nifty.ne.jp>");
--MODULE_DESCRIPTION("USB-MIDI driver");
--MODULE_LICENSE("GPL");
--
--/* ------------------------------------------------------------------------- */
--
--/** MIDIStreaming Class-Specific Interface Descriptor Subtypes **/
--
--#define MS_DESCRIPTOR_UNDEFINED 0
--#define MS_HEADER 1
--#define MIDI_IN_JACK 2
--#define MIDI_OUT_JACK 3
--/* Spec reads: ELEMENT */
--#define ELEMENT_DESCRIPTOR 4
--
--#define MS_HEADER_LENGTH 7
--
--/** MIDIStreaming Class-Specific Endpoint Descriptor Subtypes **/
--
--#define DESCRIPTOR_UNDEFINED 0
--/* Spec reads: MS_GENERAL */
--#define MS_GENERAL_ENDPOINT 1
--
--/** MIDIStreaming MIDI IN and OUT Jack Types **/
--
--#define JACK_TYPE_UNDEFINED 0
--/* Spec reads: EMBEDDED */
--#define EMBEDDED_JACK 1
--/* Spec reads: EXTERNAL */
--#define EXTERNAL_JACK 2
--
--
--/* structure summary
--
-- usb_midi_state usb_device
-- | |
-- *| *| per ep
-- in_ep out_ep
-- | |
-- *| *| per cable
-- min mout
-- | | (cable to device pairing magic)
-- | |
-- usb_midi_dev dev_id (major,minor) == file->private_data
--
--*/
--
--/* usb_midi_state: corresponds to a USB-MIDI module */
--struct usb_midi_state {
-- struct list_head mididev;
--
-- struct usb_device *usbdev;
--
-- struct list_head midiDevList;
-- struct list_head inEndpointList;
-- struct list_head outEndpointList;
--
-- spinlock_t lock;
--
-- unsigned int count; /* usage counter */
--};
--
--/* midi_out_endpoint: corresponds to an output endpoint */
--struct midi_out_endpoint {
-- struct list_head list;
--
-- struct usb_device *usbdev;
-- int endpoint;
-- spinlock_t lock;
-- wait_queue_head_t wait;
--
-- unsigned char *buf;
-- int bufWrPtr;
-- int bufSize;
--
-- struct urb *urb;
--};
--
--/* midi_in_endpoint: corresponds to an input endpoint */
--struct midi_in_endpoint {
-- struct list_head list;
--
-- struct usb_device *usbdev;
-- int endpoint;
-- spinlock_t lock;
-- wait_queue_head_t wait;
--
-- struct usb_mididev *cables[16]; // cables open for read
-- int readers; // number of cables open for read
--
-- struct urb *urb;
-- unsigned char *recvBuf;
-- int recvBufSize;
-- int urbSubmitted; //FIXME: == readers > 0
--};
--
--/* usb_mididev: corresponds to a logical device */
--struct usb_mididev {
-- struct list_head list;
--
-- struct usb_midi_state *midi;
-- int dev_midi;
-- mode_t open_mode;
--
-- struct {
-- struct midi_in_endpoint *ep;
-- int cableId;
--
--// as we are pushing data from usb_bulk_read to usb_midi_read,
--// we need a larger, cyclic buffer here.
-- unsigned char buf[MIDI_IN_BUFSIZ];
-- int bufRdPtr;
-- int bufWrPtr;
-- int bufRemains;
-- } min;
--
-- struct {
-- struct midi_out_endpoint *ep;
-- int cableId;
--
-- unsigned char buf[3];
-- int bufPtr;
-- int bufRemains;
--
-- int isInExclusive;
-- unsigned char lastEvent;
-- } mout;
--
-- int singlebyte;
--};
--
--/** Map the high nybble of MIDI voice messages to number of Message bytes.
-- * High nyble ranges from 0x8 to 0xe
-- */
--
--static int remains_80e0[] = {
-- 3, /** 0x8X Note Off **/
-- 3, /** 0x9X Note On **/
-- 3, /** 0xAX Poly-key pressure **/
-- 3, /** 0xBX Control Change **/
-- 2, /** 0xCX Program Change **/
-- 2, /** 0xDX Channel pressure **/
-- 3 /** 0xEX PitchBend Change **/
--};
--
--/** Map the messages to a number of Message bytes.
-- *
-- **/
--static int remains_f0f6[] = {
-- 0, /** 0xF0 **/
-- 2, /** 0XF1 **/
-- 3, /** 0XF2 **/
-- 2, /** 0XF3 **/
-- 2, /** 0XF4 (Undefined by MIDI Spec, and subject to change) **/
-- 2, /** 0XF5 (Undefined by MIDI Spec, and subject to change) **/
-- 1 /** 0XF6 **/
--};
--
--/** Map the messages to a CIN (Code Index Number).
-- *
-- **/
--static int cin_f0ff[] = {
-- 4, /** 0xF0 System Exclusive Message Start (special cases may be 6 or 7) */
-- 2, /** 0xF1 **/
-- 3, /** 0xF2 **/
-- 2, /** 0xF3 **/
-- 2, /** 0xF4 **/
-- 2, /** 0xF5 **/
-- 5, /** 0xF6 **/
-- 5, /** 0xF7 End of System Exclusive Message (May be 6 or 7) **/
-- 5, /** 0xF8 **/
-- 5, /** 0xF9 **/
-- 5, /** 0xFA **/
-- 5, /** 0xFB **/
-- 5, /** 0xFC **/
-- 5, /** 0xFD **/
-- 5, /** 0xFE **/
-- 5 /** 0xFF **/
--};
--
--/** Map MIDIStreaming Event packet Code Index Number (low nybble of byte 0)
-- * to the number of bytes of valid MIDI data.
-- *
-- * CIN of 0 and 1 are NOT USED in MIDIStreaming 1.0.
-- *
-- **/
--static int cin_to_len[] = {
-- 0, 0, 2, 3,
-- 3, 1, 2, 3,
-- 3, 3, 3, 3,
-- 2, 2, 3, 1
--};
--
--
--/* ------------------------------------------------------------------------- */
--
--static struct list_head mididevs = LIST_HEAD_INIT(mididevs);
--
--static DECLARE_MUTEX(open_sem);
--static DECLARE_WAIT_QUEUE_HEAD(open_wait);
--
--
--/* ------------------------------------------------------------------------- */
--
--static void usb_write_callback(struct urb *urb, struct pt_regs *regs)
--{
-- struct midi_out_endpoint *ep = (struct midi_out_endpoint *)urb->context;
--
-- if ( waitqueue_active( &ep->wait ) )
-- wake_up_interruptible( &ep->wait );
--}
--
--
--static int usb_write( struct midi_out_endpoint *ep, unsigned char *buf, int len )
--{
-- struct usb_device *d;
-- int pipe;
-- int ret = 0;
-- int status;
-- int maxretry = 50;
--
-- DECLARE_WAITQUEUE(wait,current);
-- init_waitqueue_head(&ep->wait);
--
-- d = ep->usbdev;
-- pipe = usb_sndbulkpipe(d, ep->endpoint);
-- usb_fill_bulk_urb( ep->urb, d, pipe, (unsigned char*)buf, len,
-- usb_write_callback, ep );
--
-- status = usb_submit_urb(ep->urb, GFP_KERNEL);
--
-- if (status) {
-- printk(KERN_ERR "usbmidi: Cannot submit urb (%d)\n",status);
-- ret = -EIO;
-- goto error;
-- }
--
-- add_wait_queue( &ep->wait, &wait );
-- set_current_state( TASK_INTERRUPTIBLE );
--
-- while( ep->urb->status == -EINPROGRESS ) {
-- if ( maxretry-- < 0 ) {
-- printk(KERN_ERR "usbmidi: usb_bulk_msg timed out\n");
-- ret = -ETIME;
-- break;
-- }
-- interruptible_sleep_on_timeout( &ep->wait, 10 );
-- }
-- set_current_state( TASK_RUNNING );
-- remove_wait_queue( &ep->wait, &wait );
--
--error:
-- return ret;
--}
--
--
--/** Copy data from URB to In endpoint buf.
-- * Discard if CIN == 0 or CIN = 1.
-- *
-- *
-- **/
--
--static void usb_bulk_read(struct urb *urb, struct pt_regs *regs)
--{
-- struct midi_in_endpoint *ep = (struct midi_in_endpoint *)(urb->context);
-- unsigned char *data = urb->transfer_buffer;
-- int i, j, wake;
--
-- if ( !ep->urbSubmitted ) {
-- return;
-- }
--
-- if ( (urb->status == 0) && (urb->actual_length > 0) ) {
-- wake = 0;
-- spin_lock( &ep->lock );
--
-- for(j = 0; j < urb->actual_length; j += 4) {
-- int cin = (data[j]>>0)&0xf;
-- int cab = (data[j]>>4)&0xf;
-- struct usb_mididev *cable = ep->cables[cab];
-- if ( cable ) {
-- int len = cin_to_len[cin]; /** length of MIDI data **/
-- for (i = 0; i < len; i++) {
-- cable->min.buf[cable->min.bufWrPtr] = data[1+i+j];
-- cable->min.bufWrPtr = (cable->min.bufWrPtr+1)%MIDI_IN_BUFSIZ;
-- if (cable->min.bufRemains < MIDI_IN_BUFSIZ)
-- cable->min.bufRemains += 1;
-- else /** need to drop data **/
-- cable->min.bufRdPtr += (cable->min.bufRdPtr+1)%MIDI_IN_BUFSIZ;
-- wake = 1;
-- }
-- }
-- }
--
-- spin_unlock ( &ep->lock );
-- if ( wake ) {
-- wake_up( &ep->wait );
-- }
-- }
--
-- /* urb->dev must be reinitialized on 2.4.x kernels */
-- urb->dev = ep->usbdev;
--
-- urb->actual_length = 0;
-- usb_submit_urb(urb, GFP_ATOMIC);
--}
--
--
--
--/* ------------------------------------------------------------------------- */
--
--/* This routine must be called with spin_lock */
--
--/** Wrapper around usb_write().
-- * This routine must be called with spin_lock held on ep.
-- * Called by midiWrite(), putOneMidiEvent(), and usb_midi_write();
-- **/
--static int flush_midi_buffer( struct midi_out_endpoint *ep )
--{
-- int ret=0;
--
-- if ( ep->bufWrPtr > 0 ) {
-- ret = usb_write( ep, ep->buf, ep->bufWrPtr );
-- ep->bufWrPtr = 0;
-- }
--
-- return ret;
--}
--
--
--/* ------------------------------------------------------------------------- */
--
--
--/** Given a MIDI Event, determine size of data to be attached to
-- * USB-MIDI packet.
-- * Returns 1, 2 or 3.
-- * Called by midiWrite();
-- * Uses remains_80e0 and remains_f0f6;
-- **/
--static int get_remains(int event)
--{
-- int ret;
--
-- if ( event < 0x80 ) {
-- ret = 1;
-- } else if ( event < 0xf0 ) {
-- ret = remains_80e0[((event-0x80)>>4)&0x0f];
-- } else if ( event < 0xf7 ) {
-- ret = remains_f0f6[event-0xf0];
-- } else {
-- ret = 1;
-- }
--
-- return ret;
--}
--
--/** Given the output MIDI data in the output buffer, computes a reasonable
-- * CIN.
-- * Called by putOneMidiEvent().
-- **/
--static int get_CIN( struct usb_mididev *m )
--{
-- int cin;
--
-- if ( m->mout.buf[0] == 0xf7 ) {
-- cin = 5;
-- }
-- else if ( m->mout.buf[1] == 0xf7 ) {
-- cin = 6;
-- }
-- else if ( m->mout.buf[2] == 0xf7 ) {
-- cin = 7;
-- }
-- else {
-- if ( m->mout.isInExclusive == 1 ) {
-- cin = 4;
-- } else if ( m->mout.buf[0] < 0x80 ) {
-- /** One byte that we know nothing about. **/
-- cin = 0xF;
-- } else if ( m->mout.buf[0] < 0xf0 ) {
-- /** MIDI Voice messages 0x8X to 0xEX map to cin 0x8 to 0xE. **/
-- cin = (m->mout.buf[0]>>4)&0x0f;
-- }
-- else {
-- /** Special lookup table exists for real-time events. **/
-- cin = cin_f0ff[m->mout.buf[0]-0xf0];
-- }
-- }
--
-- return cin;
--}
--
--
--/* ------------------------------------------------------------------------- */
--
--
--
--/** Move data to USB endpoint buffer.
-- *
-- **/
--static int put_one_midi_event(struct usb_mididev *m)
--{
-- int cin;
-- unsigned long flags;
-- struct midi_out_endpoint *ep = m->mout.ep;
-- int ret=0;
--
-- cin = get_CIN( m );
-- if ( cin > 0x0f || cin < 0 ) {
-- return -EINVAL;
-- }
--
-- spin_lock_irqsave( &ep->lock, flags );
-- ep->buf[ep->bufWrPtr++] = (m->mout.cableId<<4) | cin;
-- ep->buf[ep->bufWrPtr++] = m->mout.buf[0];
-- ep->buf[ep->bufWrPtr++] = m->mout.buf[1];
-- ep->buf[ep->bufWrPtr++] = m->mout.buf[2];
-- if ( ep->bufWrPtr >= ep->bufSize ) {
-- ret = flush_midi_buffer( ep );
-- }
-- spin_unlock_irqrestore( &ep->lock, flags);
--
-- m->mout.buf[0] = m->mout.buf[1] = m->mout.buf[2] = 0;
-- m->mout.bufPtr = 0;
--
-- return ret;
--}
--
--/** Write the MIDI message v on the midi device.
-- * Called by usb_midi_write();
-- * Responsible for packaging a MIDI data stream into USB-MIDI packets.
-- **/
--
--static int midi_write( struct usb_mididev *m, int v )
--{
-- unsigned long flags;
-- struct midi_out_endpoint *ep = m->mout.ep;
-- int ret=0;
-- unsigned char c = (unsigned char)v;
-- unsigned char sysrt_buf[4];
--
-- if ( m->singlebyte != 0 ) {
-- /** Simple code to handle the single-byte USB-MIDI protocol. */
-- spin_lock_irqsave( &ep->lock, flags );
-- if ( ep->bufWrPtr+4 > ep->bufSize ) {
-- ret = flush_midi_buffer( ep );
-- if ( !ret ) {
-- spin_unlock_irqrestore( &ep->lock, flags );
-- return ret;
-- }
-- }
-- ep->buf[ep->bufWrPtr++] = (m->mout.cableId<<4) | 0x0f; /* single byte */
-- ep->buf[ep->bufWrPtr++] = c;
-- ep->buf[ep->bufWrPtr++] = 0;
-- ep->buf[ep->bufWrPtr++] = 0;
-- if ( ep->bufWrPtr >= ep->bufSize ) {
-- ret = flush_midi_buffer( ep );
-- }
-- spin_unlock_irqrestore( &ep->lock, flags );
--
-- return ret;
-- }
-- /** Normal USB-MIDI protocol begins here. */
--
-- if ( c > 0xf7 ) { /* system: Realtime messages */
-- /** Realtime messages are written IMMEDIATELY. */
-- sysrt_buf[0] = (m->mout.cableId<<4) | 0x0f;
-- sysrt_buf[1] = c;
-- sysrt_buf[2] = 0;
-- sysrt_buf[3] = 0;
-- spin_lock_irqsave( &ep->lock, flags );
-- ret = usb_write( ep, sysrt_buf, 4 );
-- spin_unlock_irqrestore( &ep->lock, flags );
-- /* m->mout.lastEvent = 0; */
--
-- return ret;
-- }
--
-- if ( c >= 0x80 ) {
-- if ( c < 0xf0 ) {
-- m->mout.lastEvent = c;
-- m->mout.isInExclusive = 0;
-- m->mout.bufRemains = get_remains(c);
-- } else if ( c == 0xf0 ) {
-- /* m->mout.lastEvent = 0; */
-- m->mout.isInExclusive = 1;
-- m->mout.bufRemains = get_remains(c);
-- } else if ( c == 0xf7 && m->mout.isInExclusive == 1 ) {
-- /* m->mout.lastEvent = 0; */
-- m->mout.isInExclusive = 0;
-- m->mout.bufRemains = 1;
-- } else if ( c > 0xf0 ) {
-- /* m->mout.lastEvent = 0; */
-- m->mout.isInExclusive = 0;
-- m->mout.bufRemains = get_remains(c);
-- }
--
-- } else if ( m->mout.bufRemains == 0 && m->mout.isInExclusive == 0 ) {
-- if ( m->mout.lastEvent == 0 ) {
-- return 0; /* discard, waiting for the first event */
-- }
-- /** track status **/
-- m->mout.buf[0] = m->mout.lastEvent;
-- m->mout.bufPtr = 1;
-- m->mout.bufRemains = get_remains(m->mout.lastEvent)-1;
-- }
--
-- m->mout.buf[m->mout.bufPtr++] = c;
-- m->mout.bufRemains--;
-- if ( m->mout.bufRemains == 0 || m->mout.bufPtr >= 3) {
-- ret = put_one_midi_event(m);
-- }
--
-- return ret;
--}
--
--
--/* ------------------------------------------------------------------------- */
--
--/** Basic operation on /dev/midiXX as registered through struct file_operations.
-- *
-- * Basic contract: Used to change the current read/write position in a file.
-- * On success, the non-negative position is reported.
-- * On failure, the negative of an error code is reported.
-- *
-- * Because a MIDIStream is not a file, all seek operations are doomed to fail.
-- *
-- **/
--static loff_t usb_midi_llseek(struct file *file, loff_t offset, int origin)
--{
-- /** Tell user you cannot seek on a PIPE-like device. **/
-- return -ESPIPE;
--}
--
--
--/** Basic operation on /dev/midiXX as registered through struct file_operations.
-- *
-- * Basic contract: Block until count bytes have been read or an error occurs.
-- *
-- **/
--
--static ssize_t usb_midi_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
--{
-- struct usb_mididev *m = (struct usb_mididev *)file->private_data;
-- struct midi_in_endpoint *ep = m->min.ep;
-- ssize_t ret;
-- DECLARE_WAITQUEUE(wait, current);
--
-- if ( !access_ok(VERIFY_READ, buffer, count) ) {
-- return -EFAULT;
-- }
-- if ( count == 0 ) {
-- return 0;
-- }
--
-- add_wait_queue( &ep->wait, &wait );
-- ret = 0;
-- while( count > 0 ) {
-- int cnt;
-- int d = (int)count;
--
-- cnt = m->min.bufRemains;
-- if ( cnt > d ) {
-- cnt = d;
-- }
--
-- if ( cnt <= 0 ) {
-- if ( file->f_flags & O_NONBLOCK ) {
-- if (!ret)
-- ret = -EAGAIN;
-- break;
-- }
-- __set_current_state(TASK_INTERRUPTIBLE);
-- schedule();
-- if (signal_pending(current)) {
-- if(!ret)
-- ret=-ERESTARTSYS;
-- break;
-- }
-- continue;
-- }
--
-- {
-- int i;
-- unsigned long flags; /* used to synchronize access to the endpoint */
-- spin_lock_irqsave( &ep->lock, flags );
-- for (i = 0; i < cnt; i++) {
-- if ( copy_to_user( buffer+i, m->min.buf+m->min.bufRdPtr, 1 ) ) {
-- if ( !ret )
-- ret = -EFAULT;
-- break;
-- }
-- m->min.bufRdPtr = (m->min.bufRdPtr+1)%MIDI_IN_BUFSIZ;
-- m->min.bufRemains -= 1;
-- }
-- spin_unlock_irqrestore( &ep->lock, flags );
-- }
--
-- count-=cnt;
-- buffer+=cnt;
-- ret+=cnt;
--
-- break;
-- }
--
-- remove_wait_queue( &ep->wait, &wait );
-- set_current_state(TASK_RUNNING);
--
-- return ret;
--}
--
--
--/** Basic operation on /dev/midiXX as registered through struct file_operations.
-- *
-- * Basic Contract: Take MIDI data byte-by-byte and pass it to
-- * writeMidi() which packages MIDI data into USB-MIDI stream.
-- * Then flushMidiData() is called to ensure all bytes have been written
-- * in a timely fashion.
-- *
-- **/
--
--static ssize_t usb_midi_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
--{
-- struct usb_mididev *m = (struct usb_mididev *)file->private_data;
-- ssize_t ret;
-- unsigned long int flags;
--
-- if ( !access_ok(VERIFY_READ, buffer, count) ) {
-- return -EFAULT;
-- }
-- if ( count == 0 ) {
-- return 0;
-- }
--
-- ret = 0;
-- while( count > 0 ) {
-- unsigned char c;
--
-- if (copy_from_user((unsigned char *)&c, buffer, 1)) {
-- if ( ret == 0 )
-- ret = -EFAULT;
-- break;
-- }
-- if( midi_write(m, (int)c) ) {
-- if ( ret == 0 )
-- ret = -EFAULT;
-- break;
-- }
-- count--;
-- buffer++;
-- ret++;
-- }
--
-- spin_lock_irqsave( &m->mout.ep->lock, flags );
-- if ( flush_midi_buffer(m->mout.ep) < 0 ) {
-- ret = -EFAULT;
-- }
-- spin_unlock_irqrestore( &m->mout.ep->lock, flags );
--
-- return ret;
--}
--
--/** Basic operation on /dev/midiXX as registered through struct file_operations.
-- *
-- * Basic contract: Wait (spin) until ready to read or write on the file.
-- *
-- **/
--static unsigned int usb_midi_poll(struct file *file, struct poll_table_struct *wait)
--{
-- struct usb_mididev *m = (struct usb_mididev *)file->private_data;
-- struct midi_in_endpoint *iep = m->min.ep;
-- struct midi_out_endpoint *oep = m->mout.ep;
-- unsigned long flags;
-- unsigned int mask = 0;
--
-- if ( file->f_mode & FMODE_READ ) {
-- poll_wait( file, &iep->wait, wait );
-- spin_lock_irqsave( &iep->lock, flags );
-- if ( m->min.bufRemains > 0 )
-- mask |= POLLIN | POLLRDNORM;
-- spin_unlock_irqrestore( &iep->lock, flags );
-- }
--
-- if ( file->f_mode & FMODE_WRITE ) {
-- poll_wait( file, &oep->wait, wait );
-- spin_lock_irqsave( &oep->lock, flags );
-- if ( oep->bufWrPtr < oep->bufSize )
-- mask |= POLLOUT | POLLWRNORM;
-- spin_unlock_irqrestore( &oep->lock, flags );
-- }
--
-- return mask;
--}
--
--
--/** Basic operation on /dev/midiXX as registered through struct file_operations.
-- *
-- * Basic contract: This is always the first operation performed on the
-- * device node. If no method is defined, the open succeeds without any
-- * notification given to the module.
-- *
-- **/
--
--static int usb_midi_open(struct inode *inode, struct file *file)
--{
-- int minor = iminor(inode);
-- DECLARE_WAITQUEUE(wait, current);
-- struct usb_midi_state *s;
-- struct usb_mididev *m;
-- unsigned long flags;
-- int succeed = 0;
--
--#if 0
-- printk(KERN_INFO "usb-midi: Open minor= %d.\n", minor);
--#endif
--
-- for(;;) {
-- down(&open_sem);
-- list_for_each_entry(s, &mididevs, mididev) {
-- list_for_each_entry(m, &s->midiDevList, list) {
-- if ( !((m->dev_midi ^ minor) & ~0xf) )
-- goto device_found;
-- }
-- }
-- up(&open_sem);
-- return -ENODEV;
--
-- device_found:
-- if ( !s->usbdev ) {
-- up(&open_sem);
-- return -EIO;
-- }
-- if ( !(m->open_mode & file->f_mode) ) {
-- break;
-- }
-- if ( file->f_flags & O_NONBLOCK ) {
-- up(&open_sem);
-- return -EBUSY;
-- }
-- __set_current_state(TASK_INTERRUPTIBLE);
-- add_wait_queue( &open_wait, &wait );
-- up(&open_sem);
-- schedule();
-- remove_wait_queue( &open_wait, &wait );
-- if ( signal_pending(current) ) {
-- return -ERESTARTSYS;
-- }
-- }
--
-- file->private_data = m;
-- spin_lock_irqsave( &s->lock, flags );
--
-- if ( !(m->open_mode & (FMODE_READ | FMODE_WRITE)) ) {
-- //FIXME: intented semantics unclear here
-- m->min.bufRdPtr = 0;
-- m->min.bufWrPtr = 0;
-- m->min.bufRemains = 0;
-- spin_lock_init(&m->min.ep->lock);
--
-- m->mout.bufPtr = 0;
-- m->mout.bufRemains = 0;
-- m->mout.isInExclusive = 0;
-- m->mout.lastEvent = 0;
-- spin_lock_init(&m->mout.ep->lock);
-- }
--
-- if ( (file->f_mode & FMODE_READ) && m->min.ep != NULL ) {
-- unsigned long int flagsep;
-- spin_lock_irqsave( &m->min.ep->lock, flagsep );
-- m->min.ep->cables[m->min.cableId] = m;
-- m->min.ep->readers += 1;
-- m->min.bufRdPtr = 0;
-- m->min.bufWrPtr = 0;
-- m->min.bufRemains = 0;
-- spin_unlock_irqrestore( &m->min.ep->lock, flagsep );
--
-- if ( !(m->min.ep->urbSubmitted)) {
--
-- /* urb->dev must be reinitialized on 2.4.x kernels */
-- m->min.ep->urb->dev = m->min.ep->usbdev;
--
-- if ( usb_submit_urb(m->min.ep->urb, GFP_ATOMIC) ) {
-- printk(KERN_ERR "usbmidi: Cannot submit urb for MIDI-IN\n");
-- }
-- m->min.ep->urbSubmitted = 1;
-- }
-- m->open_mode |= FMODE_READ;
-- succeed = 1;
-- }
--
-- if ( (file->f_mode & FMODE_WRITE) && m->mout.ep != NULL ) {
-- m->mout.bufPtr = 0;
-- m->mout.bufRemains = 0;
-- m->mout.isInExclusive = 0;
-- m->mout.lastEvent = 0;
-- m->open_mode |= FMODE_WRITE;
-- succeed = 1;
-- }
--
-- spin_unlock_irqrestore( &s->lock, flags );
--
-- s->count++;
-- up(&open_sem);
--
-- /** Changed to prevent extra increments to USE_COUNT. **/
-- if (!succeed) {
-- return -EBUSY;
-- }
--
--#if 0
-- printk(KERN_INFO "usb-midi: Open Succeeded. minor= %d.\n", minor);
--#endif
--
-- return nonseekable_open(inode, file); /** Success. **/
--}
--
--
--/** Basic operation on /dev/midiXX as registered through struct file_operations.
-- *
-- * Basic contract: Close an opened file and deallocate anything we allocated.
-- * Like open(), this can be missing. If open set file->private_data,
-- * release() must clear it.
-- *
-- **/
--
--static int usb_midi_release(struct inode *inode, struct file *file)
--{
-- struct usb_mididev *m = (struct usb_mididev *)file->private_data;
-- struct usb_midi_state *s = (struct usb_midi_state *)m->midi;
--
--#if 0
-- printk(KERN_INFO "usb-midi: Close.\n");
--#endif
--
-- down(&open_sem);
--
-- if ( m->open_mode & FMODE_WRITE ) {
-- m->open_mode &= ~FMODE_WRITE;
-- usb_kill_urb( m->mout.ep->urb );
-- }
--
-- if ( m->open_mode & FMODE_READ ) {
-- unsigned long int flagsep;
-- spin_lock_irqsave( &m->min.ep->lock, flagsep );
-- m->min.ep->cables[m->min.cableId] = NULL; // discard cable
-- m->min.ep->readers -= 1;
-- m->open_mode &= ~FMODE_READ;
-- if ( m->min.ep->readers == 0 &&
-- m->min.ep->urbSubmitted ) {
-- m->min.ep->urbSubmitted = 0;
-- usb_kill_urb(m->min.ep->urb);
-- }
-- spin_unlock_irqrestore( &m->min.ep->lock, flagsep );
-- }
--
-- s->count--;
--
-- up(&open_sem);
-- wake_up(&open_wait);
--
-- file->private_data = NULL;
-- return 0;
--}
--
--static struct file_operations usb_midi_fops = {
-- .owner = THIS_MODULE,
-- .llseek = usb_midi_llseek,
-- .read = usb_midi_read,
-- .write = usb_midi_write,
-- .poll = usb_midi_poll,
-- .open = usb_midi_open,
-- .release = usb_midi_release,
--};
--
--/* ------------------------------------------------------------------------- */
--
--/** Returns filled midi_in_endpoint structure or null on failure.
-- *
-- * Parameters:
-- * d - a usb_device
-- * endPoint - An usb endpoint in the range 0 to 15.
-- * Called by allocUsbMidiDev();
-- *
-- **/
--
--static struct midi_in_endpoint *alloc_midi_in_endpoint( struct usb_device *d, int endPoint )
--{
-- struct midi_in_endpoint *ep;
-- int bufSize;
-- int pipe;
--
-- endPoint &= 0x0f; /* Silently force endPoint to lie in range 0 to 15. */
--
-- pipe = usb_rcvbulkpipe( d, endPoint );
-- bufSize = usb_maxpacket( d, pipe, 0 );
-- /* usb_pipein() = ! usb_pipeout() = true for an in Endpoint */
--
-- ep = (struct midi_in_endpoint *)kmalloc(sizeof(struct midi_in_endpoint), GFP_KERNEL);
-- if ( !ep ) {
-- printk(KERN_ERR "usbmidi: no memory for midi in-endpoint\n");
-- return NULL;
-- }
-- memset( ep, 0, sizeof(struct midi_in_endpoint) );
--// this sets cables[] and readers to 0, too.
--// for (i=0; i<16; i++) ep->cables[i] = 0; // discard cable
--// ep->readers = 0;
--
-- ep->endpoint = endPoint;
--
-- ep->recvBuf = (unsigned char *)kmalloc(sizeof(unsigned char)*(bufSize), GFP_KERNEL);
-- if ( !ep->recvBuf ) {
-- printk(KERN_ERR "usbmidi: no memory for midi in-endpoint buffer\n");
-- kfree(ep);
-- return NULL;
-- }
--
-- ep->urb = usb_alloc_urb(0, GFP_KERNEL); /* no ISO */
-- if ( !ep->urb ) {
-- printk(KERN_ERR "usbmidi: no memory for midi in-endpoint urb\n");
-- kfree(ep->recvBuf);
-- kfree(ep);
-- return NULL;
-- }
-- usb_fill_bulk_urb( ep->urb, d,
-- usb_rcvbulkpipe(d, endPoint),
-- (unsigned char *)ep->recvBuf, bufSize,
-- usb_bulk_read, ep );
--
-- /* ep->bufRdPtr = 0; */
-- /* ep->bufWrPtr = 0; */
-- /* ep->bufRemains = 0; */
-- /* ep->urbSubmitted = 0; */
-- ep->recvBufSize = bufSize;
--
-- init_waitqueue_head(&ep->wait);
--
-- return ep;
--}
--
--static int remove_midi_in_endpoint( struct midi_in_endpoint *min )
--{
-- usb_kill_urb( min->urb );
-- usb_free_urb( min->urb );
-- kfree( min->recvBuf );
-- kfree( min );
--
-- return 0;
--}
--
--/** Returns filled midi_out_endpoint structure or null on failure.
-- *
-- * Parameters:
-- * d - a usb_device
-- * endPoint - An usb endpoint in the range 0 to 15.
-- * Called by allocUsbMidiDev();
-- *
-- **/
--static struct midi_out_endpoint *alloc_midi_out_endpoint( struct usb_device *d, int endPoint )
--{
-- struct midi_out_endpoint *ep = NULL;
-- int pipe;
-- int bufSize;
--
-- endPoint &= 0x0f;
-- pipe = usb_sndbulkpipe( d, endPoint );
-- bufSize = usb_maxpacket( d, pipe, 1 );
--
-- ep = (struct midi_out_endpoint *)kmalloc(sizeof(struct midi_out_endpoint), GFP_KERNEL);
-- if ( !ep ) {
-- printk(KERN_ERR "usbmidi: no memory for midi out-endpoint\n");
-- return NULL;
-- }
-- memset( ep, 0, sizeof(struct midi_out_endpoint) );
--
-- ep->endpoint = endPoint;
-- ep->buf = (unsigned char *)kmalloc(sizeof(unsigned char)*bufSize, GFP_KERNEL);
-- if ( !ep->buf ) {
-- printk(KERN_ERR "usbmidi: no memory for midi out-endpoint buffer\n");
-- kfree(ep);
-- return NULL;
-- }
--
-- ep->urb = usb_alloc_urb(0, GFP_KERNEL); /* no ISO */
-- if ( !ep->urb ) {
-- printk(KERN_ERR "usbmidi: no memory for midi out-endpoint urb\n");
-- kfree(ep->buf);
-- kfree(ep);
-- return NULL;
-- }
--
-- ep->bufSize = bufSize;
-- /* ep->bufWrPtr = 0; */
--
-- init_waitqueue_head(&ep->wait);
--
-- return ep;
--}
--
--
--static int remove_midi_out_endpoint( struct midi_out_endpoint *mout )
--{
-- usb_kill_urb( mout->urb );
-- usb_free_urb( mout->urb );
-- kfree( mout->buf );
-- kfree( mout );
--
-- return 0;
--}
--
--
--/** Returns a filled usb_mididev structure, registered as a Linux MIDI device.
-- *
-- * Returns null if memory is not available or the device cannot be registered.
-- * Called by allocUsbMidiDev();
-- *
-- **/
--static struct usb_mididev *allocMidiDev(
-- struct usb_midi_state *s,
-- struct midi_in_endpoint *min,
-- struct midi_out_endpoint *mout,
-- int inCableId,
-- int outCableId )
--{
-- struct usb_mididev *m;
--
-- m = (struct usb_mididev *)kmalloc(sizeof(struct usb_mididev), GFP_KERNEL);
-- if (!m) {
-- printk(KERN_ERR "usbmidi: no memory for midi device\n");
-- return NULL;
-- }
--
-- memset(m, 0, sizeof(struct usb_mididev));
--
-- if ((m->dev_midi = register_sound_midi(&usb_midi_fops, -1)) < 0) {
-- printk(KERN_ERR "usbmidi: cannot register midi device\n");
-- kfree(m);
-- return NULL;
-- }
--
-- m->midi = s;
-- /* m->open_mode = 0; */
--
-- if ( min ) {
-- m->min.ep = min;
-- m->min.ep->usbdev = s->usbdev;
-- m->min.cableId = inCableId;
-- }
-- /* m->min.bufPtr = 0; */
-- /* m->min.bufRemains = 0; */
--
-- if ( mout ) {
-- m->mout.ep = mout;
-- m->mout.ep->usbdev = s->usbdev;
-- m->mout.cableId = outCableId;
-- }
-- /* m->mout.bufPtr = 0; */
-- /* m->mout.bufRemains = 0; */
-- /* m->mout.isInExclusive = 0; */
-- /* m->mout.lastEvent = 0; */
--
-- m->singlebyte = singlebyte;
--
-- return m;
--}
--
--
--static void release_midi_device( struct usb_midi_state *s )
--{
-- struct usb_mididev *m;
-- struct midi_in_endpoint *min;
-- struct midi_out_endpoint *mout;
--
-- if ( s->count > 0 ) {
-- up(&open_sem);
-- return;
-- }
-- up( &open_sem );
-- wake_up( &open_wait );
--
-- while(!list_empty(&s->inEndpointList)) {
-- min = list_entry(s->inEndpointList.next, struct midi_in_endpoint, list);
-- list_del(&min->list);
-- remove_midi_in_endpoint(min);
-- }
--
-- while(!list_empty(&s->outEndpointList)) {
-- mout = list_entry(s->outEndpointList.next, struct midi_out_endpoint, list);
-- list_del(&mout->list);
-- remove_midi_out_endpoint(mout);
-- }
--
-- while(!list_empty(&s->midiDevList)) {
-- m = list_entry(s->midiDevList.next, struct usb_mididev, list);
-- list_del(&m->list);
-- kfree(m);
-- }
--
-- kfree(s);
--
-- return;
--}
--
--
--/* ------------------------------------------------------------------------- */
--
--/** Utility routine to find a descriptor in a dump of many descriptors.
-- * Returns start of descriptor or NULL if not found.
-- * descStart pointer to list of interfaces.
-- * descLength length (in bytes) of dump
-- * after (ignored if NULL) this routine returns only descriptors after "after"
-- * dtype (mandatory) The descriptor type.
-- * iface (ignored if -1) returns descriptor at/following given interface
-- * altSetting (ignored if -1) returns descriptor at/following given altSetting
-- *
-- *
-- * Called by parseDescriptor(), find_csinterface_descriptor();
-- *
-- */
--static void *find_descriptor( void *descStart, unsigned int descLength, void *after, unsigned char dtype, int iface, int altSetting )
--{
-- unsigned char *p, *end, *next;
-- int interfaceNumber = -1, altSet = -1;
--
-- p = descStart;
-- end = p + descLength;
-- for( ; p < end; ) {
-- if ( p[0] < 2 )
-- return NULL;
-- next = p + p[0];
-- if ( next > end )
-- return NULL;
-- if ( p[1] == USB_DT_INTERFACE ) {
-- if ( p[0] < USB_DT_INTERFACE_SIZE )
-- return NULL;
-- interfaceNumber = p[2];
-- altSet = p[3];
-- }
-- if ( p[1] == dtype &&
-- ( !after || ( p > (unsigned char *)after) ) &&
-- ( ( iface == -1) || (iface == interfaceNumber) ) &&
-- ( (altSetting == -1) || (altSetting == altSet) )) {
-- return p;
-- }
-- p = next;
-- }
-- return NULL;
--}
--
--/** Utility to find a class-specific interface descriptor.
-- * dsubtype is a descriptor subtype
-- * Called by parseDescriptor();
-- **/
--static void *find_csinterface_descriptor(void *descStart, unsigned int descLength, void *after, u8 dsubtype, int iface, int altSetting)
--{
-- unsigned char *p;
--
-- p = find_descriptor( descStart, descLength, after, USB_DT_CS_INTERFACE, iface, altSetting );
-- while ( p ) {
-- if ( p[0] >= 3 && p[2] == dsubtype )
-- return p;
-- p = find_descriptor( descStart, descLength, p, USB_DT_CS_INTERFACE,
-- iface, altSetting );
-- }
-- return NULL;
--}
--
--
--/** The magic of making a new usb_midi_device from config happens here.
-- *
-- * The caller is responsible for free-ing this return value (if not NULL).
-- *
-- **/
--static struct usb_midi_device *parse_descriptor( struct usb_device *d, unsigned char *buffer, int bufSize, unsigned int ifnum , unsigned int altSetting, int quirks)
--{
-- struct usb_midi_device *u;
-- unsigned char *p1;
-- unsigned char *p2;
-- unsigned char *next;
-- int iep, oep;
-- int length;
-- unsigned long longBits;
-- int pins, nbytes, offset, shift, jack;
--#ifdef HAVE_JACK_STRINGS
-- /** Jacks can have associated names. **/
-- unsigned char jack2string[256];
--#endif
--
-- u = NULL;
-- /* find audiocontrol interface */
-- p1 = find_csinterface_descriptor( buffer, bufSize, NULL,
-- MS_HEADER, ifnum, altSetting);
--
-- if ( !p1 ) {
-- goto error_end;
-- }
--
-- if ( p1[0] < MS_HEADER_LENGTH ) {
-- goto error_end;
-- }
--
-- /* Assume success. Since the device corresponds to USB-MIDI spec, we assume
-- that the rest of the USB 2.0 spec is obeyed. */
--
-- u = (struct usb_midi_device *)kmalloc( sizeof(struct usb_midi_device), GFP_KERNEL );
-- if ( !u ) {
-- return NULL;
-- }
-- u->deviceName = NULL;
-- u->idVendor = le16_to_cpu(d->descriptor.idVendor);
-- u->idProduct = le16_to_cpu(d->descriptor.idProduct);
-- u->interface = ifnum;
-- u->altSetting = altSetting;
-- u->in[0].endpoint = -1;
-- u->in[0].cableId = -1;
-- u->out[0].endpoint = -1;
-- u->out[0].cableId = -1;
--
--
-- printk(KERN_INFO "usb-midi: Found MIDIStreaming device corresponding to Release %d.%02d of spec.\n",
-- (p1[4] >> 4) * 10 + (p1[4] & 0x0f ),
-- (p1[3] >> 4) * 10 + (p1[3] & 0x0f )
-- );
--
-- length = p1[5] | (p1[6] << 8);
--
--#ifdef HAVE_JACK_STRINGS
-- memset(jack2string, 0, sizeof(unsigned char) * 256);
--#endif
--
-- length -= p1[0];
-- for (p2 = p1 + p1[0]; length > 0; p2 = next) {
-- next = p2 + p2[0];
-- length -= p2[0];
--
-- if (p2[0] < 2 )
-- break;
-- if (p2[1] != USB_DT_CS_INTERFACE)
-- break;
-- if (p2[2] == MIDI_IN_JACK && p2[0] >= 6 ) {
-- jack = p2[4];
--#ifdef HAVE_JACK_STRINGS
-- jack2string[jack] = p2[5];
--#endif
-- printk(KERN_INFO "usb-midi: Found IN Jack 0x%02x %s\n",
-- jack, (p2[3] == EMBEDDED_JACK)?"EMBEDDED":"EXTERNAL" );
-- } else if ( p2[2] == MIDI_OUT_JACK && p2[0] >= 6) {
-- pins = p2[5];
-- if ( p2[0] < (6 + 2 * pins) )
-- continue;
-- jack = p2[4];
--#ifdef HAVE_JACK_STRINGS
-- jack2string[jack] = p2[5 + 2 * pins];
--#endif
-- printk(KERN_INFO "usb-midi: Found OUT Jack 0x%02x %s, %d pins\n",
-- jack, (p2[3] == EMBEDDED_JACK)?"EMBEDDED":"EXTERNAL", pins );
-- } else if ( p2[2] == ELEMENT_DESCRIPTOR && p2[0] >= 10) {
-- pins = p2[4];
-- if ( p2[0] < (9 + 2 * pins ) )
-- continue;
-- nbytes = p2[8 + 2 * pins ];
-- if ( p2[0] < (10 + 2 * pins + nbytes) )
-- continue;
-- longBits = 0L;
-- for ( offset = 0, shift = 0; offset < nbytes && offset < 8; offset ++, shift += 8) {
-- longBits |= ((long)(p2[9 + 2 * pins + offset])) << shift;
-- }
-- jack = p2[3];
--#ifdef HAVE_JACK_STRINGS
-- jack2string[jack] = p2[9 + 2 * pins + nbytes];
--#endif
-- printk(KERN_INFO "usb-midi: Found ELEMENT 0x%02x, %d/%d pins in/out, bits: 0x%016lx\n",
-- jack, pins, (int)(p2[5 + 2 * pins]), (long)longBits );
-- } else {
-- }
-- }
--
-- iep=0;
-- oep=0;
--
-- if (quirks==0) {
-- /* MIDISTREAM */
-- p2 = NULL;
-- for (p1 = find_descriptor(buffer, bufSize, NULL, USB_DT_ENDPOINT,
-- ifnum, altSetting ); p1; p1 = next ) {
-- next = find_descriptor(buffer, bufSize, p1, USB_DT_ENDPOINT,
-- ifnum, altSetting );
-- p2 = find_descriptor(buffer, bufSize, p1, USB_DT_CS_ENDPOINT,
-- ifnum, altSetting );
--
-- if ( p2 && next && ( p2 > next ) )
-- p2 = NULL;
--
-- if ( p1[0] < 9 || !p2 || p2[0] < 4 )
-- continue;
--
-- if ( (p1[2] & 0x80) == 0x80 ) {
-- if ( iep < 15 ) {
-- pins = p2[3]; /* not pins -- actually "cables" */
-- if ( pins > 16 )
-- pins = 16;
-- u->in[iep].endpoint = p1[2];
-- u->in[iep].cableId = ( 1 << pins ) - 1;
-- if ( u->in[iep].cableId )
-- iep ++;
-- if ( iep < 15 ) {
-- u->in[iep].endpoint = -1;
-- u->in[iep].cableId = -1;
-- }
-- }
-- } else {
-- if ( oep < 15 ) {
-- pins = p2[3]; /* not pins -- actually "cables" */
-- if ( pins > 16 )
-- pins = 16;
-- u->out[oep].endpoint = p1[2];
-- u->out[oep].cableId = ( 1 << pins ) - 1;
-- if ( u->out[oep].cableId )
-- oep ++;
-- if ( oep < 15 ) {
-- u->out[oep].endpoint = -1;
-- u->out[oep].cableId = -1;
-- }
-- }
-- }
--
-- }
-- } else if (quirks==1) {
-- /* YAMAHA quirks */
-- for (p1 = find_descriptor(buffer, bufSize, NULL, USB_DT_ENDPOINT,
-- ifnum, altSetting ); p1; p1 = next ) {
-- next = find_descriptor(buffer, bufSize, p1, USB_DT_ENDPOINT,
-- ifnum, altSetting );
--
-- if ( p1[0] < 7 )
-- continue;
--
-- if ( (p1[2] & 0x80) == 0x80 ) {
-- if ( iep < 15 ) {
-- pins = iep+1;
-- if ( pins > 16 )
-- pins = 16;
-- u->in[iep].endpoint = p1[2];
-- u->in[iep].cableId = ( 1 << pins ) - 1;
-- if ( u->in[iep].cableId )
-- iep ++;
-- if ( iep < 15 ) {
-- u->in[iep].endpoint = -1;
-- u->in[iep].cableId = -1;
-- }
-- }
-- } else {
-- if ( oep < 15 ) {
-- pins = oep+1;
-- u->out[oep].endpoint = p1[2];
-- u->out[oep].cableId = ( 1 << pins ) - 1;
-- if ( u->out[oep].cableId )
-- oep ++;
-- if ( oep < 15 ) {
-- u->out[oep].endpoint = -1;
-- u->out[oep].cableId = -1;
-- }
-- }
-- }
--
-- }
-- }
--
-- if ( !iep && ! oep ) {
-- goto error_end;
-- }
--
-- return u;
--
--error_end:
-- kfree(u);
-- return NULL;
--}
--
--/* ------------------------------------------------------------------------- */
--
--/** Returns number between 0 and 16.
-- *
-- **/
--static int on_bits( unsigned short v )
--{
-- int i;
-- int ret=0;
--
-- for ( i=0 ; i<16 ; i++ ) {
-- if ( v & (1<<i) )
-- ret++;
-- }
--
-- return ret;
--}
--
--
--/** USB-device will be interrogated for altSetting.
-- *
-- * Returns negative on error.
-- * Called by allocUsbMidiDev();
-- *
-- **/
--
--static int get_alt_setting( struct usb_device *d, int ifnum )
--{
-- int alts, alt=0;
-- struct usb_interface *iface;
-- struct usb_host_interface *interface;
-- struct usb_endpoint_descriptor *ep;
-- int epin, epout;
-- int i;
--
-- iface = usb_ifnum_to_if( d, ifnum );
-- alts = iface->num_altsetting;
--
-- for ( alt=0 ; alt<alts ; alt++ ) {
-- interface = &iface->altsetting[alt];
-- epin = -1;
-- epout = -1;
--
-- for ( i=0 ; i<interface->desc.bNumEndpoints ; i++ ) {
-- ep = &interface->endpoint[i].desc;
-- if ( (ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_BULK ) {
-- continue;
-- }
-- if ( (ep->bEndpointAddress & USB_DIR_IN) && epin < 0 ) {
-- epin = i;
-- } else if ( epout < 0 ) {
-- epout = i;
-- }
-- if ( epin >= 0 && epout >= 0 ) {
-- return interface->desc.bAlternateSetting;
-- }
-- }
-- }
--
-- return -ENODEV;
--}
--
--
--/* ------------------------------------------------------------------------- */
--
--
--/** Returns 0 if successful in allocating and registering internal structures.
-- * Returns negative on failure.
-- * Calls allocMidiDev which additionally registers /dev/midiXX devices.
-- * Writes messages on success to indicate which /dev/midiXX is which physical
-- * endpoint.
-- *
-- **/
--static int alloc_usb_midi_device( struct usb_device *d, struct usb_midi_state *s, struct usb_midi_device *u )
--{
-- struct usb_mididev **mdevs=NULL;
-- struct midi_in_endpoint *mins[15], *min;
-- struct midi_out_endpoint *mouts[15], *mout;
-- int inDevs=0, outDevs=0;
-- int inEndpoints=0, outEndpoints=0;
-- int inEndpoint, outEndpoint;
-- int inCableId, outCableId;
-- int i;
-- int devices = 0;
-- int alt = 0;
--
-- /* Obtain altSetting or die.. */
-- alt = u->altSetting;
-- if ( alt < 0 ) {
-- alt = get_alt_setting( d, u->interface );
-- }
-- if ( alt < 0 )
-- return -ENXIO;
--
-- /* Configure interface */
-- if ( usb_set_interface( d, u->interface, alt ) < 0 ) {
-- return -ENXIO;
-- }
--
-- for ( i = 0 ; i < 15 ; i++ ) {
-- mins[i] = NULL;
-- mouts[i] = NULL;
-- }
--
-- /* Begin Allocation */
-- while( inEndpoints < 15
-- && inDevs < maxdevices
-- && u->in[inEndpoints].cableId >= 0 ) {
-- inDevs += on_bits((unsigned short)u->in[inEndpoints].cableId);
-- mins[inEndpoints] = alloc_midi_in_endpoint( d, u->in[inEndpoints].endpoint );
-- if ( mins[inEndpoints] == NULL )
-- goto error_end;
-- inEndpoints++;
-- }
--
-- while( outEndpoints < 15
-- && outDevs < maxdevices
-- && u->out[outEndpoints].cableId >= 0 ) {
-- outDevs += on_bits((unsigned short)u->out[outEndpoints].cableId);
-- mouts[outEndpoints] = alloc_midi_out_endpoint( d, u->out[outEndpoints].endpoint );
-- if ( mouts[outEndpoints] == NULL )
-- goto error_end;
-- outEndpoints++;
-- }
--
-- devices = inDevs > outDevs ? inDevs : outDevs;
-- devices = maxdevices > devices ? devices : maxdevices;
--
-- /* obtain space for device name (iProduct) if not known. */
-- if ( ! u->deviceName ) {
-- mdevs = (struct usb_mididev **)
-- kmalloc(sizeof(struct usb_mididevs *)*devices
-- + sizeof(char) * 256, GFP_KERNEL);
-- } else {
-- mdevs = (struct usb_mididev **)
-- kmalloc(sizeof(struct usb_mididevs *)*devices, GFP_KERNEL);
-- }
--
-- if ( !mdevs ) {
-- /* devices = 0; */
-- /* mdevs = NULL; */
-- goto error_end;
-- }
-- for ( i=0 ; i<devices ; i++ ) {
-- mdevs[i] = NULL;
-- }
--
-- /* obtain device name (iProduct) if not known. */
-- if ( ! u->deviceName ) {
-- u->deviceName = (char *) (mdevs + devices);
-- if ( ! d->have_langid && d->descriptor.iProduct) {
-- alt = usb_get_string(d, 0, 0, u->deviceName, 250);
-- if (alt < 0) {
-- printk(KERN_INFO "error getting string descriptor 0 (error=%d)\n", alt);
-- } else if (u->deviceName[0] < 4) {
-- printk(KERN_INFO "string descriptor 0 too short (length = %d)\n", alt);
-- } else {
-- printk(KERN_INFO "string descriptor 0 found (length = %d)\n", alt);
-- for(; alt >= 4; alt -= 2) {
-- i = u->deviceName[alt-2] | (u->deviceName[alt-1]<< 8);
-- printk(KERN_INFO "usb-midi: langid(%d) 0x%04x\n",
-- (alt-4) >> 1, i);
-- if ( ( ( i ^ ulangid ) & 0xff ) == 0 ) {
-- d->have_langid = 1;
-- d->string_langid = i;
-- printk(KERN_INFO "usb-midi: langid(match) 0x%04x\n", i);
-- if ( i == ulangid )
-- break;
-- }
-- }
-- }
-- }
-- u->deviceName[0] = (char) 0;
-- if (d->descriptor.iProduct) {
-- printk(KERN_INFO "usb-midi: fetchString(%d)\n", d->descriptor.iProduct);
-- alt = usb_string(d, d->descriptor.iProduct, u->deviceName, 255);
-- if( alt < 0 ) {
-- u->deviceName[0] = (char) 0;
-- }
-- printk(KERN_INFO "usb-midi: fetchString = %d\n", alt);
-- }
-- /* Failsafe */
-- if ( !u->deviceName[0] ) {
-- if (le16_to_cpu(d->descriptor.idVendor) == USB_VENDOR_ID_ROLAND ) {
-- strcpy(u->deviceName, "Unknown Roland");
-- } else if (le16_to_cpu(d->descriptor.idVendor) == USB_VENDOR_ID_STEINBERG ) {
-- strcpy(u->deviceName, "Unknown Steinberg");
-- } else if (le16_to_cpu(d->descriptor.idVendor) == USB_VENDOR_ID_YAMAHA ) {
-- strcpy(u->deviceName, "Unknown Yamaha");
-- } else {
-- strcpy(u->deviceName, "Unknown");
-- }
-- }
-- }
--
-- inEndpoint = 0; inCableId = -1;
-- outEndpoint = 0; outCableId = -1;
--
-- for ( i=0 ; i<devices ; i++ ) {
-- for ( inCableId ++ ;
-- inEndpoint <15
-- && mins[inEndpoint]
-- && !(u->in[inEndpoint].cableId & (1<<inCableId)) ;
-- inCableId++ ) {
-- if ( inCableId >= 16 ) {
-- inEndpoint ++;
-- inCableId = 0;
-- }
-- }
-- min = mins[inEndpoint];
-- for ( outCableId ++ ;
-- outEndpoint <15
-- && mouts[outEndpoint]
-- && !(u->out[outEndpoint].cableId & (1<<outCableId)) ;
-- outCableId++ ) {
-- if ( outCableId >= 16 ) {
-- outEndpoint ++;
-- outCableId = 0;
-- }
-- }
-- mout = mouts[outEndpoint];
--
-- mdevs[i] = allocMidiDev( s, min, mout, inCableId, outCableId );
-- if ( mdevs[i] == NULL )
-- goto error_end;
--
-- }
--
-- /* Success! */
-- for ( i=0 ; i<devices ; i++ ) {
-- list_add_tail( &mdevs[i]->list, &s->midiDevList );
-- }
-- for ( i=0 ; i<inEndpoints ; i++ ) {
-- list_add_tail( &mins[i]->list, &s->inEndpointList );
-- }
-- for ( i=0 ; i<outEndpoints ; i++ ) {
-- list_add_tail( &mouts[i]->list, &s->outEndpointList );
-- }
--
-- printk(KERN_INFO "usbmidi: found [ %s ] (0x%04x:0x%04x), attached:\n", u->deviceName, u->idVendor, u->idProduct );
-- for ( i=0 ; i<devices ; i++ ) {
-- int dm = (mdevs[i]->dev_midi-2)>>4;
-- if ( mdevs[i]->mout.ep != NULL && mdevs[i]->min.ep != NULL ) {
-- printk(KERN_INFO "usbmidi: /dev/midi%02d: in (ep:%02x cid:%2d bufsiz:%2d) out (ep:%02x cid:%2d bufsiz:%2d)\n",
-- dm,
-- mdevs[i]->min.ep->endpoint|USB_DIR_IN, mdevs[i]->min.cableId, mdevs[i]->min.ep->recvBufSize,
-- mdevs[i]->mout.ep->endpoint, mdevs[i]->mout.cableId, mdevs[i]->mout.ep->bufSize);
-- } else if ( mdevs[i]->min.ep != NULL ) {
-- printk(KERN_INFO "usbmidi: /dev/midi%02d: in (ep:%02x cid:%2d bufsiz:%02d)\n",
-- dm,
-- mdevs[i]->min.ep->endpoint|USB_DIR_IN, mdevs[i]->min.cableId, mdevs[i]->min.ep->recvBufSize);
-- } else if ( mdevs[i]->mout.ep != NULL ) {
-- printk(KERN_INFO "usbmidi: /dev/midi%02d: out (ep:%02x cid:%2d bufsiz:%02d)\n",
-- dm,
-- mdevs[i]->mout.ep->endpoint, mdevs[i]->mout.cableId, mdevs[i]->mout.ep->bufSize);
-- }
-- }
--
-- kfree(mdevs);
-- return 0;
--
-- error_end:
-- if ( mdevs != NULL ) {
-- for ( i=0 ; i<devices ; i++ ) {
-- if ( mdevs[i] != NULL ) {
-- unregister_sound_midi( mdevs[i]->dev_midi );
-- kfree(mdevs[i]);
-- }
-- }
-- kfree(mdevs);
-- }
--
-- for ( i=0 ; i<15 ; i++ ) {
-- if ( mins[i] != NULL ) {
-- remove_midi_in_endpoint( mins[i] );
-- }
-- if ( mouts[i] != NULL ) {
-- remove_midi_out_endpoint( mouts[i] );
-- }
-- }
--
-- return -ENOMEM;
--}
--
--/* ------------------------------------------------------------------------- */
--
--/** Attempt to scan YAMAHA's device descriptor and detect correct values of
-- * them.
-- * Return 0 on succes, negative on failure.
-- * Called by usb_midi_probe();
-- **/
--
--static int detect_yamaha_device( struct usb_device *d,
-- struct usb_interface *iface, unsigned int ifnum,
-- struct usb_midi_state *s)
--{
-- struct usb_host_interface *interface;
-- struct usb_midi_device *u;
-- unsigned char *buffer;
-- int bufSize;
-- int i;
-- int alts=-1;
-- int ret;
--
-- if (le16_to_cpu(d->descriptor.idVendor) != USB_VENDOR_ID_YAMAHA) {
-- return -EINVAL;
-- }
--
-- for ( i=0 ; i < iface->num_altsetting; i++ ) {
-- interface = iface->altsetting + i;
--
-- if ( interface->desc.bInterfaceClass != 255 ||
-- interface->desc.bInterfaceSubClass != 0 )
-- continue;
-- alts = interface->desc.bAlternateSetting;
-- }
-- if ( alts == -1 ) {
-- return -EINVAL;
-- }
--
-- printk(KERN_INFO "usb-midi: Found YAMAHA USB-MIDI device on dev %04x:%04x, iface %d\n",
-- le16_to_cpu(d->descriptor.idVendor),
-- le16_to_cpu(d->descriptor.idProduct), ifnum);
--
-- i = d->actconfig - d->config;
-- buffer = d->rawdescriptors[i];
-- bufSize = le16_to_cpu(d->actconfig->desc.wTotalLength);
--
-- u = parse_descriptor( d, buffer, bufSize, ifnum, alts, 1);
-- if ( u == NULL ) {
-- return -EINVAL;
-- }
--
-- ret = alloc_usb_midi_device( d, s, u );
--
-- kfree(u);
--
-- return ret;
--}
--
--
--/** Scan table of known devices which are only partially compliant with
-- * the MIDIStreaming specification.
-- * Called by usb_midi_probe();
-- *
-- **/
--
--static int detect_vendor_specific_device( struct usb_device *d, unsigned int ifnum, struct usb_midi_state *s )
--{
-- struct usb_midi_device *u;
-- int i;
-- int ret = -ENXIO;
--
-- for ( i=0; i<VENDOR_SPECIFIC_USB_MIDI_DEVICES ; i++ ) {
-- u=&(usb_midi_devices[i]);
--
-- if ( le16_to_cpu(d->descriptor.idVendor) != u->idVendor ||
-- le16_to_cpu(d->descriptor.idProduct) != u->idProduct ||
-- ifnum != u->interface )
-- continue;
--
-- ret = alloc_usb_midi_device( d, s, u );
-- break;
-- }
--
-- return ret;
--}
--
--
--/** Attempt to match any config of an interface to a MIDISTREAMING interface.
-- * Returns 0 on success, negative on failure.
-- * Called by usb_midi_probe();
-- **/
--static int detect_midi_subclass(struct usb_device *d,
-- struct usb_interface *iface, unsigned int ifnum,
-- struct usb_midi_state *s)
--{
-- struct usb_host_interface *interface;
-- struct usb_midi_device *u;
-- unsigned char *buffer;
-- int bufSize;
-- int i;
-- int alts=-1;
-- int ret;
--
-- for ( i=0 ; i < iface->num_altsetting; i++ ) {
-- interface = iface->altsetting + i;
--
-- if ( interface->desc.bInterfaceClass != USB_CLASS_AUDIO ||
-- interface->desc.bInterfaceSubClass != USB_SUBCLASS_MIDISTREAMING )
-- continue;
-- alts = interface->desc.bAlternateSetting;
-- }
-- if ( alts == -1 ) {
-- return -EINVAL;
-- }
--
-- printk(KERN_INFO "usb-midi: Found MIDISTREAMING on dev %04x:%04x, iface %d\n",
-- le16_to_cpu(d->descriptor.idVendor),
-- le16_to_cpu(d->descriptor.idProduct), ifnum);
--
--
-- /* From USB Spec v2.0, Section 9.5.
-- If the class or vendor specific descriptors use the same format
-- as standard descriptors (e.g., start with a length byte and
-- followed by a type byte), they must be returned interleaved with
-- standard descriptors in the configuration information returned by
-- a GetDescriptor(Configuration) request. In this case, the class
-- or vendor-specific descriptors must follow a related standard
-- descriptor they modify or extend.
-- */
--
-- i = d->actconfig - d->config;
-- buffer = d->rawdescriptors[i];
-- bufSize = le16_to_cpu(d->actconfig->desc.wTotalLength);
--
-- u = parse_descriptor( d, buffer, bufSize, ifnum, alts, 0);
-- if ( u == NULL ) {
-- return -EINVAL;
-- }
--
-- ret = alloc_usb_midi_device( d, s, u );
--
-- kfree(u);
--
-- return ret;
--}
--
--
--/** When user has requested a specific device, match it exactly.
-- *
-- * Uses uvendor, uproduct, uinterface, ualt, umin, umout and ucable.
-- * Called by usb_midi_probe();
-- *
-- **/
--static int detect_by_hand(struct usb_device *d, unsigned int ifnum, struct usb_midi_state *s)
--{
-- struct usb_midi_device u;
--
-- if ( le16_to_cpu(d->descriptor.idVendor) != uvendor ||
-- le16_to_cpu(d->descriptor.idProduct) != uproduct ||
-- ifnum != uinterface ) {
-- return -EINVAL;
-- }
--
-- if ( ualt < 0 )
-- ualt = -1;
--
-- if ( umin < 0 || umin > 15 )
-- umin = 0x01 | USB_DIR_IN;
-- if ( umout < 0 || umout > 15 )
-- umout = 0x01;
-- if ( ucable < 0 || ucable > 15 )
-- ucable = 0;
--
-- u.deviceName = NULL; /* A flag for alloc_usb_midi_device to get device
-- name from device. */
-- u.idVendor = uvendor;
-- u.idProduct = uproduct;
-- u.interface = uinterface;
-- u.altSetting = ualt;
--
-- u.in[0].endpoint = umin;
-- u.in[0].cableId = (1<<ucable);
--
-- u.out[0].endpoint = umout;
-- u.out[0].cableId = (1<<ucable);
--
-- return alloc_usb_midi_device( d, s, &u );
--}
--
--
--
--/* ------------------------------------------------------------------------- */
--
--static int usb_midi_probe(struct usb_interface *intf,
-- const struct usb_device_id *id)
--{
-- struct usb_midi_state *s;
-- struct usb_device *dev = interface_to_usbdev(intf);
-- int ifnum = intf->cur_altsetting->desc.bInterfaceNumber;
--
-- s = (struct usb_midi_state *)kmalloc(sizeof(struct usb_midi_state), GFP_KERNEL);
-- if ( !s )
-- return -ENOMEM;
--
-- memset( s, 0, sizeof(struct usb_midi_state) );
-- INIT_LIST_HEAD(&s->midiDevList);
-- INIT_LIST_HEAD(&s->inEndpointList);
-- INIT_LIST_HEAD(&s->outEndpointList);
-- s->usbdev = dev;
-- s->count = 0;
-- spin_lock_init(&s->lock);
--
-- if (
-- detect_by_hand( dev, ifnum, s ) &&
-- detect_midi_subclass( dev, intf, ifnum, s ) &&
-- detect_vendor_specific_device( dev, ifnum, s ) &&
-- detect_yamaha_device( dev, intf, ifnum, s) ) {
-- kfree(s);
-- return -EIO;
-- }
--
-- down(&open_sem);
-- list_add_tail(&s->mididev, &mididevs);
-- up(&open_sem);
--
-- usb_set_intfdata (intf, s);
-- return 0;
--}
--
--
--static void usb_midi_disconnect(struct usb_interface *intf)
--{
-- struct usb_midi_state *s = usb_get_intfdata (intf);
-- struct usb_mididev *m;
--
-- if ( !s )
-- return;
--
-- if ( s == (struct usb_midi_state *)-1 ) {
-- return;
-- }
-- if ( !s->usbdev ) {
-- return;
-- }
-- down(&open_sem);
-- list_del(&s->mididev);
-- INIT_LIST_HEAD(&s->mididev);
-- s->usbdev = NULL;
-- usb_set_intfdata (intf, NULL);
--
-- list_for_each_entry(m, &s->midiDevList, list) {
-- wake_up(&(m->min.ep->wait));
-- wake_up(&(m->mout.ep->wait));
-- if ( m->dev_midi >= 0 ) {
-- unregister_sound_midi(m->dev_midi);
-- }
-- m->dev_midi = -1;
-- }
-- release_midi_device(s);
-- wake_up(&open_wait);
--}
--
--/* we want to look at all devices by hand */
--static struct usb_device_id id_table[] = {
-- {.driver_info = 42},
-- {}
--};
--
--static struct usb_driver usb_midi_driver = {
-- .name = "midi",
-- .probe = usb_midi_probe,
-- .disconnect = usb_midi_disconnect,
-- .id_table = id_table,
--};
--
--/* ------------------------------------------------------------------------- */
--
--static int __init usb_midi_init(void)
--{
-- return usb_register(&usb_midi_driver);
--}
--
--static void __exit usb_midi_exit(void)
--{
-- usb_deregister(&usb_midi_driver);
--}
--
--module_init(usb_midi_init) ;
--module_exit(usb_midi_exit) ;
--
--#ifdef HAVE_ALSA_SUPPORT
--#define SNDRV_MAIN_OBJECT_FILE
--#include "../../include/driver.h"
--#include "../../include/control.h"
--#include "../../include/info.h"
--#include "../../include/cs46xx.h"
--
--/* ------------------------------------------------------------------------- */
--
--static int snd_usbmidi_input_close(snd_rawmidi_substream_t * substream)
--{
-- return 0;
--}
--
--static int snd_usbmidi_input_open(snd_rawmidi_substream_t * substream )
--{
-- return 0;
--}
--
--static void snd_usbmidi_input_trigger(snd_rawmidi_substream_t * substream, int up)
--{
-- return 0;
--}
--
--
--/* ------------------------------------------------------------------------- */
--
--static int snd_usbmidi_output_close(snd_rawmidi_substream_t * substream)
--{
-- return 0;
--}
--
--static int snd_usbmidi_output_open(snd_rawmidi_substream_t * substream)
--{
-- return 0;
--}
--
--static void snd_usb_midi_output_trigger(snd_rawmidi_substream_t * substream,
-- int up)
--{
-- return 0;
--}
--
--/* ------------------------------------------------------------------------- */
--
--static snd_rawmidi_ops_t snd_usbmidi_output =
--{
-- .open = snd_usbmidi_output_open,
-- .close = snd_usbmidi_output_close,
-- .trigger = snd_usbmidi_output_trigger,
--};
--static snd_rawmidi_ops_t snd_usbmidi_input =
--{
-- .open = snd_usbmidi_input_open,
-- .close = snd_usbmidi_input_close,
-- .trigger = snd_usbmidi_input_trigger,
--};
--
--int snd_usbmidi_midi(cs46xx_t *chip, int device, snd_rawmidi_t **rrawmidi)
--{
-- snd_rawmidi_t *rmidi;
-- int err;
--
-- if (rrawmidi)
-- *rrawmidi = NULL;
-- if ((err = snd_rawmidi_new(chip->card, "USB-MIDI", device, 1, 1, &rmidi)) < 0)
-- return err;
-- strcpy(rmidi->name, "USB-MIDI");
--
-- snd_rawmidi_set_ops( rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_usbmidi_output );
-- snd_rawmidi_set_ops( rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_usbmidi_input );
--
-- rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT | SNDRV_RAWMIDI_INFO_INPUT | SNDRV_RAWMIDI_INFO_DUPLEX;
--
-- rmidi->private_data = chip;
-- chip->rmidi = rmidi;
-- if (rrawmidi)
-- *rrawmidi = NULL;
--
-- return 0;
--}
--
--int snd_usbmidi_create( snd_card_t * card,
-- struct pci_dev * pci,
-- usbmidi_t ** rchip )
--{
-- usbmidi_t *chip;
-- int err, idx;
-- snd_region_t *region;
-- static snd_device_opt_t ops = {
-- .dev_free = snd_usbmidi_dev_free,
-- };
--
-- *rchip = NULL;
-- chip = snd_magic_kcalloc( usbmidi_t, 0, GFP_KERNEL );
-- if ( chip == NULL )
-- return -ENOMEM;
--}
--
--EXPORT_SYMBOL(snd_usbmidi_create);
--EXPORT_SYMBOL(snd_usbmidi_midi);
--#endif /* HAVE_ALSA_SUPPORT */
--
---- gregkh-2.6.orig/drivers/usb/class/usb-midi.h
-+++ /dev/null
-@@ -1,164 +0,0 @@
--/*
-- usb-midi.h -- USB-MIDI driver
--
-- Copyright (C) 2001
-- NAGANO Daisuke <breeze.nagano@nifty.ne.jp>
--
-- 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, 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.
-- */
--
--/* ------------------------------------------------------------------------- */
--
--#ifndef _USB_MIDI_H_
--#define _USB_MIDI_H_
--
--#ifndef USB_SUBCLASS_MIDISTREAMING
--#define USB_SUBCLASS_MIDISTREAMING 3
--#endif
--
--/* ------------------------------------------------------------------------- */
--/* Roland MIDI Devices */
--
--#define USB_VENDOR_ID_ROLAND 0x0582
--#define USBMIDI_ROLAND_UA100G 0x0000
--#define USBMIDI_ROLAND_MPU64 0x0002
--#define USBMIDI_ROLAND_SC8850 0x0003
--#define USBMIDI_ROLAND_SC8820 0x0007
--#define USBMIDI_ROLAND_UM2 0x0005
--#define USBMIDI_ROLAND_UM1 0x0009
--#define USBMIDI_ROLAND_PC300 0x0008
--
--/* YAMAHA MIDI Devices */
--#define USB_VENDOR_ID_YAMAHA 0x0499
--#define USBMIDI_YAMAHA_MU1000 0x1001
--
--/* Steinberg MIDI Devices */
--#define USB_VENDOR_ID_STEINBERG 0x0763
--#define USBMIDI_STEINBERG_USB2MIDI 0x1001
--
--/* Mark of the Unicorn MIDI Devices */
--#define USB_VENDOR_ID_MOTU 0x07fd
--#define USBMIDI_MOTU_FASTLANE 0x0001
--
--/* ------------------------------------------------------------------------- */
--/* Supported devices */
--
--struct usb_midi_endpoint {
-- int endpoint;
-- int cableId; /* if bit-n == 1 then cableId-n is enabled (n: 0 - 15) */
--};
--
--struct usb_midi_device {
-- char *deviceName;
--
-- u16 idVendor;
-- u16 idProduct;
-- int interface;
-- int altSetting; /* -1: auto detect */
--
-- struct usb_midi_endpoint in[15];
-- struct usb_midi_endpoint out[15];
--};
--
--static struct usb_midi_device usb_midi_devices[] = {
-- { /* Roland UM-1 */
-- "Roland UM-1",
-- USB_VENDOR_ID_ROLAND, USBMIDI_ROLAND_UM1, 2, -1,
-- { { 0x81, 1 }, {-1, -1} },
-- { { 0x01, 1,}, {-1, -1} },
-- },
--
-- { /* Roland UM-2 */
-- "Roland UM-2" ,
-- USB_VENDOR_ID_ROLAND, USBMIDI_ROLAND_UM2, 2, -1,
-- { { 0x81, 3 }, {-1, -1} },
-- { { 0x01, 3,}, {-1, -1} },
-- },
--
--/** Next entry courtesy research by Michael Minn <michael@michaelminn.com> **/
-- { /* Roland UA-100 */
-- "Roland UA-100",
-- USB_VENDOR_ID_ROLAND, USBMIDI_ROLAND_UA100G, 2, -1,
-- { { 0x82, 7 }, {-1, -1} }, /** cables 0,1 and 2 for SYSEX **/
-- { { 0x02, 7 }, {-1, -1} },
-- },
--
--/** Next entry courtesy research by Michael Minn <michael@michaelminn.com> **/
-- { /* Roland SC8850 */
-- "Roland SC8850",
-- USB_VENDOR_ID_ROLAND, USBMIDI_ROLAND_SC8850, 2, -1,
-- { { 0x81, 0x3f }, {-1, -1} },
-- { { 0x01, 0x3f }, {-1, -1} },
-- },
--
-- { /* Roland SC8820 */
-- "Roland SC8820",
-- USB_VENDOR_ID_ROLAND, USBMIDI_ROLAND_SC8820, 2, -1,
-- { { 0x81, 0x13 }, {-1, -1} },
-- { { 0x01, 0x13 }, {-1, -1} },
-- },
--
-- { /* Roland SC8820 */
-- "Roland SC8820",
-- USB_VENDOR_ID_ROLAND, USBMIDI_ROLAND_SC8820, 2, -1,
-- { { 0x81, 17 }, {-1, -1} },
-- { { 0x01, 17 }, {-1, -1} },
-- },
--
-- { /* YAMAHA MU1000 */
-- "YAMAHA MU1000",
-- USB_VENDOR_ID_YAMAHA, USBMIDI_YAMAHA_MU1000, 0, -1,
-- { { 0x81, 1 }, {-1, -1} },
-- { { 0x01, 15 }, {-1, -1} },
-- },
-- { /* Roland PC-300 */
-- "Roland PC-300",
-- USB_VENDOR_ID_ROLAND, USBMIDI_ROLAND_PC300, 2, -1,
-- { { 0x81, 1 }, {-1, -1} },
-- { { 0x01, 1 }, {-1, -1} },
-- },
-- { /* MOTU Fastlane USB */
-- "MOTU Fastlane USB",
-- USB_VENDOR_ID_MOTU, USBMIDI_MOTU_FASTLANE, 1, 0,
-- { { 0x82, 3 }, {-1, -1} },
-- { { 0x02, 3 }, {-1, -1} },
-- }
--};
--
--#define VENDOR_SPECIFIC_USB_MIDI_DEVICES (sizeof(usb_midi_devices)/sizeof(struct usb_midi_device))
--
--/* for Hot-Plugging */
--
--static struct usb_device_id usb_midi_ids [] = {
-- { .match_flags = (USB_DEVICE_ID_MATCH_INT_CLASS | USB_DEVICE_ID_MATCH_INT_SUBCLASS),
-- .bInterfaceClass = USB_CLASS_AUDIO, .bInterfaceSubClass = USB_SUBCLASS_MIDISTREAMING},
-- { USB_DEVICE( USB_VENDOR_ID_ROLAND, USBMIDI_ROLAND_UM1 ) },
-- { USB_DEVICE( USB_VENDOR_ID_ROLAND, USBMIDI_ROLAND_UM2 ) },
-- { USB_DEVICE( USB_VENDOR_ID_ROLAND, USBMIDI_ROLAND_UA100G ) },
-- { USB_DEVICE( USB_VENDOR_ID_ROLAND, USBMIDI_ROLAND_PC300 ) },
-- { USB_DEVICE( USB_VENDOR_ID_ROLAND, USBMIDI_ROLAND_SC8850 ) },
-- { USB_DEVICE( USB_VENDOR_ID_ROLAND, USBMIDI_ROLAND_SC8820 ) },
-- { USB_DEVICE( USB_VENDOR_ID_YAMAHA, USBMIDI_YAMAHA_MU1000 ) },
-- { USB_DEVICE( USB_VENDOR_ID_MOTU, USBMIDI_MOTU_FASTLANE ) },
--/* { USB_DEVICE( USB_VENDOR_ID_STEINBERG, USBMIDI_STEINBERG_USB2MIDI ) },*/
-- { } /* Terminating entry */
--};
--
--MODULE_DEVICE_TABLE (usb, usb_midi_ids);
--
--/* ------------------------------------------------------------------------- */
--#endif /* _USB_MIDI_H_ */
--
--
diff --git a/usb/usb-remove-usbcore-specific-wakeup-flags.patch b/usb/usb-remove-usbcore-specific-wakeup-flags.patch
deleted file mode 100644
index a4595fdb4fbdc..0000000000000
--- a/usb/usb-remove-usbcore-specific-wakeup-flags.patch
+++ /dev/null
@@ -1,181 +0,0 @@
-From david-b@pacbell.net Tue Jan 24 08:40:38 2006
-From: David Brownell <david-b@pacbell.net>
-Subject: USB: remove usbcore-specific wakeup flags
-Date: Tue, 24 Jan 2006 08:40:27 -0800
-Cc: Alan Stern <stern@rowland.harvard.edu>, Greg KH <greg@kroah.com>
-Message-Id: <200601240840.27533.david-b@pacbell.net>
-
-
-This makes usbcore use the driver model wakeup flags for host controllers
-and for their root hubs. Since previous patches have removed all users of
-the HCD flags they replace, this converts the last users of those flags.
-
-Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-
----
- drivers/usb/core/hcd-pci.c | 11 ++++++++---
- drivers/usb/core/hcd.c | 40 ++++++++++++++++++++++++++--------------
- drivers/usb/core/hcd.h | 2 --
- drivers/usb/core/hub.c | 22 ++++++++++++++--------
- 4 files changed, 48 insertions(+), 27 deletions(-)
-
---- gregkh-2.6.orig/drivers/usb/core/hcd-pci.c
-+++ gregkh-2.6/drivers/usb/core/hcd-pci.c
-@@ -264,14 +264,19 @@ int usb_hcd_pci_suspend (struct pci_dev
- */
- retval = pci_set_power_state (dev, PCI_D3hot);
- if (retval == 0) {
-- dev_dbg (hcd->self.controller, "--> PCI D3\n");
-+ int wake = device_can_wakeup(&hcd->self.root_hub->dev);
-+
-+ wake = wake && device_may_wakeup(hcd->self.controller);
-+
-+ dev_dbg (hcd->self.controller, "--> PCI D3%s\n",
-+ wake ? "/wakeup" : "");
-
- /* Ignore these return values. We rely on pci code to
- * reject requests the hardware can't implement, rather
- * than coding the same thing.
- */
-- (void) pci_enable_wake (dev, PCI_D3hot, hcd->remote_wakeup);
-- (void) pci_enable_wake (dev, PCI_D3cold, hcd->remote_wakeup);
-+ (void) pci_enable_wake (dev, PCI_D3hot, wake);
-+ (void) pci_enable_wake (dev, PCI_D3cold, wake);
- } else {
- dev_dbg (&dev->dev, "PCI D3 suspend fail, %d\n",
- retval);
---- gregkh-2.6.orig/drivers/usb/core/hcd.c
-+++ gregkh-2.6/drivers/usb/core/hcd.c
-@@ -367,21 +367,39 @@ static int rh_call_control (struct usb_h
-
- /* DEVICE REQUESTS */
-
-+ /* The root hub's remote wakeup enable bit is implemented using
-+ * driver model wakeup flags. If this system supports wakeup
-+ * through USB, userspace may change the default "allow wakeup"
-+ * policy through sysfs or these calls.
-+ *
-+ * Most root hubs support wakeup from downstream devices, for
-+ * runtime power management (disabling USB clocks and reducing
-+ * VBUS power usage). However, not all of them do so; silicon,
-+ * board, and BIOS bugs here are not uncommon, so these can't
-+ * be treated quite like external hubs.
-+ *
-+ * Likewise, not all root hubs will pass wakeup events upstream,
-+ * to wake up the whole system. So don't assume root hub and
-+ * controller capabilities are identical.
-+ */
-+
- case DeviceRequest | USB_REQ_GET_STATUS:
-- tbuf [0] = (hcd->remote_wakeup << USB_DEVICE_REMOTE_WAKEUP)
-+ tbuf [0] = (device_may_wakeup(&hcd->self.root_hub->dev)
-+ << USB_DEVICE_REMOTE_WAKEUP)
- | (1 << USB_DEVICE_SELF_POWERED);
- tbuf [1] = 0;
- len = 2;
- break;
- case DeviceOutRequest | USB_REQ_CLEAR_FEATURE:
- if (wValue == USB_DEVICE_REMOTE_WAKEUP)
-- hcd->remote_wakeup = 0;
-+ device_set_wakeup_enable(&hcd->self.root_hub->dev, 0);
- else
- goto error;
- break;
- case DeviceOutRequest | USB_REQ_SET_FEATURE:
-- if (hcd->can_wakeup && wValue == USB_DEVICE_REMOTE_WAKEUP)
-- hcd->remote_wakeup = 1;
-+ if (device_can_wakeup(&hcd->self.root_hub->dev)
-+ && wValue == USB_DEVICE_REMOTE_WAKEUP)
-+ device_set_wakeup_enable(&hcd->self.root_hub->dev, 1);
- else
- goto error;
- break;
-@@ -410,7 +428,7 @@ static int rh_call_control (struct usb_h
- bufp = fs_rh_config_descriptor;
- len = sizeof fs_rh_config_descriptor;
- }
-- if (hcd->can_wakeup)
-+ if (device_can_wakeup(&hcd->self.root_hub->dev))
- patch_wakeup = 1;
- break;
- case USB_DT_STRING << 8:
-@@ -1804,16 +1822,10 @@ int usb_add_hcd(struct usb_hcd *hcd,
- device_init_wakeup(&rhdev->dev,
- device_can_wakeup(hcd->self.controller));
-
-- // ... all these hcd->*_wakeup flags will vanish
-- hcd->can_wakeup = device_can_wakeup(hcd->self.controller);
--
-- /* hcd->driver->reset() reported can_wakeup, probably with
-- * assistance from board's boot firmware.
-- * NOTE: normal devices won't enable wakeup by default.
-- */
-- if (hcd->can_wakeup)
-+ /* NOTE: root hub and controller capabilities may not be the same */
-+ if (device_can_wakeup(hcd->self.controller)
-+ && device_can_wakeup(&hcd->self.root_hub->dev))
- dev_dbg(hcd->self.controller, "supports USB remote wakeup\n");
-- hcd->remote_wakeup = hcd->can_wakeup;
-
- /* enable irqs just before we start the controller */
- if (hcd->driver->irq) {
---- gregkh-2.6.orig/drivers/usb/core/hcd.h
-+++ gregkh-2.6/drivers/usb/core/hcd.h
-@@ -78,8 +78,6 @@ struct usb_hcd { /* usb_bus.hcpriv point
- #define HCD_FLAG_HW_ACCESSIBLE 0x00000001
- #define HCD_FLAG_SAW_IRQ 0x00000002
-
-- unsigned can_wakeup:1; /* hw supports wakeup? */
-- unsigned remote_wakeup:1;/* sw should use wakeup? */
- unsigned rh_registered:1;/* is root hub registered? */
-
- /* The next flag is a stopgap, to be removed when all the HCDs
---- gregkh-2.6.orig/drivers/usb/core/hub.c
-+++ gregkh-2.6/drivers/usb/core/hub.c
-@@ -1006,12 +1006,18 @@ void usb_set_device_state(struct usb_dev
- ; /* do nothing */
- else if (new_state != USB_STATE_NOTATTACHED) {
- udev->state = new_state;
-- if (new_state == USB_STATE_CONFIGURED)
-- device_init_wakeup(&udev->dev,
-- (udev->actconfig->desc.bmAttributes
-- & USB_CONFIG_ATT_WAKEUP));
-- else if (new_state != USB_STATE_SUSPENDED)
-- device_init_wakeup(&udev->dev, 0);
-+
-+ /* root hub wakeup capabilities are managed out-of-band
-+ * and may involve silicon errata ... ignore them here.
-+ */
-+ if (udev->parent) {
-+ if (new_state == USB_STATE_CONFIGURED)
-+ device_init_wakeup(&udev->dev,
-+ (udev->actconfig->desc.bmAttributes
-+ & USB_CONFIG_ATT_WAKEUP));
-+ else if (new_state != USB_STATE_SUSPENDED)
-+ device_init_wakeup(&udev->dev, 0);
-+ }
- } else
- recursively_mark_NOTATTACHED(udev);
- spin_unlock_irqrestore(&device_state_lock, flags);
-@@ -1877,9 +1883,9 @@ int usb_resume_device(struct usb_device
- if (udev->state == USB_STATE_NOTATTACHED)
- return -ENODEV;
-
--#ifdef CONFIG_USB_SUSPEND
- /* selective resume of one downstream hub-to-device port */
- if (udev->parent) {
-+#ifdef CONFIG_USB_SUSPEND
- if (udev->state == USB_STATE_SUSPENDED) {
- // NOTE swsusp may bork us, device state being wrong...
- // NOTE this fails if parent is also suspended...
-@@ -1887,8 +1893,8 @@ int usb_resume_device(struct usb_device
- udev->portnum, udev);
- } else
- status = 0;
-- } else
- #endif
-+ } else
- status = finish_device_resume(udev);
- if (status < 0)
- dev_dbg(&udev->dev, "can't resume, status %d\n",
diff --git a/usb/usb-rtl8150-small-fix.patch b/usb/usb-rtl8150-small-fix.patch
deleted file mode 100644
index ec92259f1ec0d..0000000000000
--- a/usb/usb-rtl8150-small-fix.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From petkan@nucleusys.com Wed Mar 15 06:29:32 2006
-Date: Wed, 15 Mar 2006 16:29:38 +0200 (EET)
-From: Petko Manolov <petkan@nucleusys.com>
-To: Greg KH <greg@kroah.com>
-Subject: USB: rtl8150 small fix
-Message-ID: <Pine.LNX.4.62.0603151626570.2354@localhost.localdomain>
-
-This one is about announcing the device registration after the last check
-has been made.
-
-From: Petko Manolov <petkan@nucleusys.com>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-
----
- drivers/usb/net/rtl8150.c | 4 +++-
- 1 file changed, 3 insertions(+), 1 deletion(-)
-
---- gregkh-2.6.orig/drivers/usb/net/rtl8150.c
-+++ gregkh-2.6/drivers/usb/net/rtl8150.c
-@@ -880,7 +880,6 @@ static int rtl8150_probe(struct usb_inte
- }
- fill_skb_pool(dev);
- set_ethernet_addr(dev);
-- info("%s: rtl8150 is detected", netdev->name);
-
- usb_set_intfdata(intf, dev);
- SET_NETDEV_DEV(netdev, &intf->dev);
-@@ -888,6 +887,9 @@ static int rtl8150_probe(struct usb_inte
- err("couldn't register the device");
- goto out2;
- }
-+
-+ info("%s: rtl8150 is detected", netdev->name);
-+
- return 0;
-
- out2:
diff --git a/usb/usb-sn9c10x-driver-updates.patch b/usb/usb-sn9c10x-driver-updates.patch
deleted file mode 100644
index d90c465bf5847..0000000000000
--- a/usb/usb-sn9c10x-driver-updates.patch
+++ /dev/null
@@ -1,1073 +0,0 @@
-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.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_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_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-storage-another-unusual_devs.h-entry.patch b/usb/usb-storage-another-unusual_devs.h-entry.patch
deleted file mode 100644
index 4008b1c66305e..0000000000000
--- a/usb/usb-storage-another-unusual_devs.h-entry.patch
+++ /dev/null
@@ -1,35 +0,0 @@
-From phil@ipom.com Sun Mar 5 21:43:46 2006
-Message-ID: <440BCC0C.1090103@ipom.com>
-Date: Sun, 05 Mar 2006 21:43:40 -0800
-From: Phil Dibowitz <phil@ipom.com>
-To: Greg KH <greg@kroah.com>, <chris@rebelbase.com>, <zaitcev@redhat.com>
-Subject: USB: storage: another unusual_devs.h entry
-
-From: Pete Zaitcev <zaitcev@redhat.com>
-
-Signed-off-by: Phil Dibowitz <phil@ipom.com>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-
----
- drivers/usb/storage/unusual_devs.h | 10 ++++++++++
- 1 file changed, 10 insertions(+)
-
---- gregkh-2.6.orig/drivers/usb/storage/unusual_devs.h
-+++ gregkh-2.6/drivers/usb/storage/unusual_devs.h
-@@ -1080,6 +1080,16 @@ UNUSUAL_DEV( 0x0c0b, 0xa109, 0x0000, 0xf
- 0),
- #endif
-
-+/*
-+ * Pete Zaitcev <zaitcev@yahoo.com>, bz#164688.
-+ * The device blatantly ignores LUN and returns 1 in GetMaxLUN.
-+ */
-+UNUSUAL_DEV( 0x0c45, 0x1060, 0x0100, 0x0100,
-+ "Unknown",
-+ "Unknown",
-+ US_SC_DEVICE, US_PR_DEVICE, NULL,
-+ US_FL_SINGLE_LUN ),
-+
- /* Submitted by Joris Struyve <joris@struyve.be> */
- UNUSUAL_DEV( 0x0d96, 0x410a, 0x0001, 0xffff,
- "Medion",
diff --git a/usb/usb-storage-new-unusual_devs.h-entry-mitsumi-7in1-card-reader.patch b/usb/usb-storage-new-unusual_devs.h-entry-mitsumi-7in1-card-reader.patch
deleted file mode 100644
index 7428f1225b8aa..0000000000000
--- a/usb/usb-storage-new-unusual_devs.h-entry-mitsumi-7in1-card-reader.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From stern@rowland.harvard.edu Mon Mar 6 07:45:50 2006
-Date: Mon, 6 Mar 2006 10:45:42 -0500 (EST)
-From: Alan Stern <stern@rowland.harvard.edu>
-To: Greg KH <greg@kroah.com>
-cc: "Rodolfo Quesada Z." <rquesada@eml.cc>, Phil Dibowitz <phil@ipom.com>
-Subject: USB: storage: new unusual_devs.h entry: Mitsumi 7in1 Card Reader
-Message-ID: <Pine.LNX.4.44L0.0603061042190.5142-100000@iolanthe.rowland.org>
-
-From: Rodolfo Quesada <rquesada@roqz.net>
-
-This patch (as661) adds an unusual_devs entry for the Mitsumi 7in1 Card
-Reader.
-
-From: Rodolfo Quesada <rquesada@roqz.net>
-Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-
----
- drivers/usb/storage/unusual_devs.h | 7 +++++++
- 1 file changed, 7 insertions(+)
-
---- gregkh-2.6.orig/drivers/usb/storage/unusual_devs.h
-+++ gregkh-2.6/drivers/usb/storage/unusual_devs.h
-@@ -62,6 +62,13 @@ UNUSUAL_DEV( 0x03ee, 0x6901, 0x0000, 0x
- US_SC_DEVICE, US_PR_DEVICE, NULL,
- US_FL_SINGLE_LUN ),
-
-+/* Reported by Rodolfo Quesada <rquesada@roqz.net> */
-+UNUSUAL_DEV( 0x03ee, 0x6906, 0x0003, 0x0003,
-+ "VIA Technologies Inc.",
-+ "Mitsumi multi cardreader",
-+ US_SC_DEVICE, US_PR_DEVICE, NULL,
-+ US_FL_IGNORE_RESIDUE ),
-+
- UNUSUAL_DEV( 0x03f0, 0x0107, 0x0200, 0x0200,
- "HP",
- "CD-Writer+",
diff --git a/usb/usb-storage-sandisk-unusual_devices-entry.patch b/usb/usb-storage-sandisk-unusual_devices-entry.patch
deleted file mode 100644
index 3f9895e62d20c..0000000000000
--- a/usb/usb-storage-sandisk-unusual_devices-entry.patch
+++ /dev/null
@@ -1,45 +0,0 @@
-From phil@ipom.com Sun Mar 5 21:36:56 2006
-Message-ID: <440BCA73.1050904@ipom.com>
-Date: Sun, 05 Mar 2006 21:36:51 -0800
-From: Phil Dibowitz <phil@ipom.com>
-To: Roman Hodek <roman@hodek.net>, Greg KH <greg@kroah.com>
-Subject: USB: storage: sandisk unusual_devices entry
-
-
-The following adds an unusual_devs entry for the SanDisk ImageMate CompactFlash
-USB drive, for the US_FL_FIX_CAPACITY flag. Additionally, it removes trailing
-whitespace from the previous entry. It's based on the patch sent by Roman Hodek
-<roman@hodek.net>.
-
-Signed-off-by: Phil Dibowitz <phil@ipom.com>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
----
-
-
----
- drivers/usb/storage/unusual_devs.h | 9 ++++++++-
- 1 file changed, 8 insertions(+), 1 deletion(-)
-
---- gregkh-2.6.orig/drivers/usb/storage/unusual_devs.h
-+++ gregkh-2.6/drivers/usb/storage/unusual_devs.h
-@@ -760,12 +760,19 @@ UNUSUAL_DEV( 0x069b, 0x3004, 0x0001, 0x
- US_SC_DEVICE, US_PR_DEVICE, NULL,
- US_FL_FIX_CAPACITY ),
-
--UNUSUAL_DEV( 0x0781, 0x0001, 0x0200, 0x0200,
-+/* Submitted by Roman Hodek <roman@hodek.net> */
-+UNUSUAL_DEV( 0x0781, 0x0001, 0x0200, 0x0200,
- "Sandisk",
- "ImageMate SDDR-05a",
- US_SC_SCSI, US_PR_CB, NULL,
- US_FL_SINGLE_LUN ),
-
-+UNUSUAL_DEV( 0x0781, 0x0002, 0x0009, 0x0009,
-+ "SanDisk Corporation",
-+ "ImageMate CompactFlash USB",
-+ US_SC_DEVICE, US_PR_DEVICE, NULL,
-+ US_FL_FIX_CAPACITY ),
-+
- #ifdef CONFIG_USB_STORAGE_USBAT
- UNUSUAL_DEV( 0x0781, 0x0005, 0x0005, 0x0005,
- "Sandisk",
diff --git a/usb/usb-storage-unusual_devs.h-entry-0420-0001.patch b/usb/usb-storage-unusual_devs.h-entry-0420-0001.patch
deleted file mode 100644
index 9aa41aae402c0..0000000000000
--- a/usb/usb-storage-unusual_devs.h-entry-0420-0001.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From phil@ipom.com Sun Mar 5 21:45:49 2006
-Message-ID: <440BCC88.4040001@ipom.com>
-Date: Sun, 05 Mar 2006 21:45:44 -0800
-From: Phil Dibowitz <phil@ipom.com>
-To: Greg KH <greg@kroah.com>, <zaitcev@redhat.com>, <chris@rebelbase.com>
-Subject: USB: storage: unusual_devs.h entry 0420:0001
-
-From: Pete Zaitcev <zaitcev@redhat.com>
-
-Ref
-https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=176584
-
-Signed-off-by: Phil Dibowitz <phil@ipom.com>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-
----
- drivers/usb/storage/unusual_devs.h | 6 ++++++
- 1 file changed, 6 insertions(+)
-
---- gregkh-2.6.orig/drivers/usb/storage/unusual_devs.h
-+++ gregkh-2.6/drivers/usb/storage/unusual_devs.h
-@@ -120,6 +120,12 @@ UNUSUAL_DEV( 0x0419, 0xaaf6, 0x0100, 0x
- US_SC_DEVICE, US_PR_DEVICE, NULL,
- US_FL_IGNORE_RESIDUE ),
-
-+/* Reported by Pete Zaitcev <zaitcev@redhat.com>, bz#176584 */
-+UNUSUAL_DEV( 0x0420, 0x0001, 0x0100, 0x0100,
-+ "GENERIC", "MP3 PLAYER", /* MyMusix PD-205 on the outside. */
-+ US_SC_DEVICE, US_PR_DEVICE, NULL,
-+ US_FL_IGNORE_RESIDUE ),
-+
- /* Reported by Olaf Hering <olh@suse.de> from novell bug #105878 */
- UNUSUAL_DEV( 0x0424, 0x0fdc, 0x0210, 0x0210,
- "SMSC",
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
deleted file mode 100644
index 043b322d58df9..0000000000000
--- a/usb/usb-support-for-usb-to-serial-cable-from-speed-dragon-multimedia.patch
+++ /dev/null
@@ -1,42 +0,0 @@
-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-ub-01-remove-first_open.patch b/usb/usb-ub-01-remove-first_open.patch
deleted file mode 100644
index 494b3f51bba3b..0000000000000
--- a/usb/usb-ub-01-remove-first_open.patch
+++ /dev/null
@@ -1,71 +0,0 @@
-From zaitcev@redhat.com Thu Mar 2 16:36:30 2006
-Date: Thu, 2 Mar 2006 16:36:09 -0800
-From: Pete Zaitcev <zaitcev@redhat.com>
-To: greg@kroah.com
-Cc: zaitcev@redhat.com, linux-usb-devel@lists.sourceforge.net
-Subject: USB: ub 01 remove first_open
-Message-Id: <20060302163609.21b4236a.zaitcev@redhat.com>
-
-The first_open was long overdue for removal, but I wanted to keep this
-separate for other changes in case of regressions.
-
-Signed-off-by: Pete Zaitcev <zaitcev@redhat.com>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-
----
- drivers/block/ub.c | 23 -----------------------
- 1 file changed, 23 deletions(-)
-
---- gregkh-2.6.orig/drivers/block/ub.c
-+++ gregkh-2.6/drivers/block/ub.c
-@@ -8,7 +8,6 @@
- * and is not licensed separately. See file COPYING for details.
- *
- * TODO (sorted by decreasing priority)
-- * -- Kill first_open (Al Viro fixed the block layer now)
- * -- set readonly flag for CDs, set removable flag for CF readers
- * -- do inquiry and verify we got a disk and not a tape (for LUN mismatch)
- * -- special case some senses, e.g. 3a/0 -> no media present, reduce retries
-@@ -334,7 +333,6 @@ struct ub_lun {
- int changed; /* Media was changed */
- int removable;
- int readonly;
-- int first_open; /* Kludge. See ub_bd_open. */
-
- struct ub_request urq;
-
-@@ -1849,26 +1847,6 @@ static int ub_bd_open(struct inode *inod
- sc->openc++;
- spin_unlock_irqrestore(&ub_lock, flags);
-
-- /*
-- * This is a workaround for a specific problem in our block layer.
-- * In 2.6.9, register_disk duplicates the code from rescan_partitions.
-- * However, if we do add_disk with a device which persistently reports
-- * a changed media, add_disk calls register_disk, which does do_open,
-- * which will call rescan_paritions for changed media. After that,
-- * register_disk attempts to do it all again and causes double kobject
-- * registration and a eventually an oops on module removal.
-- *
-- * The bottom line is, Al Viro says that we should not allow
-- * bdev->bd_invalidated to be set when doing add_disk no matter what.
-- */
-- if (lun->first_open) {
-- lun->first_open = 0;
-- if (lun->changed) {
-- rc = -ENOMEDIUM;
-- goto err_open;
-- }
-- }
--
- if (lun->removable || lun->readonly)
- check_disk_change(inode->i_bdev);
-
-@@ -2537,7 +2515,6 @@ static int ub_probe_lun(struct ub_dev *s
-
- lun->removable = 1; /* XXX Query this from the device */
- lun->changed = 1; /* ub_revalidate clears only */
-- lun->first_open = 1;
- ub_revalidate(sc, lun);
-
- rc = -ENOMEM;
diff --git a/usb/usb-ub-02-remove-diag.patch b/usb/usb-ub-02-remove-diag.patch
deleted file mode 100644
index 85b976ec58830..0000000000000
--- a/usb/usb-ub-02-remove-diag.patch
+++ /dev/null
@@ -1,395 +0,0 @@
-From zaitcev@redhat.com Thu Mar 2 16:43:23 2006
-Date: Thu, 2 Mar 2006 16:42:59 -0800
-From: Pete Zaitcev <zaitcev@redhat.com>
-To: greg@kroah.com
-Cc: zaitcev@redhat.com, linux-usb-devel@lists.sourceforge.net, viro@www.linux.org.uk
-Subject: USB: ub 02 remove diag
-Message-Id: <20060302164259.095ab85b.zaitcev@redhat.com>
-
-Remove the "diag" file from the sysfs. The usbmon is good enough these days
-so I do not need this feature anymore. Also, sysfs is a pain. Al Viro caught
-a race in this, which I thought too bothersome to fix.
-
-Signed-off-by: Pete Zaitcev <zaitcev@redhat.com>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-
----
- drivers/block/ub.c | 197 +----------------------------------------------------
- 1 file changed, 4 insertions(+), 193 deletions(-)
-
---- gregkh-2.6.orig/drivers/block/ub.c
-+++ gregkh-2.6/drivers/block/ub.c
-@@ -180,6 +180,7 @@ struct ub_dev;
- #define UB_DIR_ILLEGAL2 2
- #define UB_DIR_WRITE 3
-
-+/* P3 */
- #define UB_DIR_CHAR(c) (((c)==UB_DIR_WRITE)? 'w': \
- (((c)==UB_DIR_READ)? 'r': 'n'))
-
-@@ -195,24 +196,11 @@ enum ub_scsi_cmd_state {
- UB_CMDST_DONE /* Final state */
- };
-
--static char *ub_scsi_cmd_stname[] = {
-- ". ",
-- "Cmd",
-- "dat",
-- "c2s",
-- "sts",
-- "clr",
-- "crs",
-- "Sen",
-- "fin"
--};
--
- struct ub_scsi_cmd {
- unsigned char cdb[UB_MAX_CDB_SIZE];
- unsigned char cdb_len;
-
- unsigned char dir; /* 0 - none, 1 - read, 3 - write. */
-- unsigned char trace_index;
- enum ub_scsi_cmd_state state;
- unsigned int tag;
- struct ub_scsi_cmd *next;
-@@ -249,28 +237,6 @@ struct ub_capacity {
- };
-
- /*
-- * The SCSI command tracing structure.
-- */
--
--#define SCMD_ST_HIST_SZ 8
--#define SCMD_TRACE_SZ 63 /* Less than 4KB of 61-byte lines */
--
--struct ub_scsi_cmd_trace {
-- int hcur;
-- unsigned int tag;
-- unsigned int req_size, act_size;
-- unsigned char op;
-- unsigned char dir;
-- unsigned char key, asc, ascq;
-- char st_hst[SCMD_ST_HIST_SZ];
--};
--
--struct ub_scsi_trace {
-- int cur;
-- struct ub_scsi_cmd_trace vec[SCMD_TRACE_SZ];
--};
--
--/*
- * This is a direct take-off from linux/include/completion.h
- * The difference is that I do not wait on this thing, just poll.
- * When I want to wait (ub_probe), I just use the stock completion.
-@@ -388,7 +354,6 @@ struct ub_dev {
- wait_queue_head_t reset_wait;
-
- int sg_stat[6];
-- struct ub_scsi_trace tr;
- };
-
- /*
-@@ -458,137 +423,6 @@ static int ub_qlock_next = 0;
- static DEFINE_SPINLOCK(ub_lock); /* Locks globals and ->openc */
-
- /*
-- * The SCSI command tracing procedures.
-- */
--
--static void ub_cmdtr_new(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
--{
-- int n;
-- struct ub_scsi_cmd_trace *t;
--
-- if ((n = sc->tr.cur + 1) == SCMD_TRACE_SZ) n = 0;
-- t = &sc->tr.vec[n];
--
-- memset(t, 0, sizeof(struct ub_scsi_cmd_trace));
-- t->tag = cmd->tag;
-- t->op = cmd->cdb[0];
-- t->dir = cmd->dir;
-- t->req_size = cmd->len;
-- t->st_hst[0] = cmd->state;
--
-- sc->tr.cur = n;
-- cmd->trace_index = n;
--}
--
--static void ub_cmdtr_state(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
--{
-- int n;
-- struct ub_scsi_cmd_trace *t;
--
-- t = &sc->tr.vec[cmd->trace_index];
-- if (t->tag == cmd->tag) {
-- if ((n = t->hcur + 1) == SCMD_ST_HIST_SZ) n = 0;
-- t->st_hst[n] = cmd->state;
-- t->hcur = n;
-- }
--}
--
--static void ub_cmdtr_act_len(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
--{
-- struct ub_scsi_cmd_trace *t;
--
-- t = &sc->tr.vec[cmd->trace_index];
-- if (t->tag == cmd->tag)
-- t->act_size = cmd->act_len;
--}
--
--static void ub_cmdtr_sense(struct ub_dev *sc, struct ub_scsi_cmd *cmd,
-- unsigned char *sense)
--{
-- struct ub_scsi_cmd_trace *t;
--
-- t = &sc->tr.vec[cmd->trace_index];
-- if (t->tag == cmd->tag) {
-- t->key = sense[2] & 0x0F;
-- t->asc = sense[12];
-- t->ascq = sense[13];
-- }
--}
--
--static ssize_t ub_diag_show(struct device *dev, struct device_attribute *attr,
-- char *page)
--{
-- struct usb_interface *intf;
-- struct ub_dev *sc;
-- struct list_head *p;
-- struct ub_lun *lun;
-- int cnt;
-- unsigned long flags;
-- int nc, nh;
-- int i, j;
-- struct ub_scsi_cmd_trace *t;
--
-- intf = to_usb_interface(dev);
-- sc = usb_get_intfdata(intf);
-- if (sc == NULL)
-- return 0;
--
-- cnt = 0;
-- spin_lock_irqsave(sc->lock, flags);
--
-- cnt += sprintf(page + cnt,
-- "poison %d reset %d\n",
-- atomic_read(&sc->poison), sc->reset);
-- cnt += sprintf(page + cnt,
-- "qlen %d qmax %d\n",
-- sc->cmd_queue.qlen, sc->cmd_queue.qmax);
-- cnt += sprintf(page + cnt,
-- "sg %d %d %d %d %d .. %d\n",
-- sc->sg_stat[0],
-- sc->sg_stat[1],
-- sc->sg_stat[2],
-- sc->sg_stat[3],
-- sc->sg_stat[4],
-- sc->sg_stat[5]);
--
-- list_for_each (p, &sc->luns) {
-- lun = list_entry(p, struct ub_lun, link);
-- cnt += sprintf(page + cnt,
-- "lun %u changed %d removable %d readonly %d\n",
-- lun->num, lun->changed, lun->removable, lun->readonly);
-- }
--
-- if ((nc = sc->tr.cur + 1) == SCMD_TRACE_SZ) nc = 0;
-- for (j = 0; j < SCMD_TRACE_SZ; j++) {
-- t = &sc->tr.vec[nc];
--
-- cnt += sprintf(page + cnt, "%08x %02x", t->tag, t->op);
-- if (t->op == REQUEST_SENSE) {
-- cnt += sprintf(page + cnt, " [sense %x %02x %02x]",
-- t->key, t->asc, t->ascq);
-- } else {
-- cnt += sprintf(page + cnt, " %c", UB_DIR_CHAR(t->dir));
-- cnt += sprintf(page + cnt, " [%5d %5d]",
-- t->req_size, t->act_size);
-- }
-- if ((nh = t->hcur + 1) == SCMD_ST_HIST_SZ) nh = 0;
-- for (i = 0; i < SCMD_ST_HIST_SZ; i++) {
-- cnt += sprintf(page + cnt, " %s",
-- ub_scsi_cmd_stname[(int)t->st_hst[nh]]);
-- if (++nh == SCMD_ST_HIST_SZ) nh = 0;
-- }
-- cnt += sprintf(page + cnt, "\n");
--
-- if (++nc == SCMD_TRACE_SZ) nc = 0;
-- }
--
-- spin_unlock_irqrestore(sc->lock, flags);
-- return cnt;
--}
--
--static DEVICE_ATTR(diag, S_IRUGO, ub_diag_show, NULL); /* N.B. World readable */
--
--/*
- * The id allocator.
- *
- * This also stores the host for indexing by minor, which is somewhat dirty.
-@@ -1090,7 +924,6 @@ static int ub_scsi_cmd_start(struct ub_d
- add_timer(&sc->work_timer);
-
- cmd->state = UB_CMDST_CMD;
-- ub_cmdtr_state(sc, cmd);
- return 0;
- }
-
-@@ -1143,12 +976,10 @@ static void ub_scsi_dispatch(struct ub_d
- ub_cmdq_pop(sc);
- (*cmd->done)(sc, cmd);
- } else if (cmd->state == UB_CMDST_INIT) {
-- ub_cmdtr_new(sc, cmd);
- if ((rc = ub_scsi_cmd_start(sc, cmd)) == 0)
- break;
- cmd->error = rc;
- cmd->state = UB_CMDST_DONE;
-- ub_cmdtr_state(sc, cmd);
- } else {
- if (!ub_is_completed(&sc->work_done))
- break;
-@@ -1245,7 +1076,6 @@ static void ub_scsi_urb_compl(struct ub_
- return;
- }
- cmd->state = UB_CMDST_CLEAR;
-- ub_cmdtr_state(sc, cmd);
- return;
- case -ESHUTDOWN: /* unplug */
- case -EILSEQ: /* unplug timeout on uhci */
-@@ -1277,7 +1107,6 @@ static void ub_scsi_urb_compl(struct ub_
- return;
- }
- cmd->state = UB_CMDST_CLR2STS;
-- ub_cmdtr_state(sc, cmd);
- return;
- }
- if (urb->status == -EOVERFLOW) {
-@@ -1302,7 +1131,6 @@ static void ub_scsi_urb_compl(struct ub_
- if (urb->status != 0 ||
- len != cmd->sgv[cmd->current_sg].length) {
- cmd->act_len += len;
-- ub_cmdtr_act_len(sc, cmd);
-
- cmd->error = -EIO;
- ub_state_stat(sc, cmd);
-@@ -1329,7 +1157,6 @@ static void ub_scsi_urb_compl(struct ub_
- }
-
- cmd->act_len += urb->actual_length;
-- ub_cmdtr_act_len(sc, cmd);
-
- if (++cmd->current_sg < cmd->nsg) {
- ub_data_start(sc, cmd);
-@@ -1355,7 +1182,6 @@ static void ub_scsi_urb_compl(struct ub_
- cmd->error = -EIO; /* A cheap trick... */
-
- cmd->state = UB_CMDST_CLRRS;
-- ub_cmdtr_state(sc, cmd);
- return;
- }
-
-@@ -1439,7 +1265,6 @@ static void ub_scsi_urb_compl(struct ub_
- return;
- }
- cmd->state = UB_CMDST_DONE;
-- ub_cmdtr_state(sc, cmd);
- ub_cmdq_pop(sc);
- (*cmd->done)(sc, cmd);
-
-@@ -1494,7 +1319,6 @@ static void ub_data_start(struct ub_dev
- add_timer(&sc->work_timer);
-
- cmd->state = UB_CMDST_DATA;
-- ub_cmdtr_state(sc, cmd);
- }
-
- /*
-@@ -1506,7 +1330,6 @@ static void ub_state_done(struct ub_dev
-
- cmd->error = rc;
- cmd->state = UB_CMDST_DONE;
-- ub_cmdtr_state(sc, cmd);
- ub_cmdq_pop(sc);
- (*cmd->done)(sc, cmd);
- }
-@@ -1552,7 +1375,6 @@ static void ub_state_stat(struct ub_dev
-
- cmd->stat_count = 0;
- cmd->state = UB_CMDST_STAT;
-- ub_cmdtr_state(sc, cmd);
- }
-
- /*
-@@ -1571,7 +1393,6 @@ static void ub_state_stat_counted(struct
- return;
-
- cmd->state = UB_CMDST_STAT;
-- ub_cmdtr_state(sc, cmd);
- }
-
- /*
-@@ -1609,7 +1430,6 @@ static void ub_state_sense(struct ub_dev
- scmd->tag = sc->tagcnt++;
-
- cmd->state = UB_CMDST_SENSE;
-- ub_cmdtr_state(sc, cmd);
-
- ub_cmdq_insert(sc, scmd);
- return;
-@@ -1666,11 +1486,6 @@ static void ub_top_sense_done(struct ub_
- struct ub_scsi_cmd *cmd;
-
- /*
-- * Ignoring scmd->act_len, because the buffer was pre-zeroed.
-- */
-- ub_cmdtr_sense(sc, scmd, sense);
--
-- /*
- * Find the command which triggered the unit attention or a check,
- * save the sense into it, and advance its state machine.
- */
-@@ -1691,6 +1506,9 @@ static void ub_top_sense_done(struct ub_
- return;
- }
-
-+ /*
-+ * Ignoring scmd->act_len, because the buffer was pre-zeroed.
-+ */
- cmd->key = sense[2] & 0x0F;
- cmd->asc = sense[12];
- cmd->ascq = sense[13];
-@@ -2413,9 +2231,6 @@ static int ub_probe(struct usb_interface
- if (ub_get_pipes(sc, sc->dev, intf) != 0)
- goto err_dev_desc;
-
-- if (device_create_file(&sc->intf->dev, &dev_attr_diag) != 0)
-- goto err_diag;
--
- /*
- * At this point, all USB initialization is done, do upper layer.
- * We really hate halfway initialized structures, so from the
-@@ -2480,8 +2295,6 @@ static int ub_probe(struct usb_interface
- }
- return 0;
-
-- /* device_remove_file(&sc->intf->dev, &dev_attr_diag); */
--err_diag:
- err_dev_desc:
- usb_set_intfdata(intf, NULL);
- // usb_put_intf(sc->intf);
-@@ -2609,7 +2422,6 @@ static void ub_disconnect(struct usb_int
- while ((cmd = ub_cmdq_peek(sc)) != NULL) {
- cmd->error = -ENOTCONN;
- cmd->state = UB_CMDST_DONE;
-- ub_cmdtr_state(sc, cmd);
- ub_cmdq_pop(sc);
- (*cmd->done)(sc, cmd);
- cnt++;
-@@ -2660,7 +2472,6 @@ static void ub_disconnect(struct usb_int
- * and no URBs left in transit.
- */
-
-- device_remove_file(&sc->intf->dev, &dev_attr_diag);
- usb_set_intfdata(intf, NULL);
- // usb_put_intf(sc->intf);
- sc->intf = NULL;
diff --git a/usb/usb-ub-03-drop-stall-clearing.patch b/usb/usb-ub-03-drop-stall-clearing.patch
deleted file mode 100644
index 8f98647bb621b..0000000000000
--- a/usb/usb-ub-03-drop-stall-clearing.patch
+++ /dev/null
@@ -1,45 +0,0 @@
-From zaitcev@redhat.com Thu Mar 2 16:53:17 2006
-Date: Thu, 2 Mar 2006 16:53:00 -0800
-From: Pete Zaitcev <zaitcev@redhat.com>
-To: greg@kroah.com
-Cc: zaitcev@redhat.com, linux-usb-devel@lists.sourceforge.net
-Subject: USB: ub 03 drop stall clearing
-Message-Id: <20060302165300.211eb11c.zaitcev@redhat.com>
-
-Matt mentioned that a very old ZIP-100 actually does need this, but I am
-yet to see anyone who actually has one still working and uses ub with it.
-He/she must be a retrocomputing geek, who can easily bias it to usb-storage
-with libusual, if needed. Meanwhile, common folks have trouble with poorly
-designed USB keys and some el-cheapo European music players. I think we
-better drop this for now.
-
-Signed-off-by: Pete Zaitcev <zaitcev@redhat.com>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-
----
- drivers/block/ub.c | 13 +------------
- 1 file changed, 1 insertion(+), 12 deletions(-)
-
---- gregkh-2.6.orig/drivers/block/ub.c
-+++ gregkh-2.6/drivers/block/ub.c
-@@ -2270,19 +2270,8 @@ static int ub_probe(struct usb_interface
-
- nluns = 1;
- for (i = 0; i < 3; i++) {
-- if ((rc = ub_sync_getmaxlun(sc)) < 0) {
-- /*
-- * This segment is taken from usb-storage. They say
-- * that ZIP-100 needs this, but my own ZIP-100 works
-- * fine without this.
-- * Still, it does not seem to hurt anything.
-- */
-- if (rc == -EPIPE) {
-- ub_probe_clear_stall(sc, sc->recv_bulk_pipe);
-- ub_probe_clear_stall(sc, sc->send_bulk_pipe);
-- }
-+ if ((rc = ub_sync_getmaxlun(sc)) < 0)
- break;
-- }
- if (rc != 0) {
- nluns = rc;
- break;
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
deleted file mode 100644
index 5058539a7913f..0000000000000
--- a/usb/usb-uhci-increase-port-reset-completion-delay-for-hp-controllers.patch
+++ /dev/null
@@ -1,59 +0,0 @@
-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-usbcore-don-t-assume-a-usb-configuration-includes-any-interfaces.patch b/usb/usb-usbcore-don-t-assume-a-usb-configuration-includes-any-interfaces.patch
deleted file mode 100644
index 8728992353852..0000000000000
--- a/usb/usb-usbcore-don-t-assume-a-usb-configuration-includes-any-interfaces.patch
+++ /dev/null
@@ -1,66 +0,0 @@
-From stern@rowland.harvard.edu Wed Mar 8 12:14:14 2006
-Date: Wed, 8 Mar 2006 15:14:09 -0500 (EST)
-From: Alan Stern <stern@rowland.harvard.edu>
-To: David Brownell <david-b@pacbell.net>
-cc: Greg KH <greg@kroah.com>, Andrew Morton <akpm@osdl.org>, Linus Torvalds <torvalds@osdl.org>, <mingo@elte.hu>
-Subject: USB: usbcore: Don't assume a USB configuration includes any interfaces
-Message-ID: <Pine.LNX.4.44L0.0603081509100.5360-100000@iolanthe.rowland.org>
-
-In a couple of places, usbcore assumes that a USB device configuration
-will have a nonzero number of interfaces. Having no interfaces may or
-may not be allowed by the USB spec; in any event we shouldn't die if we
-encounter such a thing. This patch (as662) removes the assumptions.
-
-Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-
----
- drivers/usb/core/hub.c | 16 ++++++++++------
- 1 file changed, 10 insertions(+), 6 deletions(-)
-
---- gregkh-2.6.orig/drivers/usb/core/hub.c
-+++ gregkh-2.6/drivers/usb/core/hub.c
-@@ -1179,8 +1179,11 @@ static int choose_configuration(struct u
- c = udev->config;
- num_configs = udev->descriptor.bNumConfigurations;
- for (i = 0; i < num_configs; (i++, c++)) {
-- struct usb_interface_descriptor *desc =
-- &c->intf_cache[0]->altsetting->desc;
-+ struct usb_interface_descriptor *desc = NULL;
-+
-+ /* It's possible that a config has no interfaces! */
-+ if (c->desc.bNumInterfaces > 0)
-+ desc = &c->intf_cache[0]->altsetting->desc;
-
- /*
- * HP's USB bus-powered keyboard has only one configuration
-@@ -1215,7 +1218,8 @@ static int choose_configuration(struct u
- /* If the first config's first interface is COMM/2/0xff
- * (MSFT RNDIS), rule it out unless Linux has host-side
- * RNDIS support. */
-- if (i == 0 && desc->bInterfaceClass == USB_CLASS_COMM
-+ if (i == 0 && desc
-+ && desc->bInterfaceClass == USB_CLASS_COMM
- && desc->bInterfaceSubClass == 2
- && desc->bInterfaceProtocol == 0xff) {
- #ifndef CONFIG_USB_NET_RNDIS
-@@ -1231,8 +1235,8 @@ static int choose_configuration(struct u
- * than a vendor-specific driver. */
- else if (udev->descriptor.bDeviceClass !=
- USB_CLASS_VENDOR_SPEC &&
-- desc->bInterfaceClass !=
-- USB_CLASS_VENDOR_SPEC) {
-+ (!desc || desc->bInterfaceClass !=
-+ USB_CLASS_VENDOR_SPEC)) {
- best = c;
- break;
- }
-@@ -3024,7 +3028,7 @@ int usb_reset_device(struct usb_device *
- parent_hub = hdev_to_hub(parent_hdev);
-
- /* If we're resetting an active hub, take some special actions */
-- if (udev->actconfig &&
-+ if (udev->actconfig && udev->actconfig->desc.bNumInterfaces > 0 &&
- udev->actconfig->interface[0]->dev.driver ==
- &hub_driver.driver &&
- (hub = hdev_to_hub(udev)) != NULL) {
diff --git a/usb/usb-usbcore-sets-up-root-hubs-earlier.patch b/usb/usb-usbcore-sets-up-root-hubs-earlier.patch
deleted file mode 100644
index 487b93a213bec..0000000000000
--- a/usb/usb-usbcore-sets-up-root-hubs-earlier.patch
+++ /dev/null
@@ -1,198 +0,0 @@
-From david-b@pacbell.net Mon Jan 23 16:29:38 2006
-From: David Brownell <david-b@pacbell.net>
-To: Greg KH <greg@kroah.com>
-Subject: USB: usbcore sets up root hubs earlier
-Date: Mon, 23 Jan 2006 15:25:40 -0800
-Message-Id: <200601231525.41094.david-b@pacbell.net>
-
-Make the HCD initialization sequence more sane ... notably, setting up
-root hubs before HCDs are asked to do their one-time init. Among other
-things, that lets the HCDs do custom root hub init along with all the
-other one-time initialization done in the (now misnamed) reset() method.
-
-This also copies the controller wakeup flags into the root hub; it's
-done a bit later than would be ideal, but that'll be necessary until
-the PCI code initializes them correctly. (The PCI patch breaks on PPC
-due to how it sequences PCI initialization.)
-
-Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-
----
- drivers/usb/core/hcd.c | 104 +++++++++++++++++++++++++------------------------
- 1 file changed, 55 insertions(+), 49 deletions(-)
-
---- gregkh-2.6.orig/drivers/usb/core/hcd.c
-+++ gregkh-2.6/drivers/usb/core/hcd.c
-@@ -823,18 +823,17 @@ static void usb_deregister_bus (struct u
-
- /**
- * register_root_hub - called by usb_add_hcd() to register a root hub
-- * @usb_dev: the usb root hub device to be registered.
- * @hcd: host controller for this root hub
- *
- * This function registers the root hub with the USB subsystem. It sets up
-- * the device properly in the device tree and stores the root_hub pointer
-- * in the bus structure, then calls usb_new_device() to register the usb
-- * device. It also assigns the root hub's USB address (always 1).
-+ * the device properly in the device tree and then calls usb_new_device()
-+ * to register the usb device. It also assigns the root hub's USB address
-+ * (always 1).
- */
--static int register_root_hub (struct usb_device *usb_dev,
-- struct usb_hcd *hcd)
-+static int register_root_hub(struct usb_hcd *hcd)
- {
- struct device *parent_dev = hcd->self.controller;
-+ struct usb_device *usb_dev = hcd->self.root_hub;
- const int devnum = 1;
- int retval;
-
-@@ -846,12 +845,10 @@ static int register_root_hub (struct usb
- usb_set_device_state(usb_dev, USB_STATE_ADDRESS);
-
- mutex_lock(&usb_bus_list_lock);
-- usb_dev->bus->root_hub = usb_dev;
-
- usb_dev->ep0.desc.wMaxPacketSize = __constant_cpu_to_le16(64);
- retval = usb_get_device_descriptor(usb_dev, USB_DT_DEVICE_SIZE);
- if (retval != sizeof usb_dev->descriptor) {
-- usb_dev->bus->root_hub = NULL;
- mutex_unlock(&usb_bus_list_lock);
- dev_dbg (parent_dev, "can't read %s device descriptor %d\n",
- usb_dev->dev.bus_id, retval);
-@@ -860,7 +857,6 @@ static int register_root_hub (struct usb
-
- retval = usb_new_device (usb_dev);
- if (retval) {
-- usb_dev->bus->root_hub = NULL;
- dev_err (parent_dev, "can't register root hub for %s, %d\n",
- usb_dev->dev.bus_id, retval);
- }
-@@ -1772,12 +1768,10 @@ int usb_add_hcd(struct usb_hcd *hcd,
-
- set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
-
-- /* till now HC has been in an indeterminate state ... */
-- if (hcd->driver->reset && (retval = hcd->driver->reset(hcd)) < 0) {
-- dev_err(hcd->self.controller, "can't reset\n");
-- return retval;
-- }
--
-+ /* HC is in reset state, but accessible. Now do the one-time init,
-+ * bottom up so that hcds can customize the root hubs before khubd
-+ * starts talking to them. (Note, bus id is assigned early too.)
-+ */
- if ((retval = hcd_buffer_create(hcd)) != 0) {
- dev_dbg(hcd->self.controller, "pool alloc failed\n");
- return retval;
-@@ -1786,6 +1780,42 @@ int usb_add_hcd(struct usb_hcd *hcd,
- if ((retval = usb_register_bus(&hcd->self)) < 0)
- goto err_register_bus;
-
-+ if ((rhdev = usb_alloc_dev(NULL, &hcd->self, 0)) == NULL) {
-+ dev_err(hcd->self.controller, "unable to allocate root hub\n");
-+ retval = -ENOMEM;
-+ goto err_allocate_root_hub;
-+ }
-+ rhdev->speed = (hcd->driver->flags & HCD_USB2) ? USB_SPEED_HIGH :
-+ USB_SPEED_FULL;
-+ hcd->self.root_hub = rhdev;
-+
-+ /* "reset" is misnamed; its role is now one-time init. the controller
-+ * should already have been reset (and boot firmware kicked off etc).
-+ */
-+ if (hcd->driver->reset && (retval = hcd->driver->reset(hcd)) < 0) {
-+ dev_err(hcd->self.controller, "can't setup\n");
-+ goto err_hcd_driver_setup;
-+ }
-+
-+ /* wakeup flag init is in transition; for now we can't rely on PCI to
-+ * initialize these bits properly, so we let reset() override it.
-+ * This init should _precede_ the reset() once PCI behaves.
-+ */
-+ device_init_wakeup(&rhdev->dev,
-+ device_can_wakeup(hcd->self.controller));
-+
-+ // ... all these hcd->*_wakeup flags will vanish
-+ hcd->can_wakeup = device_can_wakeup(hcd->self.controller);
-+
-+ /* hcd->driver->reset() reported can_wakeup, probably with
-+ * assistance from board's boot firmware.
-+ * NOTE: normal devices won't enable wakeup by default.
-+ */
-+ if (hcd->can_wakeup)
-+ dev_dbg(hcd->self.controller, "supports USB remote wakeup\n");
-+ hcd->remote_wakeup = hcd->can_wakeup;
-+
-+ /* enable irqs just before we start the controller */
- if (hcd->driver->irq) {
- char buf[8], *bufp = buf;
-
-@@ -1817,56 +1847,32 @@ int usb_add_hcd(struct usb_hcd *hcd,
- (unsigned long long)hcd->rsrc_start);
- }
-
-- /* Allocate the root hub before calling hcd->driver->start(),
-- * but don't register it until afterward so that the hardware
-- * is running.
-- */
-- if ((rhdev = usb_alloc_dev(NULL, &hcd->self, 0)) == NULL) {
-- dev_err(hcd->self.controller, "unable to allocate root hub\n");
-- retval = -ENOMEM;
-- goto err_allocate_root_hub;
-- }
--
-- /* Although in principle hcd->driver->start() might need to use rhdev,
-- * none of the current drivers do.
-- */
- if ((retval = hcd->driver->start(hcd)) < 0) {
- dev_err(hcd->self.controller, "startup error %d\n", retval);
- goto err_hcd_driver_start;
- }
-
-- /* hcd->driver->start() reported can_wakeup, probably with
-- * assistance from board's boot firmware.
-- * NOTE: normal devices won't enable wakeup by default.
-- */
-- if (hcd->can_wakeup)
-- dev_dbg(hcd->self.controller, "supports USB remote wakeup\n");
-- hcd->remote_wakeup = hcd->can_wakeup;
--
-- rhdev->speed = (hcd->driver->flags & HCD_USB2) ? USB_SPEED_HIGH :
-- USB_SPEED_FULL;
-+ /* starting here, usbcore will pay attention to this root hub */
- rhdev->bus_mA = min(500u, hcd->power_budget);
-- if ((retval = register_root_hub(rhdev, hcd)) != 0)
-+ if ((retval = register_root_hub(hcd)) != 0)
- goto err_register_root_hub;
-
- if (hcd->uses_new_polling && hcd->poll_rh)
- usb_hcd_poll_rh_status(hcd);
- return retval;
-
-- err_register_root_hub:
-+err_register_root_hub:
- hcd->driver->stop(hcd);
--
-- err_hcd_driver_start:
-- usb_put_dev(rhdev);
--
-- err_allocate_root_hub:
-+err_hcd_driver_start:
- if (hcd->irq >= 0)
- free_irq(irqnum, hcd);
--
-- err_request_irq:
-+err_request_irq:
-+err_hcd_driver_setup:
-+ hcd->self.root_hub = NULL;
-+ usb_put_dev(rhdev);
-+err_allocate_root_hub:
- usb_deregister_bus(&hcd->self);
--
-- err_register_bus:
-+err_register_bus:
- hcd_buffer_destroy(hcd);
- return retval;
- }
diff --git a/usb/usb-usbcore-usb_set_configuration-oops.patch b/usb/usb-usbcore-usb_set_configuration-oops.patch
deleted file mode 100644
index 057dfe1016baa..0000000000000
--- a/usb/usb-usbcore-usb_set_configuration-oops.patch
+++ /dev/null
@@ -1,43 +0,0 @@
-From horst@schirmeier.com Thu Mar 9 05:10:56 2006
-Date: Thu, 9 Mar 2006 14:10:49 +0100
-From: Horst Schirmeier <horst@schirmeier.com>
-To: Alan Stern <stern@rowland.harvard.edu>
-Cc: Greg KH <greg@kroah.com>
-Subject: USB: usbcore: usb_set_configuration oops (NULL ptr dereference)
-Message-ID: <20060309131048.GL22994@quickstop.soohrt.org>
-Content-Disposition: inline
-
-When trying to deconfigure a device via usb_set_configuration(dev, 0),
-2.6.16-rc kernels after 55c527187c9d78f840b284d596a0b298bc1493af oops
-with "Unable to handle NULL pointer dereference at...". This is due to
-an unchecked dereference of cp in the power budget part.
-
-Signed-off-by: Horst Schirmeier <horst@schirmeier.com>
-Acked-by: Alan Stern <stern@rowland.harvard.edu>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-
----
- drivers/usb/core/message.c | 12 +++++++-----
- 1 file changed, 7 insertions(+), 5 deletions(-)
-
---- gregkh-2.6.orig/drivers/usb/core/message.c
-+++ gregkh-2.6/drivers/usb/core/message.c
-@@ -1388,11 +1388,13 @@ free_interfaces:
- if (dev->state != USB_STATE_ADDRESS)
- usb_disable_device (dev, 1); // Skip ep0
-
-- i = dev->bus_mA - cp->desc.bMaxPower * 2;
-- if (i < 0)
-- dev_warn(&dev->dev, "new config #%d exceeds power "
-- "limit by %dmA\n",
-- configuration, -i);
-+ if (cp) {
-+ i = dev->bus_mA - cp->desc.bMaxPower * 2;
-+ if (i < 0)
-+ dev_warn(&dev->dev, "new config #%d exceeds power "
-+ "limit by %dmA\n",
-+ configuration, -i);
-+ }
-
- if ((ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
- USB_REQ_SET_CONFIGURATION, 0, configuration, 0,
diff --git a/usb/usb-vicam.c-fix-a-null-pointer-dereference.patch b/usb/usb-vicam.c-fix-a-null-pointer-dereference.patch
deleted file mode 100644
index de4e31540d7cf..0000000000000
--- a/usb/usb-vicam.c-fix-a-null-pointer-dereference.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From bunk@stusta.de Fri Mar 10 14:25:09 2006
-Date: Fri, 10 Mar 2006 23:25:06 +0100
-From: Adrian Bunk <bunk@stusta.de>
-To: gregkh@suse.de
-Subject: USB: vicam.c: fix a NULL pointer dereference
-Message-ID: <20060310222506.GA21864@stusta.de>
-Content-Disposition: inline
-
-This patch fixes a NULL pointer dereference spotted by the Coverity
-checker.
-
-
-Signed-off-by: Adrian Bunk <bunk@stusta.de>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-
----
- drivers/usb/media/vicam.c | 1 +
- 1 file changed, 1 insertion(+)
-
---- gregkh-2.6.orig/drivers/usb/media/vicam.c
-+++ gregkh-2.6/drivers/usb/media/vicam.c
-@@ -764,6 +764,7 @@ vicam_open(struct inode *inode, struct f
- if (!cam) {
- printk(KERN_ERR
- "vicam video_device improperly initialized");
-+ return -EINVAL;
- }
-
- /* the videodev_lock held above us protects us from
diff --git a/usb/usb-zc0301-driver-bugfix.patch b/usb/usb-zc0301-driver-bugfix.patch
deleted file mode 100644
index 4879273b81f06..0000000000000
--- a/usb/usb-zc0301-driver-bugfix.patch
+++ /dev/null
@@ -1,111 +0,0 @@
-From luca.risolia@studio.unibo.it Fri Mar 3 00:56:06 2006
-Date: Fri, 3 Mar 2006 09:58:39 +0000
-From: Luca Risolia <luca.risolia@studio.unibo.it>
-To: Greg Kroah-Hartman <gregkh@suse.de>
-Subject: USB: ZC0301 driver bugfix
-Message-ID: <20060303095839.GA3857@studio.unibo.it>
-Content-Disposition: inline
-
-ZC0301 driver bugfix.
-
-Use correct PID/VID USB entries.
-
-Signed-off-by: Luca Risolia <luca.risolia@studio.unibo.it>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-
----
- Documentation/usb/zc0301.txt | 12 ++++++------
- drivers/usb/media/zc0301.h | 5 +----
- drivers/usb/media/zc0301_core.c | 6 +++---
- drivers/usb/media/zc0301_sensor.h | 12 ++++++------
- 4 files changed, 16 insertions(+), 19 deletions(-)
-
---- gregkh-2.6.orig/Documentation/usb/zc0301.txt
-+++ gregkh-2.6/Documentation/usb/zc0301.txt
-@@ -201,14 +201,14 @@ devices mounting the ZC0301 Image Proces
-
- Vendor ID Product ID
- --------- ----------
--0x10fd 0x8050
--0x041e 0x0417
--0x041e 0x041e
--0x041e 0x081c
--0x041e 0x0834
--0x041e 0x0835
-+0x041e 0x4017
-+0x041e 0x401c
-+0x041e 0x401e
-+0x041e 0x4034
-+0x041e 0x4035
- 0x046d 0x08ae
- 0x0ac8 0x0301
-+0x10fd 0x8050
-
- 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;
---- gregkh-2.6.orig/drivers/usb/media/zc0301.h
-+++ gregkh-2.6/drivers/usb/media/zc0301.h
-@@ -134,10 +134,7 @@ 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;
-+ return usb_match_id(usb_ifnum_to_if(cam->usbdev, 0), id) ? cam : NULL;
- }
-
- void
---- gregkh-2.6.orig/drivers/usb/media/zc0301_core.c
-+++ gregkh-2.6/drivers/usb/media/zc0301_core.c
-@@ -52,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.02"
--#define ZC0301_MODULE_VERSION_CODE KERNEL_VERSION(1, 0, 2)
-+#define ZC0301_MODULE_VERSION "1:1.03"
-+#define ZC0301_MODULE_VERSION_CODE KERNEL_VERSION(1, 0, 3)
-
- /*****************************************************************************/
-
-@@ -637,7 +637,6 @@ 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);
- }
-
-@@ -727,6 +726,7 @@ static int zc0301_release(struct inode*
-
- if (cam->state & DEV_DISCONNECTED) {
- zc0301_release_resources(cam);
-+ usb_put_dev(cam->usbdev);
- mutex_unlock(&cam->dev_mutex);
- kfree(cam);
- return 0;
---- gregkh-2.6.orig/drivers/usb/media/zc0301_sensor.h
-+++ gregkh-2.6/drivers/usb/media/zc0301_sensor.h
-@@ -58,14 +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(0x041e, 0x4017, 0xff), }, \
-+ { ZC0301_USB_DEVICE(0x041e, 0x401c, 0xff), }, /* PAS106 */ \
-+ { ZC0301_USB_DEVICE(0x041e, 0x401e, 0xff), }, /* HV7131B */ \
-+ { ZC0301_USB_DEVICE(0x041e, 0x4034, 0xff), }, /* PAS106 */ \
-+ { ZC0301_USB_DEVICE(0x041e, 0x4035, 0xff), }, /* PAS106 */ \
- { ZC0301_USB_DEVICE(0x046d, 0x08ae, 0xff), }, /* PAS202BCB */ \
- { ZC0301_USB_DEVICE(0x0ac8, 0x0301, 0xff), }, \
-+ { ZC0301_USB_DEVICE(0x10fd, 0x8050, 0xff), }, /* TAS5130D */ \
- { } \
- };
-
diff --git a/usb/usb-zc0301-driver-updates-2.patch b/usb/usb-zc0301-driver-updates-2.patch
deleted file mode 100644
index f64108145e65a..0000000000000
--- a/usb/usb-zc0301-driver-updates-2.patch
+++ /dev/null
@@ -1,496 +0,0 @@
-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.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_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_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];
diff --git a/usb/usb-zc0301-driver-updates.patch b/usb/usb-zc0301-driver-updates.patch
deleted file mode 100644
index 7450846719b59..0000000000000
--- a/usb/usb-zc0301-driver-updates.patch
+++ /dev/null
@@ -1,214 +0,0 @@
-From luca.risolia@studio.unibo.it Tue Feb 7 15:03:45 2006
-Date: Wed, 8 Feb 2006 00:05:27 +0000
-From: Luca Risolia <luca.risolia@studio.unibo.it>
-To: Greg Kroah-Hartman <gregkh@suse.de>
-Cc: Andrew Morton <akpm@osdl.org>
-Subject: USB: ZC0301 driver updates
-Message-ID: <20060208000527.GA10310@studio.unibo.it>
-Content-Disposition: inline
-
-"Cosmetic" driver updates for the ZC0301 driver:
-
-- Fix stream_interrupt() (and work around a possible kernel bug);
-
-- Fix vidioc_enum_input() and split vidioc_gs_input() in two parts;
-- Use wait_event_interruptible_timeout() instead of wait_event_interruptible()
- when waiting for video frames;
-- replace erroneous wake_up_interruptible(&wait_stream) with
- wake_up(&wait_stream);
-- Cosmetic cleanups in the documentation.
-
-Signed-off-by: Luca Risolia <luca.risolia@studio.unibo.it>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-
----
- Documentation/usb/zc0301.txt | 19 +++++----------
- drivers/usb/media/zc0301.h | 2 -
- drivers/usb/media/zc0301_core.c | 43 ++++++++++++++++++++++-------------
- drivers/usb/media/zc0301_pas202bcb.c | 2 -
- 4 files changed, 37 insertions(+), 29 deletions(-)
-
---- gregkh-2.6.orig/Documentation/usb/zc0301.txt
-+++ gregkh-2.6/Documentation/usb/zc0301.txt
-@@ -67,8 +67,7 @@ Some of the features of the driver are:
- - available mmap or read/poll methods for video streaming through isochronous
- data transfers;
- - automatic detection of image sensor;
--- video formats is standard JPEG in various compression qualities
-- (see also "Notes for V4L2 application developers" paragraph);
-+- 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
-@@ -226,10 +225,6 @@ The same number of buffers as before wil
- of the new video frames, so you have to map the buffers again before any I/O
- attempts on them.
-
--This driver supports the standard JPEG video format. The current compression
--quality may vary from 0 to 3 and can be selected or queried thanks to the
--VIDIOC_S_JPEGCOMP and VIDIOC_G_JPEGCOMP V4L2 ioctl's.
--
-
- 10. Contact information
- =======================
-@@ -242,9 +237,9 @@ the fingerprint is: '88E8 F32F 7244 68BA
-
- 11. Credits
- ===========
--- Informations about the chip internals 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 connected to the PAS202BCB image sensor
-- have been taken from the SPCA5XX driver maintained by
-- Michel Xhaard <mxhaard@magic.fr>
-+- 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
-+ image sensor have been taken from the SPCA5XX driver maintained by
-+ Michel Xhaard <mxhaard@magic.fr>.
---- gregkh-2.6.orig/drivers/usb/media/zc0301.h
-+++ gregkh-2.6/drivers/usb/media/zc0301.h
-@@ -45,7 +45,7 @@
- #define ZC0301_MAX_DEVICES 64
- #define ZC0301_FORCE_MUNMAP 0
- #define ZC0301_MAX_FRAMES 32
--#define ZC0301_COMPRESSION_QUALITY 2
-+#define ZC0301_COMPRESSION_QUALITY 0
- #define ZC0301_URBS 2
- #define ZC0301_ISO_PACKETS 7
- #define ZC0301_ALTERNATE_SETTING 7
---- gregkh-2.6.orig/drivers/usb/media/zc0301_core.c
-+++ gregkh-2.6/drivers/usb/media/zc0301_core.c
-@@ -3,9 +3,9 @@
- * *
- * Copyright (C) 2006 by Luca Risolia <luca.risolia@studio.unibo.it> *
- * *
-- * Informations about the chip internals to enable the I2C protocol have *
-- * been taken from the documentation of the ZC030x Video4Linux1 driver *
-- * written by Andrew Birkett <andy@nobugs.org> *
-+ * 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> *
- * *
- * 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 *
-@@ -54,8 +54,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.00"
--#define ZC0301_MODULE_VERSION_CODE KERNEL_VERSION(1, 0, 0)
-+#define ZC0301_MODULE_VERSION "1:1.01"
-+#define ZC0301_MODULE_VERSION_CODE KERNEL_VERSION(1, 0, 1)
-
- /*****************************************************************************/
-
-@@ -314,7 +314,7 @@ static void zc0301_urb_complete(struct u
- 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)
-@@ -526,7 +526,7 @@ static int zc0301_stream_interrupt(struc
- ZC0301_URB_TIMEOUT);
- if (cam->state & DEV_DISCONNECTED)
- return -ENODEV;
-- else if (!timeout) {
-+ 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.",
-@@ -547,8 +547,7 @@ zc0301_set_compression(struct zc0301_dev
-
- if ((r = zc0301_read_reg(cam, 0x0008)) < 0)
- err += r;
-- err += zc0301_write_reg(cam, 0x0008,
-- r | 0x11 | (compression->quality >> 1));
-+ err += zc0301_write_reg(cam, 0x0008, r | 0x11 | compression->quality);
-
- return err ? -EIO : 0;
- }
-@@ -737,8 +736,7 @@ static int zc0301_release(struct inode*
-
-
- static ssize_t
--zc0301_read(struct file* filp, char __user * buf,
-- size_t count, loff_t* f_pos)
-+zc0301_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos)
- {
- struct zc0301_device* cam = video_get_drvdata(video_devdata(filp));
- struct zc0301_frame_t* f, * i;
-@@ -1019,6 +1017,7 @@ zc0301_vidioc_enuminput(struct zc0301_de
-
- 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;
-@@ -1028,7 +1027,19 @@ zc0301_vidioc_enuminput(struct zc0301_de
-
-
- static int
--zc0301_vidioc_gs_input(struct zc0301_device* cam, void __user * arg)
-+zc0301_vidioc_g_input(struct zc0301_device* cam, void __user * arg)
-+{
-+ int index = 0;
-+
-+ if (copy_to_user(arg, &index, sizeof(index)))
-+ return -EFAULT;
-+
-+ return 0;
-+}
-+
-+
-+static int
-+zc0301_vidioc_s_input(struct zc0301_device* cam, void __user * arg)
- {
- int index;
-
-@@ -1446,7 +1457,7 @@ zc0301_vidioc_s_jpegcomp(struct zc0301_d
- if (copy_from_user(&jc, arg, sizeof(jc)))
- return -EFAULT;
-
-- if (jc.quality < 0 || jc.quality > 3)
-+ if (jc.quality != 0)
- return -EINVAL;
-
- if (cam->stream == STREAM_ON)
-@@ -1738,8 +1749,10 @@ static int zc0301_ioctl_v4l2(struct inod
- return zc0301_vidioc_enuminput(cam, arg);
-
- case VIDIOC_G_INPUT:
-+ return zc0301_vidioc_g_input(cam, arg);
-+
- case VIDIOC_S_INPUT:
-- return zc0301_vidioc_gs_input(cam, arg);
-+ return zc0301_vidioc_s_input(cam, arg);
-
- case VIDIOC_QUERYCTRL:
- return zc0301_vidioc_query_ctrl(cam, arg);
-@@ -1980,7 +1993,7 @@ static void zc0301_usb_disconnect(struct
- zc0301_stop_transfer(cam);
- cam->state |= DEV_DISCONNECTED;
- wake_up_interruptible(&cam->wait_frame);
-- wake_up_interruptible(&cam->wait_stream);
-+ wake_up(&cam->wait_stream);
- } else {
- cam->state |= DEV_DISCONNECTED;
- zc0301_release_resources(cam);
---- gregkh-2.6.orig/drivers/usb/media/zc0301_pas202bcb.c
-+++ gregkh-2.6/drivers/usb/media/zc0301_pas202bcb.c
-@@ -318,7 +318,7 @@ static struct zc0301_sensor pas202bcb =
- .width = 640,
- .height = 480,
- .pixelformat = V4L2_PIX_FMT_JPEG,
-- .priv = 16,
-+ .priv = 8,
- },
- };
-
diff --git a/usb/usb-zero-driver-removed-duplicated-code.patch b/usb/usb-zero-driver-removed-duplicated-code.patch
deleted file mode 100644
index bf06e88e13a4f..0000000000000
--- a/usb/usb-zero-driver-removed-duplicated-code.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From linux-usb-devel-admin@lists.sourceforge.net Tue Feb 7 00:07:07 2006
-Message-ID: <cda58cb80602070006k29e9ea67v@mail.gmail.com>
-From: Franck Bui-Huu <vagabon.xyz@gmail.com>
-Cc: David Brownell <david-b@pacbell.net>, Alan Stern <stern@rowland.harvard.edu>
-Content-Disposition: inline
-Subject: USB: Zero driver: Removed duplicated code
-Date: Tue, 7 Feb 2006 09:06:17 +0100
-
-Signed-off-by: Franck Bui-Huu <vagabon.xyz@gmail.com>
-
-
----
- drivers/usb/gadget/zero.c | 6 ------
- 1 file changed, 6 deletions(-)
-
---- gregkh-2.6.orig/drivers/usb/gadget/zero.c
-+++ gregkh-2.6/drivers/usb/gadget/zero.c
-@@ -1224,12 +1224,6 @@ autoconf_fail:
- loopback_config.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
- }
-
-- if (gadget->is_otg) {
-- otg_descriptor.bmAttributes |= USB_OTG_HNP,
-- source_sink_config.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
-- loopback_config.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
-- }
--
- usb_gadget_set_selfpowered (gadget);
-
- init_timer (&dev->resume);
diff --git a/usb/usbcore-fix-compile-error-with-config_usb_suspend-n.patch b/usb/usbcore-fix-compile-error-with-config_usb_suspend-n.patch
deleted file mode 100644
index a48ffab904d84..0000000000000
--- a/usb/usbcore-fix-compile-error-with-config_usb_suspend-n.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From stern@rowland.harvard.edu Wed Feb 1 07:47:21 2006
-Date: Wed, 1 Feb 2006 10:47:11 -0500 (EST)
-From: Alan Stern <stern@rowland.harvard.edu>
-To: Andrew Morton <akpm@osdl.org>
-cc: David Brownell <david-b@pacbell.net>, Greg KH <greg@kroah.com>
-Subject: usbcore: fix compile error with CONFIG_USB_SUSPEND=n
-Message-ID: <Pine.LNX.4.44L0.0602011044270.5635-100000@iolanthe.rowland.org>
-
-This patch (as647) fixes a small error introduced by a recent change to
-the USB core suspend/resume code.
-
-Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
-
----
- drivers/usb/core/hub.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- gregkh-2.6.orig/drivers/usb/core/hub.c
-+++ gregkh-2.6/drivers/usb/core/hub.c
-@@ -1892,8 +1892,8 @@ int usb_resume_device(struct usb_device
- status = hub_port_resume(hdev_to_hub(udev->parent),
- udev->portnum, udev);
- } else
-- status = 0;
- #endif
-+ status = 0;
- } else
- status = finish_device_resume(udev);
- if (status < 0)
diff --git a/usb/usbhid-add-error-handling.patch b/usb/usbhid-add-error-handling.patch
deleted file mode 100644
index 987cf224b0ea7..0000000000000
--- a/usb/usbhid-add-error-handling.patch
+++ /dev/null
@@ -1,298 +0,0 @@
-From stern@rowland.harvard.edu Tue Jan 31 09:59:01 2006
-Date: Tue, 31 Jan 2006 12:58:38 -0500 (EST)
-From: Alan Stern <stern@rowland.harvard.edu>
-To: Greg KH <greg@kroah.com>
-cc: Pete Zaitcev <zaitcev@redhat.com>, Dmitry Torokhov <dtor_core@ameritech.net>
-Subject: [PATCH] usbhid: add error handling
-Message-ID: <Pine.LNX.4.44L0.0601311251270.5380-100000@iolanthe.rowland.org>
-
-This patch (as628c) adds error handling to the USB HID core. When an
-error is reported for an interrupt URB, the driver will do delayed
-retries, at increasing intervals, for up to one second. If that doesn't
-work, it will try to reset the device. Testing by users has shown that
-both the retries and the resets end up getting used.
-
-Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-
----
- drivers/usb/input/hid-core.c | 153 +++++++++++++++++++++++++++++++++++++------
- drivers/usb/input/hid.h | 10 ++
- 2 files changed, 142 insertions(+), 21 deletions(-)
-
---- gregkh-2.6.orig/drivers/usb/input/hid-core.c
-+++ gregkh-2.6/drivers/usb/input/hid-core.c
-@@ -903,6 +903,99 @@ static int hid_input_report(int type, st
- }
-
- /*
-+ * Input submission and I/O error handler.
-+ */
-+
-+static void hid_io_error(struct hid_device *hid);
-+
-+/* Start up the input URB */
-+static int hid_start_in(struct hid_device *hid)
-+{
-+ unsigned long flags;
-+ int rc = 0;
-+
-+ spin_lock_irqsave(&hid->inlock, flags);
-+ if (hid->open > 0 && !test_bit(HID_SUSPENDED, &hid->iofl) &&
-+ !test_and_set_bit(HID_IN_RUNNING, &hid->iofl)) {
-+ rc = usb_submit_urb(hid->urbin, GFP_ATOMIC);
-+ if (rc != 0)
-+ clear_bit(HID_IN_RUNNING, &hid->iofl);
-+ }
-+ spin_unlock_irqrestore(&hid->inlock, flags);
-+ return rc;
-+}
-+
-+/* I/O retry timer routine */
-+static void hid_retry_timeout(unsigned long _hid)
-+{
-+ struct hid_device *hid = (struct hid_device *) _hid;
-+
-+ dev_dbg(&hid->intf->dev, "retrying intr urb\n");
-+ if (hid_start_in(hid))
-+ hid_io_error(hid);
-+}
-+
-+/* Workqueue routine to reset the device */
-+static void hid_reset(void *_hid)
-+{
-+ struct hid_device *hid = (struct hid_device *) _hid;
-+ int rc_lock, rc;
-+
-+ dev_dbg(&hid->intf->dev, "resetting device\n");
-+ rc = rc_lock = usb_lock_device_for_reset(hid->dev, hid->intf);
-+ if (rc_lock >= 0) {
-+ rc = usb_reset_device(hid->dev);
-+ if (rc_lock)
-+ usb_unlock_device(hid->dev);
-+ }
-+ clear_bit(HID_RESET_PENDING, &hid->iofl);
-+
-+ if (rc == 0) {
-+ hid->retry_delay = 0;
-+ if (hid_start_in(hid))
-+ hid_io_error(hid);
-+ } else if (!(rc == -ENODEV || rc == -EHOSTUNREACH || rc == -EINTR))
-+ err("can't reset device, %s-%s/input%d, status %d",
-+ hid->dev->bus->bus_name,
-+ hid->dev->devpath,
-+ hid->ifnum, rc);
-+}
-+
-+/* Main I/O error handler */
-+static void hid_io_error(struct hid_device *hid)
-+{
-+ unsigned long flags;
-+
-+ spin_lock_irqsave(&hid->inlock, flags);
-+
-+ /* Stop when disconnected */
-+ if (usb_get_intfdata(hid->intf) == NULL)
-+ goto done;
-+
-+ /* When an error occurs, retry at increasing intervals */
-+ if (hid->retry_delay == 0) {
-+ hid->retry_delay = 13; /* Then 26, 52, 104, 104, ... */
-+ hid->stop_retry = jiffies + msecs_to_jiffies(1000);
-+ } else if (hid->retry_delay < 100)
-+ hid->retry_delay *= 2;
-+
-+ if (time_after(jiffies, hid->stop_retry)) {
-+
-+ /* Retries failed, so do a port reset */
-+ if (!test_and_set_bit(HID_RESET_PENDING, &hid->iofl)) {
-+ if (schedule_work(&hid->reset_work))
-+ goto done;
-+ clear_bit(HID_RESET_PENDING, &hid->iofl);
-+ }
-+ }
-+
-+ mod_timer(&hid->io_retry,
-+ jiffies + msecs_to_jiffies(hid->retry_delay));
-+done:
-+ spin_unlock_irqrestore(&hid->inlock, flags);
-+}
-+
-+/*
- * Input interrupt completion handler.
- */
-
-@@ -913,25 +1006,35 @@ static void hid_irq_in(struct urb *urb,
-
- switch (urb->status) {
- case 0: /* success */
-+ hid->retry_delay = 0;
- hid_input_report(HID_INPUT_REPORT, urb, 1, regs);
- break;
- case -ECONNRESET: /* unlink */
- case -ENOENT:
-- case -EPERM:
- case -ESHUTDOWN: /* unplug */
-- case -EILSEQ: /* unplug timeout on uhci */
-+ clear_bit(HID_IN_RUNNING, &hid->iofl);
- return;
-+ case -EILSEQ: /* protocol error or unplug */
-+ case -EPROTO: /* protocol error or unplug */
- case -ETIMEDOUT: /* NAK */
-- break;
-+ clear_bit(HID_IN_RUNNING, &hid->iofl);
-+ hid_io_error(hid);
-+ return;
- default: /* error */
- warn("input irq status %d received", urb->status);
- }
-
- status = usb_submit_urb(urb, SLAB_ATOMIC);
-- if (status)
-- err("can't resubmit intr, %s-%s/input%d, status %d",
-- hid->dev->bus->bus_name, hid->dev->devpath,
-- hid->ifnum, status);
-+ if (status) {
-+ clear_bit(HID_IN_RUNNING, &hid->iofl);
-+ if (status != -EPERM) {
-+ err("can't resubmit intr, %s-%s/input%d, status %d",
-+ hid->dev->bus->bus_name,
-+ hid->dev->devpath,
-+ hid->ifnum, status);
-+ hid_io_error(hid);
-+ }
-+ }
- }
-
- /*
-@@ -1093,8 +1196,9 @@ static void hid_irq_out(struct urb *urb,
- case 0: /* success */
- break;
- case -ESHUTDOWN: /* unplug */
-- case -EILSEQ: /* unplug timeout on uhci */
- unplug = 1;
-+ case -EILSEQ: /* protocol error or unplug */
-+ case -EPROTO: /* protocol error or unplug */
- case -ECONNRESET: /* unlink */
- case -ENOENT:
- break;
-@@ -1141,8 +1245,9 @@ static void hid_ctrl(struct urb *urb, st
- hid_input_report(hid->ctrl[hid->ctrltail].report->type, urb, 0, regs);
- break;
- case -ESHUTDOWN: /* unplug */
-- case -EILSEQ: /* unplug timectrl on uhci */
- unplug = 1;
-+ case -EILSEQ: /* protocol error or unplug */
-+ case -EPROTO: /* protocol error or unplug */
- case -ECONNRESET: /* unlink */
- case -ENOENT:
- case -EPIPE: /* report not available */
-@@ -1255,14 +1360,9 @@ static int hid_get_class_descriptor(stru
-
- int hid_open(struct hid_device *hid)
- {
-- if (hid->open++)
-- return 0;
--
-- hid->urbin->dev = hid->dev;
--
-- if (usb_submit_urb(hid->urbin, GFP_KERNEL))
-- return -EIO;
--
-+ ++hid->open;
-+ if (hid_start_in(hid))
-+ hid_io_error(hid);
- return 0;
- }
-
-@@ -1787,6 +1887,10 @@ static struct hid_device *usb_hid_config
-
- init_waitqueue_head(&hid->wait);
-
-+ INIT_WORK(&hid->reset_work, hid_reset, hid);
-+ setup_timer(&hid->io_retry, hid_retry_timeout, (unsigned long) hid);
-+
-+ spin_lock_init(&hid->inlock);
- spin_lock_init(&hid->outlock);
- spin_lock_init(&hid->ctrllock);
-
-@@ -1855,11 +1959,16 @@ static void hid_disconnect(struct usb_in
- if (!hid)
- return;
-
-+ spin_lock_irq(&hid->inlock); /* Sync with error handler */
- usb_set_intfdata(intf, NULL);
-+ spin_unlock_irq(&hid->inlock);
- usb_kill_urb(hid->urbin);
- usb_kill_urb(hid->urbout);
- usb_kill_urb(hid->urbctrl);
-
-+ del_timer_sync(&hid->io_retry);
-+ flush_scheduled_work();
-+
- if (hid->claimed & HID_CLAIMED_INPUT)
- hidinput_disconnect(hid);
- if (hid->claimed & HID_CLAIMED_HIDDEV)
-@@ -1934,6 +2043,10 @@ static int hid_suspend(struct usb_interf
- {
- struct hid_device *hid = usb_get_intfdata (intf);
-
-+ spin_lock_irq(&hid->inlock); /* Sync with error handler */
-+ set_bit(HID_SUSPENDED, &hid->iofl);
-+ spin_unlock_irq(&hid->inlock);
-+ del_timer(&hid->io_retry);
- usb_kill_urb(hid->urbin);
- dev_dbg(&intf->dev, "suspend\n");
- return 0;
-@@ -1944,10 +2057,8 @@ static int hid_resume(struct usb_interfa
- struct hid_device *hid = usb_get_intfdata (intf);
- int status;
-
-- if (hid->open)
-- status = usb_submit_urb(hid->urbin, GFP_NOIO);
-- else
-- status = 0;
-+ clear_bit(HID_SUSPENDED, &hid->iofl);
-+ status = hid_start_in(hid);
- dev_dbg(&intf->dev, "resume status %d\n", status);
- return status;
- }
---- gregkh-2.6.orig/drivers/usb/input/hid.h
-+++ gregkh-2.6/drivers/usb/input/hid.h
-@@ -31,6 +31,8 @@
- #include <linux/types.h>
- #include <linux/slab.h>
- #include <linux/list.h>
-+#include <linux/timer.h>
-+#include <linux/workqueue.h>
-
- /*
- * USB HID (Human Interface Device) interface class code
-@@ -370,6 +372,9 @@ struct hid_control_fifo {
-
- #define HID_CTRL_RUNNING 1
- #define HID_OUT_RUNNING 2
-+#define HID_IN_RUNNING 3
-+#define HID_RESET_PENDING 4
-+#define HID_SUSPENDED 5
-
- struct hid_input {
- struct list_head list;
-@@ -393,12 +398,17 @@ struct hid_device { /* device repo
- int ifnum; /* USB interface number */
-
- unsigned long iofl; /* I/O flags (CTRL_RUNNING, OUT_RUNNING) */
-+ struct timer_list io_retry; /* Retry timer */
-+ unsigned long stop_retry; /* Time to give up, in jiffies */
-+ unsigned int retry_delay; /* Delay length in ms */
-+ struct work_struct reset_work; /* Task context for resets */
-
- unsigned int bufsize; /* URB buffer size */
-
- struct urb *urbin; /* Input URB */
- char *inbuf; /* Input buffer */
- dma_addr_t inbuf_dma; /* Input buffer dma */
-+ spinlock_t inlock; /* Input fifo spinlock */
-
- struct urb *urbctrl; /* Control URB */
- struct usb_ctrlrequest *cr; /* Control request struct */