aboutsummaryrefslogtreecommitdiffstats
path: root/usb
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@suse.de>2006-03-31 12:10:28 -0800
committerGreg Kroah-Hartman <gregkh@suse.de>2006-03-31 12:10:28 -0800
commit80d534567378ce62ba8e2c51a3b6621e5b8b5605 (patch)
tree805322f31f88df173918bec787285835c33d1ccf /usb
parent7446377126dc0e69c4d60dd3edf557efdd150337 (diff)
downloadpatches-80d534567378ce62ba8e2c51a3b6621e5b8b5605.tar.gz
more patches
Diffstat (limited to 'usb')
-rw-r--r--usb/usb-add-support-for-papouch-tmu.patch64
-rw-r--r--usb/usb-cleanups-for-ohci-s3c2410.c.patch51
-rw-r--r--usb/usb-ftdi_sio-add-support-for-eclo-com-to-1-wire-usb-adapter.patch46
-rw-r--r--usb/usb-g_file_storage-add-comment-about-buffer-allocation.patch44
-rw-r--r--usb/usb-g_file_storage-set-short_not_ok-for-bulk-out-transfers.patch46
-rw-r--r--usb/usb-g_file_storage-use-module_param_array_named-macro.patch86
-rw-r--r--usb/usb-input-proper-prototypes.patch45
-rw-r--r--usb/usb-net2282-and-net2280-software-compatibility.patch271
-rw-r--r--usb/usb-pci-quirks.c-proper-prototypes.patch62
-rw-r--r--usb/usb-serial-converts-port-semaphore-to-mutexes.patch121
-rw-r--r--usb/usb-usbtouchscreen-unified-usb-touchscreen-driver.patch743
11 files changed, 1579 insertions, 0 deletions
diff --git a/usb/usb-add-support-for-papouch-tmu.patch b/usb/usb-add-support-for-papouch-tmu.patch
new file mode 100644
index 00000000000000..48cc7ea267e7b4
--- /dev/null
+++ b/usb/usb-add-support-for-papouch-tmu.patch
@@ -0,0 +1,64 @@
+From kalin@thinrope.net Tue Mar 28 03:41:52 2006
+Message-ID: <442920E6.3020603@thinrope.net>
+Date: Tue, 28 Mar 2006 20:41:26 +0900
+From: Kalin KOZHUHAROV <kalin@thinrope.net>
+Cc: Greg KH <greg@kroah.com>, Folkert van Heusden <folkert@vanheusden.com>
+Subject: USB: add support for Papouch TMU (USB thermometer)
+
+From: Folkert van Heusden <folkert@vanheusden.com>
+
+This patch adds support for new vendor (papouch) and one of their
+devices - TMU (a USB thermometer).
+
+More information:
+vendor homepage:
+ http://www.papouch.com/en/
+product homepage (Polish):
+ http://www.papouch.com/shop/scripts/_detail.asp?katcislo=0188
+
+This patch is based on the submission from Folkert van Heusden [1].
+Then reviseted by Kalin KOZHUHAROV [2] and retested by Folkert.
+
+[1] http://article.gmane.org/gmane.linux.kernel/392970
+[2] http://article.gmane.org/gmane.linux.kernel/393386
+
+
+
+Signed-off-by: Folkert van Heusden <folkert@vanheusden.com>
+Signed-off-by: Kalin KOZHUHAROV <kalin@thinrope.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+
+---
+ drivers/usb/serial/ftdi_sio.c | 1 +
+ drivers/usb/serial/ftdi_sio.h | 9 +++++++++
+ 2 files changed, 10 insertions(+)
+
+--- gregkh-2.6.orig/drivers/usb/serial/ftdi_sio.c
++++ gregkh-2.6/drivers/usb/serial/ftdi_sio.c
+@@ -494,6 +494,7 @@ static struct usb_device_id id_table_com
+ { 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) },
++ { USB_DEVICE(PAPOUCH_VID, PAPOUCH_TMU_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
+@@ -405,6 +405,15 @@
+ */
+ #define FTDI_ECLO_COM_1WIRE_PID 0xEA90 /* COM to 1-Wire USB adaptor */
+
++/*
++ * Papouch products (http://www.papouch.com/)
++ * Submitted by Folkert van Heusden
++ */
++
++#define PAPOUCH_VID 0x5050 /* Vendor ID */
++#define PAPOUCH_TMU_PID 0x0400 /* TMU USB Thermometer */
++
++
+ /* Commands */
+ #define FTDI_SIO_RESET 0 /* Reset the port */
+ #define FTDI_SIO_MODEM_CTRL 1 /* Set the modem control register */
diff --git a/usb/usb-cleanups-for-ohci-s3c2410.c.patch b/usb/usb-cleanups-for-ohci-s3c2410.c.patch
new file mode 100644
index 00000000000000..5a98e0fe55be2d
--- /dev/null
+++ b/usb/usb-cleanups-for-ohci-s3c2410.c.patch
@@ -0,0 +1,51 @@
+From ben@fluff.org.uk Tue Mar 21 14:56:19 2006
+Date: Tue, 21 Mar 2006 22:54:47 +0000
+From: Ben Dooks <ben-linux-usb@fluff.org>
+To: linux-usb-devel@lists.sourceforge.net, greg@kroah.com
+Subject: USB: cleanups for ohci-s3c2410.c
+Message-ID: <20060321225447.GA6198@home.fluff.org>
+Content-Disposition: inline
+
+
+Fix compile errors due to functions not being
+defined static
+
+Signed-off-by: Ben Dooks <ben-linux@fluff.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/host/ohci-s3c2410.c | 9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+--- gregkh-2.6.orig/drivers/usb/host/ohci-s3c2410.c
++++ gregkh-2.6/drivers/usb/host/ohci-s3c2410.c
+@@ -37,7 +37,7 @@ static void s3c2410_hcd_oc(struct s3c241
+
+ /* conversion functions */
+
+-struct s3c2410_hcd_info *to_s3c2410_info(struct usb_hcd *hcd)
++static struct s3c2410_hcd_info *to_s3c2410_info(struct usb_hcd *hcd)
+ {
+ return hcd->self.controller->platform_data;
+ }
+@@ -316,7 +316,8 @@ static void s3c2410_hcd_oc(struct s3c241
+ *
+ */
+
+-void usb_hcd_s3c2410_remove (struct usb_hcd *hcd, struct platform_device *dev)
++static void
++usb_hcd_s3c2410_remove (struct usb_hcd *hcd, struct platform_device *dev)
+ {
+ usb_remove_hcd(hcd);
+ s3c2410_stop_hc(dev);
+@@ -334,8 +335,8 @@ void usb_hcd_s3c2410_remove (struct usb_
+ * through the hotplug entry's driver_data.
+ *
+ */
+-int usb_hcd_s3c2410_probe (const struct hc_driver *driver,
+- struct platform_device *dev)
++static int usb_hcd_s3c2410_probe (const struct hc_driver *driver,
++ struct platform_device *dev)
+ {
+ struct usb_hcd *hcd = NULL;
+ int retval;
diff --git a/usb/usb-ftdi_sio-add-support-for-eclo-com-to-1-wire-usb-adapter.patch b/usb/usb-ftdi_sio-add-support-for-eclo-com-to-1-wire-usb-adapter.patch
new file mode 100644
index 00000000000000..4606d44b1863f4
--- /dev/null
+++ b/usb/usb-ftdi_sio-add-support-for-eclo-com-to-1-wire-usb-adapter.patch
@@ -0,0 +1,46 @@
+From ian.abbott@mev.co.uk Tue Mar 21 06:55:57 2006
+Message-ID: <442013D8.40902@mev.co.uk>
+Date: Tue, 21 Mar 2006 14:55:20 +0000
+From: Ian Abbott <abbotti@mev.co.uk>
+Cc: Greg KH <greg@kroah.com>, Martin Grill <m.grill@lancaster.ac.uk>
+Subject: USB: ftdi_sio: add support for Eclo COM to 1-Wire USB adapter
+
+This patch adds support for the Eclo COM to 1-Wire USB adapter
+<http://www.eclo.pt/products_ibutton_adapters_usb01_en.asp> to the
+ftdi_sio driver's device ID table. Details were provided by Martin
+Grill on the ftdi-sio-usb-devel mailing list and I (Ian Abbott)
+confirmed it matched the INF file in the Eclo's Windows driver package.
+
+Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/serial/ftdi_sio.c | 1 +
+ drivers/usb/serial/ftdi_sio.h | 6 ++++++
+ 2 files changed, 7 insertions(+)
+
+--- gregkh-2.6.orig/drivers/usb/serial/ftdi_sio.c
++++ gregkh-2.6/drivers/usb/serial/ftdi_sio.c
+@@ -489,6 +489,7 @@ static struct usb_device_id id_table_com
+ { USB_DEVICE(KOBIL_VID, KOBIL_CONV_KAAN_PID) },
+ { USB_DEVICE(POSIFLEX_VID, POSIFLEX_PP7000_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_TTUSB_PID) },
++ { USB_DEVICE(FTDI_VID, FTDI_ECLO_COM_1WIRE_PID) },
+ { 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) },
+--- gregkh-2.6.orig/drivers/usb/serial/ftdi_sio.h
++++ gregkh-2.6/drivers/usb/serial/ftdi_sio.h
+@@ -399,6 +399,12 @@
+ #define FTDI_WESTREX_MODEL_777_PID 0xDC00 /* Model 777 */
+ #define FTDI_WESTREX_MODEL_8900F_PID 0xDC01 /* Model 8900F */
+
++/*
++ * Eclo (http://www.eclo.pt/) product IDs.
++ * PID 0xEA90 submitted by Martin Grill.
++ */
++#define FTDI_ECLO_COM_1WIRE_PID 0xEA90 /* COM to 1-Wire USB adaptor */
++
+ /* Commands */
+ #define FTDI_SIO_RESET 0 /* Reset the port */
+ #define FTDI_SIO_MODEM_CTRL 1 /* Set the modem control register */
diff --git a/usb/usb-g_file_storage-add-comment-about-buffer-allocation.patch b/usb/usb-g_file_storage-add-comment-about-buffer-allocation.patch
new file mode 100644
index 00000000000000..ac272b253b515f
--- /dev/null
+++ b/usb/usb-g_file_storage-add-comment-about-buffer-allocation.patch
@@ -0,0 +1,44 @@
+From stern@rowland.harvard.edu Thu Mar 23 12:07:29 2006
+Date: Thu, 23 Mar 2006 15:07:25 -0500 (EST)
+From: Alan Stern <stern@rowland.harvard.edu>
+To: Greg KH <greg@kroah.com>
+Subject: USB: g_file_storage: add comment about buffer allocation
+Message-ID: <Pine.LNX.4.44L0.0603231505170.4830-100000@iolanthe.rowland.org>
+
+This patch (as664) adds a comment to file_storage.c, noting that the
+driver is slightly non-portable because it assumes that a buffer
+allocated for a bulk-in endpoint will also be useable for a bulk-out
+endpoint.
+
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/gadget/file_storage.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+--- gregkh-2.6.orig/drivers/usb/gadget/file_storage.c
++++ gregkh-2.6/drivers/usb/gadget/file_storage.c
+@@ -71,6 +71,12 @@
+ * requirement amounts to two 16K buffers, size configurable by a parameter.
+ * Support is included for both full-speed and high-speed operation.
+ *
++ * Note that the driver is slightly non-portable in that it assumes a
++ * single memory/DMA buffer will be useable for bulk-in, bulk-out, and
++ * interrupt-in endpoints. With most device controllers this isn't an
++ * issue, but there may be some with hardware restrictions that prevent
++ * a buffer from being used by more than one endpoint.
++ *
+ * Module options:
+ *
+ * file=filename[,filename...]
+@@ -3956,6 +3962,9 @@ static int __init fsg_bind(struct usb_ga
+ for (i = 0; i < NUM_BUFFERS; ++i) {
+ struct fsg_buffhd *bh = &fsg->buffhds[i];
+
++ /* Allocate for the bulk-in endpoint. We assume that
++ * the buffer will also work with the bulk-out (and
++ * interrupt-in) endpoint. */
+ bh->buf = usb_ep_alloc_buffer(fsg->bulk_in, mod_data.buflen,
+ &bh->dma, GFP_KERNEL);
+ if (!bh->buf)
diff --git a/usb/usb-g_file_storage-set-short_not_ok-for-bulk-out-transfers.patch b/usb/usb-g_file_storage-set-short_not_ok-for-bulk-out-transfers.patch
new file mode 100644
index 00000000000000..530b3c9006ead3
--- /dev/null
+++ b/usb/usb-g_file_storage-set-short_not_ok-for-bulk-out-transfers.patch
@@ -0,0 +1,46 @@
+From stern@rowland.harvard.edu Thu Mar 23 12:05:19 2006
+Date: Thu, 23 Mar 2006 15:05:16 -0500 (EST)
+From: Alan Stern <stern@rowland.harvard.edu>
+To: Greg KH <greg@kroah.com>
+Subject: USB: g_file_storage: Set short_not_ok for bulk-out transfers
+Message-ID: <Pine.LNX.4.44L0.0603231500350.4830-100000@iolanthe.rowland.org>
+
+I'm told that some UDC hardware may work better if it knows that
+receiving a short packet should always cause an error. Accordingly,
+this patch (as663) sets the short_not_ok flag for bulk-out transfers in
+g_file_storage. Oddly enough, there are no circumstances where that
+driver can legally receive a shorter-than-expected bulk-out packet.
+
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/gadget/file_storage.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- gregkh-2.6.orig/drivers/usb/gadget/file_storage.c
++++ gregkh-2.6/drivers/usb/gadget/file_storage.c
+@@ -1795,6 +1795,7 @@ static int do_write(struct fsg_dev *fsg)
+ * the bulk-out maxpacket size */
+ bh->outreq->length = bh->bulk_out_intended_length =
+ amount;
++ bh->outreq->short_not_ok = 1;
+ start_transfer(fsg, fsg->bulk_out, bh->outreq,
+ &bh->outreq_busy, &bh->state);
+ fsg->next_buffhd_to_fill = bh->next;
+@@ -2398,6 +2399,7 @@ static int throw_away_data(struct fsg_de
+ * the bulk-out maxpacket size */
+ bh->outreq->length = bh->bulk_out_intended_length =
+ amount;
++ bh->outreq->short_not_ok = 1;
+ start_transfer(fsg, fsg->bulk_out, bh->outreq,
+ &bh->outreq_busy, &bh->state);
+ fsg->next_buffhd_to_fill = bh->next;
+@@ -3029,6 +3031,7 @@ static int get_next_command(struct fsg_d
+
+ /* Queue a request to read a Bulk-only CBW */
+ set_bulk_out_req_length(fsg, bh, USB_BULK_CB_WRAP_LEN);
++ bh->outreq->short_not_ok = 1;
+ start_transfer(fsg, fsg->bulk_out, bh->outreq,
+ &bh->outreq_busy, &bh->state);
+
diff --git a/usb/usb-g_file_storage-use-module_param_array_named-macro.patch b/usb/usb-g_file_storage-use-module_param_array_named-macro.patch
new file mode 100644
index 00000000000000..3d63bf72c9107d
--- /dev/null
+++ b/usb/usb-g_file_storage-use-module_param_array_named-macro.patch
@@ -0,0 +1,86 @@
+From stern@rowland.harvard.edu Fri Mar 31 08:46:55 2006
+Date: Fri, 31 Mar 2006 11:46:43 -0500 (EST)
+From: Alan Stern <stern@rowland.harvard.edu>
+To: Greg KH <greg@kroah.com>
+cc: Pat LaVarre <p.lavarre@ieee.org>
+Subject: USB: g_file_storage: use module_param_array_named macro
+Message-ID: <Pine.LNX.4.44L0.0603311141240.5091-100000@iolanthe.rowland.org>
+
+Randy Dunlap pointed out that there now is a module_param_array_named
+macro available. This patch (as666) updates g_file_storage to make use of
+it. It also adds a comment listing the specifications documents used in
+the design of the driver's SCSI operation (at Pat LaVarre's request).
+
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/gadget/file_storage.c | 26 +++++++++++++++++---------
+ 1 file changed, 17 insertions(+), 9 deletions(-)
+
+--- gregkh-2.6.orig/drivers/usb/gadget/file_storage.c
++++ gregkh-2.6/drivers/usb/gadget/file_storage.c
+@@ -114,6 +114,14 @@
+ * setting are not allowed when the medium is loaded.
+ *
+ * This gadget driver is heavily based on "Gadget Zero" by David Brownell.
++ * The driver's SCSI command interface was based on the "Information
++ * technology - Small Computer System Interface - 2" document from
++ * X3T9.2 Project 375D, Revision 10L, 7-SEP-93, available at
++ * <http://www.t10.org/ftp/t10/drafts/s2/s2-r10l.pdf>. The single exception
++ * is opcode 0x23 (READ FORMAT CAPACITIES), which was based on the
++ * "Universal Serial Bus Mass Storage Class UFI Command Specification"
++ * document, Revision 1.0, December 14, 1998, available at
++ * <http://www.usb.org/developers/devclass_docs/usbmass-ufi10.pdf>.
+ */
+
+
+@@ -340,11 +348,9 @@ MODULE_LICENSE("Dual BSD/GPL");
+
+ #define MAX_LUNS 8
+
+- /* Arggh! There should be a module_param_array_named macro! */
+-static char *file[MAX_LUNS];
+-static int ro[MAX_LUNS];
+-
+ static struct {
++ char *file[MAX_LUNS];
++ int ro[MAX_LUNS];
+ int num_filenames;
+ int num_ros;
+ unsigned int nluns;
+@@ -376,10 +382,11 @@ static struct {
+ };
+
+
+-module_param_array(file, charp, &mod_data.num_filenames, S_IRUGO);
++module_param_array_named(file, mod_data.file, charp, &mod_data.num_filenames,
++ S_IRUGO);
+ MODULE_PARM_DESC(file, "names of backing files or devices");
+
+-module_param_array(ro, bool, &mod_data.num_ros, S_IRUGO);
++module_param_array_named(ro, mod_data.ro, bool, &mod_data.num_ros, S_IRUGO);
+ MODULE_PARM_DESC(ro, "true to force read-only");
+
+ module_param_named(luns, mod_data.nluns, uint, S_IRUGO);
+@@ -3868,7 +3875,7 @@ static int __init fsg_bind(struct usb_ga
+
+ for (i = 0; i < fsg->nluns; ++i) {
+ curlun = &fsg->luns[i];
+- curlun->ro = ro[i];
++ curlun->ro = mod_data.ro[i];
+ curlun->dev.parent = &gadget->dev;
+ curlun->dev.driver = &fsg_driver.driver;
+ dev_set_drvdata(&curlun->dev, fsg);
+@@ -3885,8 +3892,9 @@ static int __init fsg_bind(struct usb_ga
+ kref_get(&fsg->ref);
+ }
+
+- if (file[i] && *file[i]) {
+- if ((rc = open_backing_file(curlun, file[i])) != 0)
++ if (mod_data.file[i] && *mod_data.file[i]) {
++ if ((rc = open_backing_file(curlun,
++ mod_data.file[i])) != 0)
+ goto out;
+ } else if (!mod_data.removable) {
+ ERROR(fsg, "no file given for LUN%d\n", i);
diff --git a/usb/usb-input-proper-prototypes.patch b/usb/usb-input-proper-prototypes.patch
new file mode 100644
index 00000000000000..5e70b12e46b0ee
--- /dev/null
+++ b/usb/usb-input-proper-prototypes.patch
@@ -0,0 +1,45 @@
+From bunk@stusta.de Sat Mar 25 09:03:43 2006
+Date: Sat, 25 Mar 2006 18:03:38 +0100
+From: Adrian Bunk <bunk@stusta.de>
+To: gregkh@suse.de
+Subject: USB: input/: proper prototypes
+Message-ID: <20060325170338.GF4053@stusta.de>
+Content-Disposition: inline
+
+This patch adds proper prototypes in a header file for some global
+functions.
+
+Signed-off-by: Adrian Bunk <bunk@stusta.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/input/hid-ff.c | 6 ------
+ drivers/usb/input/hid.h | 5 +++++
+ 2 files changed, 5 insertions(+), 6 deletions(-)
+
+--- gregkh-2.6.orig/drivers/usb/input/hid-ff.c
++++ gregkh-2.6/drivers/usb/input/hid-ff.c
+@@ -34,12 +34,6 @@
+
+ #include "hid.h"
+
+-/* Drivers' initializing functions */
+-extern int hid_lgff_init(struct hid_device* hid);
+-extern int hid_lg3d_init(struct hid_device* hid);
+-extern int hid_pid_init(struct hid_device* hid);
+-extern int hid_tmff_init(struct hid_device* hid);
+-
+ /*
+ * This table contains pointers to initializers. To add support for new
+ * devices, you need to add the USB vendor and product ids here.
+--- gregkh-2.6.orig/drivers/usb/input/hid.h
++++ gregkh-2.6/drivers/usb/input/hid.h
+@@ -533,3 +533,8 @@ static inline int hid_ff_event(struct hi
+ return hid->ff_event(hid, input, type, code, value);
+ return -ENOSYS;
+ }
++
++int hid_lgff_init(struct hid_device* hid);
++int hid_tmff_init(struct hid_device* hid);
++int hid_pid_init(struct hid_device* hid);
++
diff --git a/usb/usb-net2282-and-net2280-software-compatibility.patch b/usb/usb-net2282-and-net2280-software-compatibility.patch
new file mode 100644
index 00000000000000..b2de18c9e7191c
--- /dev/null
+++ b/usb/usb-net2282-and-net2280-software-compatibility.patch
@@ -0,0 +1,271 @@
+From g.liakhovetski@gmx.de Sun Mar 19 11:49:23 2006
+Date: Sun, 19 Mar 2006 20:49:14 +0100 (CET)
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+To: Greg KH <gregkh@suse.de>
+Cc: Guennadi Liakhovetski <gl@dsa-ac.de>
+Subject: USB: net2282 and net2280 software compatibility
+Message-ID: <Pine.LNX.4.60.0603192046210.3832@poirot.grange>
+
+Below is a patch to gadgets/net2280.[ch] which adds support for the
+net2282 controller. The original code was kindly provided by PLX
+Technology, I just merged it with the current net2280 driver in the
+kernel. Tested on 2.6.15.6, but only with 2282. I did the merge, so
+that the behaviour for the 2280 is unaffected (except for short delays
+for extra checks).
+
+Signed-off-by: G. Liakhovetski <g.liakhovetski@gmx.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+Support for net2282 in net2280 driver.
+
+---
+ drivers/usb/gadget/Kconfig | 4 -
+ drivers/usb/gadget/net2280.c | 90 ++++++++++++++++++++++++++++++++-----------
+ drivers/usb/gadget/net2280.h | 2
+ 3 files changed, 73 insertions(+), 23 deletions(-)
+
+--- gregkh-2.6.orig/drivers/usb/gadget/Kconfig
++++ gregkh-2.6/drivers/usb/gadget/Kconfig
+@@ -69,11 +69,11 @@ choice
+ often need board-specific hooks.
+
+ config USB_GADGET_NET2280
+- boolean "NetChip 2280"
++ boolean "NetChip 228x"
+ depends on PCI
+ select USB_GADGET_DUALSPEED
+ help
+- NetChip 2280 is a PCI based USB peripheral controller which
++ NetChip 2280 / 2282 is a PCI based USB peripheral controller which
+ supports both full and high speed USB 2.0 data transfers.
+
+ It has six configurable endpoints, as well as endpoint zero
+--- gregkh-2.6.orig/drivers/usb/gadget/net2280.c
++++ gregkh-2.6/drivers/usb/gadget/net2280.c
+@@ -26,6 +26,8 @@
+ * Copyright (C) 2003 David Brownell
+ * Copyright (C) 2003-2005 PLX Technology, Inc.
+ *
++ * Modified Seth Levy 2005 PLX Technology, Inc. to provide compatibility with 2282 chip
++ *
+ * 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
+@@ -71,8 +73,8 @@
+ #include <asm/unaligned.h>
+
+
+-#define DRIVER_DESC "PLX NET2280 USB Peripheral Controller"
+-#define DRIVER_VERSION "2005 Feb 03"
++#define DRIVER_DESC "PLX NET228x USB Peripheral Controller"
++#define DRIVER_VERSION "2005 Sept 27"
+
+ #define DMA_ADDR_INVALID (~(dma_addr_t)0)
+ #define EP_DONTUSE 13 /* nonzero */
+@@ -118,7 +120,7 @@ module_param (fifo_mode, ushort, 0644);
+ /* enable_suspend -- When enabled, the driver will respond to
+ * USB suspend requests by powering down the NET2280. Otherwise,
+ * USB suspend requests will be ignored. This is acceptible for
+- * self-powered devices, and helps avoid some quirks.
++ * self-powered devices
+ */
+ static int enable_suspend = 0;
+
+@@ -223,6 +225,11 @@ net2280_enable (struct usb_ep *_ep, cons
+ ep->is_in = (tmp & USB_DIR_IN) != 0;
+ if (!ep->is_in)
+ writel ((1 << SET_NAK_OUT_PACKETS), &ep->regs->ep_rsp);
++ else if (dev->pdev->device != 0x2280) {
++ /* Added for 2282, Don't use nak packets on an in endpoint, this was ignored on 2280 */
++ writel ((1 << CLEAR_NAK_OUT_PACKETS)
++ | (1 << CLEAR_NAK_OUT_PACKETS_MODE), &ep->regs->ep_rsp);
++ }
+
+ writel (tmp, &ep->regs->ep_cfg);
+
+@@ -232,8 +239,9 @@ net2280_enable (struct usb_ep *_ep, cons
+ writel (tmp, &dev->regs->pciirqenb0);
+
+ tmp = (1 << DATA_PACKET_RECEIVED_INTERRUPT_ENABLE)
+- | (1 << DATA_PACKET_TRANSMITTED_INTERRUPT_ENABLE)
+- | readl (&ep->regs->ep_irqenb);
++ | (1 << DATA_PACKET_TRANSMITTED_INTERRUPT_ENABLE);
++ if (dev->pdev->device == 0x2280)
++ tmp |= readl (&ep->regs->ep_irqenb);
+ writel (tmp, &ep->regs->ep_irqenb);
+ } else { /* dma, per-request */
+ tmp = (1 << (8 + ep->num)); /* completion */
+@@ -314,10 +322,18 @@ static void ep_reset (struct net2280_reg
+ /* init to our chosen defaults, notably so that we NAK OUT
+ * packets until the driver queues a read (+note erratum 0112)
+ */
+- tmp = (1 << SET_NAK_OUT_PACKETS_MODE)
++ if (!ep->is_in || ep->dev->pdev->device == 0x2280) {
++ tmp = (1 << SET_NAK_OUT_PACKETS_MODE)
+ | (1 << SET_NAK_OUT_PACKETS)
+ | (1 << CLEAR_EP_HIDE_STATUS_PHASE)
+ | (1 << CLEAR_INTERRUPT_MODE);
++ } else {
++ /* added for 2282 */
++ tmp = (1 << CLEAR_NAK_OUT_PACKETS_MODE)
++ | (1 << CLEAR_NAK_OUT_PACKETS)
++ | (1 << CLEAR_EP_HIDE_STATUS_PHASE)
++ | (1 << CLEAR_INTERRUPT_MODE);
++ }
+
+ if (ep->num != 0) {
+ tmp |= (1 << CLEAR_ENDPOINT_TOGGLE)
+@@ -326,14 +342,18 @@ static void ep_reset (struct net2280_reg
+ writel (tmp, &ep->regs->ep_rsp);
+
+ /* scrub most status bits, and flush any fifo state */
+- writel ( (1 << TIMEOUT)
++ if (ep->dev->pdev->device == 0x2280)
++ tmp = (1 << FIFO_OVERFLOW)
++ | (1 << FIFO_UNDERFLOW);
++ else
++ tmp = 0;
++
++ writel (tmp | (1 << TIMEOUT)
+ | (1 << USB_STALL_SENT)
+ | (1 << USB_IN_NAK_SENT)
+ | (1 << USB_IN_ACK_RCVD)
+ | (1 << USB_OUT_PING_NAK_SENT)
+ | (1 << USB_OUT_ACK_SENT)
+- | (1 << FIFO_OVERFLOW)
+- | (1 << FIFO_UNDERFLOW)
+ | (1 << FIFO_FLUSH)
+ | (1 << SHORT_PACKET_OUT_DONE_INTERRUPT)
+ | (1 << SHORT_PACKET_TRANSFERRED_INTERRUPT)
+@@ -718,7 +738,7 @@ fill_dma_desc (struct net2280_ep *ep, st
+ */
+ if (ep->is_in)
+ dmacount |= (1 << DMA_DIRECTION);
+- else if ((dmacount % ep->ep.maxpacket) != 0)
++ if ((!ep->is_in && (dmacount % ep->ep.maxpacket) != 0) || ep->dev->pdev->device != 0x2280)
+ dmacount |= (1 << END_OF_CHAIN);
+
+ req->valid = valid;
+@@ -760,9 +780,12 @@ static inline void stop_dma (struct net2
+ static void start_queue (struct net2280_ep *ep, u32 dmactl, u32 td_dma)
+ {
+ struct net2280_dma_regs __iomem *dma = ep->dma;
++ unsigned int tmp = (1 << VALID_BIT) | (ep->is_in << DMA_DIRECTION);
+
+- writel ((1 << VALID_BIT) | (ep->is_in << DMA_DIRECTION),
+- &dma->dmacount);
++ if (ep->dev->pdev->device != 0x2280)
++ tmp |= (1 << END_OF_CHAIN);
++
++ writel (tmp, &dma->dmacount);
+ writel (readl (&dma->dmastat), &dma->dmastat);
+
+ writel (td_dma, &dma->dmadesc);
+@@ -2110,7 +2133,11 @@ static void handle_ep_small (struct net2
+ VDEBUG (ep->dev, "%s ack ep_stat %08x, req %p\n",
+ ep->ep.name, t, req ? &req->req : 0);
+ #endif
+- writel (t & ~(1 << NAK_OUT_PACKETS), &ep->regs->ep_stat);
++ if (!ep->is_in || ep->dev->pdev->device == 0x2280)
++ writel (t & ~(1 << NAK_OUT_PACKETS), &ep->regs->ep_stat);
++ else
++ /* Added for 2282 */
++ writel (t, &ep->regs->ep_stat);
+
+ /* for ep0, monitor token irqs to catch data stage length errors
+ * and to synchronize on status.
+@@ -2337,7 +2364,7 @@ static void handle_stat0_irqs (struct ne
+ u32 raw [2];
+ struct usb_ctrlrequest r;
+ } u;
+- int tmp = 0;
++ int tmp;
+ struct net2280_request *req;
+
+ if (dev->gadget.speed == USB_SPEED_UNKNOWN) {
+@@ -2364,14 +2391,19 @@ static void handle_stat0_irqs (struct ne
+ }
+ ep->stopped = 0;
+ dev->protocol_stall = 0;
+- writel ( (1 << TIMEOUT)
++
++ if (ep->dev->pdev->device == 0x2280)
++ tmp = (1 << FIFO_OVERFLOW)
++ | (1 << FIFO_UNDERFLOW);
++ else
++ tmp = 0;
++
++ writel (tmp | (1 << TIMEOUT)
+ | (1 << USB_STALL_SENT)
+ | (1 << USB_IN_NAK_SENT)
+ | (1 << USB_IN_ACK_RCVD)
+ | (1 << USB_OUT_PING_NAK_SENT)
+ | (1 << USB_OUT_ACK_SENT)
+- | (1 << FIFO_OVERFLOW)
+- | (1 << FIFO_UNDERFLOW)
+ | (1 << SHORT_PACKET_OUT_DONE_INTERRUPT)
+ | (1 << SHORT_PACKET_TRANSFERRED_INTERRUPT)
+ | (1 << DATA_PACKET_RECEIVED_INTERRUPT)
+@@ -2385,6 +2417,8 @@ static void handle_stat0_irqs (struct ne
+ cpu_to_le32s (&u.raw [0]);
+ cpu_to_le32s (&u.raw [1]);
+
++ tmp = 0;
++
+ #define w_value le16_to_cpup (&u.r.wValue)
+ #define w_index le16_to_cpup (&u.r.wIndex)
+ #define w_length le16_to_cpup (&u.r.wLength)
+@@ -2594,10 +2628,17 @@ static void handle_stat1_irqs (struct ne
+ writel (stat, &dev->regs->irqstat1);
+
+ /* some status we can just ignore */
+- stat &= ~((1 << CONTROL_STATUS_INTERRUPT)
+- | (1 << SUSPEND_REQUEST_INTERRUPT)
+- | (1 << RESUME_INTERRUPT)
+- | (1 << SOF_INTERRUPT));
++ if (dev->pdev->device == 0x2280)
++ stat &= ~((1 << CONTROL_STATUS_INTERRUPT)
++ | (1 << SUSPEND_REQUEST_INTERRUPT)
++ | (1 << RESUME_INTERRUPT)
++ | (1 << SOF_INTERRUPT));
++ else
++ stat &= ~((1 << CONTROL_STATUS_INTERRUPT)
++ | (1 << RESUME_INTERRUPT)
++ | (1 << SOF_DOWN_INTERRUPT)
++ | (1 << SOF_INTERRUPT));
++
+ if (!stat)
+ return;
+ // DEBUG (dev, "irqstat1 %08x\n", stat);
+@@ -2939,6 +2980,13 @@ static struct pci_device_id pci_ids [] =
+ .device = 0x2280,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
++}, {
++ .class = ((PCI_CLASS_SERIAL_USB << 8) | 0xfe),
++ .class_mask = ~0,
++ .vendor = 0x17cc,
++ .device = 0x2282,
++ .subvendor = PCI_ANY_ID,
++ .subdevice = PCI_ANY_ID,
+
+ }, { /* end: all zeroes */ }
+ };
+--- gregkh-2.6.orig/drivers/usb/gadget/net2280.h
++++ gregkh-2.6/drivers/usb/gadget/net2280.h
+@@ -179,6 +179,7 @@ struct net2280_regs {
+ #define PCI_TARGET_ABORT_RECEIVED_INTERRUPT 19
+ #define PCI_RETRY_ABORT_INTERRUPT 17
+ #define PCI_MASTER_CYCLE_DONE_INTERRUPT 16
++#define SOF_DOWN_INTERRUPT 14
+ #define GPIO_INTERRUPT 13
+ #define DMA_D_INTERRUPT 12
+ #define DMA_C_INTERRUPT 11
+@@ -346,6 +347,7 @@ struct net2280_dma_regs { /* [11.7] */
+ #define DMA_ENABLE 1
+ #define DMA_ADDRESS_HOLD 0
+ u32 dmastat;
++#define DMA_ABORT_DONE_INTERRUPT 27
+ #define DMA_SCATTER_GATHER_DONE_INTERRUPT 25
+ #define DMA_TRANSACTION_DONE_INTERRUPT 24
+ #define DMA_ABORT 1
diff --git a/usb/usb-pci-quirks.c-proper-prototypes.patch b/usb/usb-pci-quirks.c-proper-prototypes.patch
new file mode 100644
index 00000000000000..20c17c7edf227a
--- /dev/null
+++ b/usb/usb-pci-quirks.c-proper-prototypes.patch
@@ -0,0 +1,62 @@
+From bunk@stusta.de Sat Mar 25 09:02:30 2006
+Date: Sat, 25 Mar 2006 18:01:53 +0100
+From: Adrian Bunk <bunk@stusta.de>
+To: stern@rowland.harvard.edu, gregkh@suse.de
+Cc: linux-usb-devel@lists.sourceforge.net, linux-kernel@vger.kernel.org
+Subject: USB: pci-quirks.c: proper prototypes
+Message-ID: <20060325170153.GE4053@stusta.de>
+Content-Disposition: inline
+
+This patch adds a header file with proper prototypes for two functions
+in drivers/usb/host/pci-quirks.c.
+
+Signed-off-by: Adrian Bunk <bunk@stusta.de>
+Acked-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/host/pci-quirks.c | 1 +
+ drivers/usb/host/pci-quirks.h | 7 +++++++
+ drivers/usb/host/uhci-hcd.c | 4 +---
+ 3 files changed, 9 insertions(+), 3 deletions(-)
+
+--- gregkh-2.6.orig/drivers/usb/host/pci-quirks.c
++++ gregkh-2.6/drivers/usb/host/pci-quirks.c
+@@ -15,6 +15,7 @@
+ #include <linux/init.h>
+ #include <linux/delay.h>
+ #include <linux/acpi.h>
++#include "pci-quirks.h"
+
+
+ #define UHCI_USBLEGSUP 0xc0 /* legacy support */
+--- /dev/null
++++ gregkh-2.6/drivers/usb/host/pci-quirks.h
+@@ -0,0 +1,7 @@
++#ifndef __LINUX_USB_PCI_QUIRKS_H
++#define __LINUX_USB_PCI_QUIRKS_H
++
++void uhci_reset_hc(struct pci_dev *pdev, unsigned long base);
++int uhci_check_and_reset_hc(struct pci_dev *pdev, unsigned long base);
++
++#endif /* __LINUX_USB_PCI_QUIRKS_H */
+--- gregkh-2.6.orig/drivers/usb/host/uhci-hcd.c
++++ gregkh-2.6/drivers/usb/host/uhci-hcd.c
+@@ -50,6 +50,7 @@
+
+ #include "../core/hcd.h"
+ #include "uhci-hcd.h"
++#include "pci-quirks.h"
+
+ /*
+ * Version Information
+@@ -100,9 +101,6 @@ static void uhci_get_current_frame_numbe
+ #include "uhci-q.c"
+ #include "uhci-hub.c"
+
+-extern void uhci_reset_hc(struct pci_dev *pdev, unsigned long base);
+-extern int uhci_check_and_reset_hc(struct pci_dev *pdev, unsigned long base);
+-
+ /*
+ * Finish up a host controller reset and update the recorded state.
+ */
diff --git a/usb/usb-serial-converts-port-semaphore-to-mutexes.patch b/usb/usb-serial-converts-port-semaphore-to-mutexes.patch
new file mode 100644
index 00000000000000..20a66c27704e17
--- /dev/null
+++ b/usb/usb-serial-converts-port-semaphore-to-mutexes.patch
@@ -0,0 +1,121 @@
+From lcapitulino@mandriva.com.br Fri Mar 24 12:12:58 2006
+Date: Fri, 24 Mar 2006 17:12:31 -0300
+From: Luiz Fernando Capitulino <lcapitulino@mandriva.com.br>
+To: Greg KH <gregkh@suse.de>
+Subject: USB serial: Converts port semaphore to mutexes.
+Message-Id: <20060324171231.6b45576a.lcapitulino@mandriva.com.br>
+
+
+The usbserial's port semaphore used to synchronize serial_open()
+and serial_close() are strict mutexes, convert them to the mutex
+implementation.
+
+Signed-off-by: Luiz Capitulino <lcapitulino@mandriva.com.br>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/serial/usb-serial.c | 16 ++++++++--------
+ drivers/usb/serial/usb-serial.h | 6 +++---
+ 2 files changed, 11 insertions(+), 11 deletions(-)
+
+--- gregkh-2.6.orig/drivers/usb/serial/usb-serial.c
++++ gregkh-2.6/drivers/usb/serial/usb-serial.c
+@@ -27,10 +27,10 @@
+ #include <linux/module.h>
+ #include <linux/moduleparam.h>
+ #include <linux/spinlock.h>
++#include <linux/mutex.h>
+ #include <linux/list.h>
+ #include <linux/smp_lock.h>
+ #include <asm/uaccess.h>
+-#include <asm/semaphore.h>
+ #include <linux/usb.h>
+ #include "usb-serial.h"
+ #include "pl2303.h"
+@@ -192,7 +192,7 @@ static int serial_open (struct tty_struc
+ if (!port)
+ return -ENODEV;
+
+- if (down_interruptible(&port->sem))
++ if (mutex_lock_interruptible(&port->mutex))
+ return -ERESTARTSYS;
+
+ ++port->open_count;
+@@ -219,7 +219,7 @@ static int serial_open (struct tty_struc
+ goto bailout_module_put;
+ }
+
+- up(&port->sem);
++ mutex_unlock(&port->mutex);
+ return 0;
+
+ bailout_module_put:
+@@ -227,7 +227,7 @@ bailout_module_put:
+ bailout_kref_put:
+ kref_put(&serial->kref, destroy_serial);
+ port->open_count = 0;
+- up(&port->sem);
++ mutex_unlock(&port->mutex);
+ return retval;
+ }
+
+@@ -240,10 +240,10 @@ static void serial_close(struct tty_stru
+
+ dbg("%s - port %d", __FUNCTION__, port->number);
+
+- down(&port->sem);
++ mutex_lock(&port->mutex);
+
+ if (port->open_count == 0) {
+- up(&port->sem);
++ mutex_unlock(&port->mutex);
+ return;
+ }
+
+@@ -262,7 +262,7 @@ static void serial_close(struct tty_stru
+ module_put(port->serial->type->driver.owner);
+ }
+
+- up(&port->sem);
++ mutex_unlock(&port->mutex);
+ kref_put(&port->serial->kref, destroy_serial);
+ }
+
+@@ -783,7 +783,7 @@ int usb_serial_probe(struct usb_interfac
+ port->number = i + serial->minor;
+ port->serial = serial;
+ spin_lock_init(&port->lock);
+- sema_init(&port->sem, 1);
++ mutex_init(&port->mutex);
+ INIT_WORK(&port->work, usb_serial_port_softint, port);
+ serial->port[i] = port;
+ }
+--- gregkh-2.6.orig/drivers/usb/serial/usb-serial.h
++++ gregkh-2.6/drivers/usb/serial/usb-serial.h
+@@ -16,7 +16,7 @@
+
+ #include <linux/config.h>
+ #include <linux/kref.h>
+-#include <asm/semaphore.h>
++#include <linux/mutex.h>
+
+ #define SERIAL_TTY_MAJOR 188 /* Nice legal number now */
+ #define SERIAL_TTY_MINORS 255 /* loads of devices :) */
+@@ -31,7 +31,7 @@
+ * @serial: pointer back to the struct usb_serial owner of this port.
+ * @tty: pointer to the corresponding tty for this port.
+ * @lock: spinlock to grab when updating portions of this structure.
+- * @sem: semaphore used to synchronize serial_open() and serial_close()
++ * @mutex: mutex used to synchronize serial_open() and serial_close()
+ * access for this port.
+ * @number: the number of the port (the minor number).
+ * @interrupt_in_buffer: pointer to the interrupt in buffer for this port.
+@@ -63,7 +63,7 @@ struct usb_serial_port {
+ struct usb_serial * serial;
+ struct tty_struct * tty;
+ spinlock_t lock;
+- struct semaphore sem;
++ struct mutex mutex;
+ unsigned char number;
+
+ unsigned char * interrupt_in_buffer;
diff --git a/usb/usb-usbtouchscreen-unified-usb-touchscreen-driver.patch b/usb/usb-usbtouchscreen-unified-usb-touchscreen-driver.patch
new file mode 100644
index 00000000000000..55a3fce3974c0d
--- /dev/null
+++ b/usb/usb-usbtouchscreen-unified-usb-touchscreen-driver.patch
@@ -0,0 +1,743 @@
+From daniel.ritz-ml@swissonline.ch Wed Mar 29 12:40:33 2006
+From: Daniel Ritz <daniel.ritz-ml@swissonline.ch>
+To: Greg KH <greg@kroah.com>, Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Subject: USB: usbtouchscreen: unified USB touchscreen driver
+Date: Wed, 29 Mar 2006 22:41:07 +0200
+Content-Disposition: inline
+Message-Id: <200603292241.07903.daniel.ritz-ml@swissonline.ch>
+
+A new single driver for various USB touchscreen devices. It currently
+supports:
+- eGalax TouchKit
+- PanJit TouchSet
+- 3M/Microtouch
+- ITM Touchscreens
+
+Support for the diffent devices can be enabled/disable when CONFIG_EMBEDDED
+is set.
+
+Sizes for comparision:
+ text data bss dec hex filename
+ 2942 724 4 3670 e56 touchkitusb.ko
+ 2647 660 0 3307 ceb mtouchusb.ko
+ 2448 628 0 3076 c04 itmtouch.ko
+ 4145 1012 12 5169 1431 usbtouchscreen.ko
+
+Signed-off-by: Daniel Ritz <daniel.ritz@gmx.ch>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/input/Kconfig | 42 ++
+ drivers/usb/input/Makefile | 1
+ drivers/usb/input/hid-core.c | 7
+ drivers/usb/input/usbtouchscreen.c | 605 +++++++++++++++++++++++++++++++++++++
+ 4 files changed, 652 insertions(+), 3 deletions(-)
+
+--- gregkh-2.6.orig/drivers/usb/input/Kconfig
++++ gregkh-2.6/drivers/usb/input/Kconfig
+@@ -200,9 +200,45 @@ config USB_POWERMATE
+ To compile this driver as a module, choose M here: the
+ module will be called powermate.
+
++config USB_TOUCHSCREEN
++ tristate "USB Touchscreen Driver"
++ depends on USB && INPUT
++ ---help---
++ USB Touchscreen driver for:
++ - eGalax Touchkit USB
++ - PanJit TouchSet USB
++ - 3M MicroTouch USB
++ - ITM
++
++ Have a look at <http://linux.chapter7.ch/touchkit/> for
++ a usage description and the required user-space stuff.
++
++ To compile this driver as a module, choose M here: the
++ module will be called usbtouchscreen.
++
++config USB_TOUCHSCREEN_EGALAX
++ default y
++ bool "eGalax device support" if EMBEDDED
++ depends on USB_TOUCHSCREEN
++
++config USB_TOUCHSCREEN_PANJIT
++ default y
++ bool "PanJit device support" if EMBEDDED
++ depends on USB_TOUCHSCREEN
++
++config USB_TOUCHSCREEN_3M
++ default y
++ bool "3M/Microtouch device support" if EMBEDDED
++ depends on USB_TOUCHSCREEN
++
++config USB_TOUCHSCREEN_ITM
++ default y
++ bool "ITM device support" if EMBEDDED
++ depends on USB_TOUCHSCREEN
++
+ config USB_MTOUCH
+ tristate "MicroTouch USB Touchscreen Driver"
+- depends on USB && INPUT
++ depends on USB && INPUT && !USB_TOUCHSCREEN_3M
+ ---help---
+ Say Y here if you want to use a MicroTouch (Now 3M) USB
+ Touchscreen controller.
+@@ -214,7 +250,7 @@ config USB_MTOUCH
+
+ config USB_ITMTOUCH
+ tristate "ITM Touch USB Touchscreen Driver"
+- depends on USB && INPUT
++ depends on USB && INPUT && !USB_TOUCHSCREEN_ITM
+ ---help---
+ Say Y here if you want to use a ITM Touch USB
+ Touchscreen controller.
+@@ -226,7 +262,7 @@ config USB_ITMTOUCH
+
+ config USB_EGALAX
+ tristate "eGalax TouchKit USB Touchscreen Driver"
+- depends on USB && INPUT
++ depends on USB && INPUT && !USB_TOUCHSCREEN_EGALAX
+ ---help---
+ Say Y here if you want to use a eGalax TouchKit USB
+ Touchscreen controller.
+--- gregkh-2.6.orig/drivers/usb/input/Makefile
++++ gregkh-2.6/drivers/usb/input/Makefile
+@@ -37,6 +37,7 @@ obj-$(CONFIG_USB_MOUSE) += usbmouse.o
+ obj-$(CONFIG_USB_MTOUCH) += mtouchusb.o
+ obj-$(CONFIG_USB_ITMTOUCH) += itmtouch.o
+ obj-$(CONFIG_USB_EGALAX) += touchkitusb.o
++obj-$(CONFIG_USB_TOUCHSCREEN) += usbtouchscreen.o
+ obj-$(CONFIG_USB_POWERMATE) += powermate.o
+ obj-$(CONFIG_USB_WACOM) += wacom.o
+ obj-$(CONFIG_USB_ACECAD) += acecad.o
+--- gregkh-2.6.orig/drivers/usb/input/hid-core.c
++++ gregkh-2.6/drivers/usb/input/hid-core.c
+@@ -1372,6 +1372,8 @@ void hid_close(struct hid_device *hid)
+ usb_kill_urb(hid->urbin);
+ }
+
++#define USB_VENDOR_ID_PANJIT 0x134c
++
+ /*
+ * Initialize all reports
+ */
+@@ -1701,6 +1703,11 @@ static const struct hid_blacklist {
+ { USB_VENDOR_ID_APPLE, 0x030A, HID_QUIRK_POWERBOOK_HAS_FN },
+ { USB_VENDOR_ID_APPLE, 0x030B, HID_QUIRK_POWERBOOK_HAS_FN },
+
++ { USB_VENDOR_ID_PANJIT, 0x0001, HID_QUIRK_IGNORE },
++ { USB_VENDOR_ID_PANJIT, 0x0002, HID_QUIRK_IGNORE },
++ { USB_VENDOR_ID_PANJIT, 0x0003, HID_QUIRK_IGNORE },
++ { USB_VENDOR_ID_PANJIT, 0x0004, HID_QUIRK_IGNORE },
++
+ { 0, 0 }
+ };
+
+--- /dev/null
++++ gregkh-2.6/drivers/usb/input/usbtouchscreen.c
+@@ -0,0 +1,605 @@
++/******************************************************************************
++ * usbtouchscreen.c
++ * Driver for USB Touchscreens, supporting those devices:
++ * - eGalax Touchkit
++ * - 3M/Microtouch
++ * - ITM
++ * - PanJit TouchSet
++ *
++ * Copyright (C) 2004-2006 by Daniel Ritz <daniel.ritz@gmx.ch>
++ * Copyright (C) by Todd E. Johnson (mtouchusb.c)
++ *
++ * 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.
++ *
++ * Driver is based on touchkitusb.c
++ * - ITM parts are from itmtouch.c
++ * - 3M parts are from mtouchusb.c
++ * - PanJit parts are from an unmerged driver by Lanslott Gish
++ *
++ *****************************************************************************/
++
++//#define DEBUG
++
++#include <linux/config.h>
++#include <linux/kernel.h>
++#include <linux/slab.h>
++#include <linux/input.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/usb.h>
++#include <linux/usb_input.h>
++
++
++#define DRIVER_VERSION "v0.3"
++#define DRIVER_AUTHOR "Daniel Ritz <daniel.ritz@gmx.ch>"
++#define DRIVER_DESC "USB Touchscreen Driver"
++
++static int swap_xy;
++module_param(swap_xy, bool, 0644);
++MODULE_PARM_DESC(swap_xy, "If set X and Y axes are swapped.");
++
++/* device specifc data/functions */
++struct usbtouch_usb;
++struct usbtouch_device_info {
++ int min_xc, max_xc;
++ int min_yc, max_yc;
++ int min_press, max_press;
++ int rept_size;
++ int flags;
++
++ void (*process_pkt) (struct usbtouch_usb *usbtouch, struct pt_regs *regs, unsigned char *pkt, int len);
++ int (*read_data) (unsigned char *pkt, int *x, int *y, int *touch, int *press);
++ int (*init) (struct usbtouch_usb *usbtouch);
++};
++
++#define USBTOUCH_FLG_BUFFER 0x01
++
++
++/* a usbtouch device */
++struct usbtouch_usb {
++ unsigned char *data;
++ dma_addr_t data_dma;
++ unsigned char *buffer;
++ int buf_len;
++ struct urb *irq;
++ struct usb_device *udev;
++ struct input_dev *input;
++ struct usbtouch_device_info *type;
++ char name[128];
++ char phys[64];
++};
++
++static void usbtouch_process_pkt(struct usbtouch_usb *usbtouch,
++ struct pt_regs *regs, unsigned char *pkt, int len);
++
++/* device types */
++enum {
++ DEVTPYE_DUMMY = -1,
++ DEVTYPE_EGALAX,
++ DEVTYPE_PANJIT,
++ DEVTYPE_3M,
++ DEVTYPE_ITM,
++};
++
++static struct usb_device_id usbtouch_devices[] = {
++#ifdef CONFIG_USB_TOUCHSCREEN_EGALAX
++ {USB_DEVICE(0x3823, 0x0001), .driver_info = DEVTYPE_EGALAX},
++ {USB_DEVICE(0x0123, 0x0001), .driver_info = DEVTYPE_EGALAX},
++ {USB_DEVICE(0x0eef, 0x0001), .driver_info = DEVTYPE_EGALAX},
++ {USB_DEVICE(0x0eef, 0x0002), .driver_info = DEVTYPE_EGALAX},
++#endif
++
++#ifdef CONFIG_USB_TOUCHSCREEN_PANJIT
++ {USB_DEVICE(0x134c, 0x0001), .driver_info = DEVTYPE_PANJIT},
++ {USB_DEVICE(0x134c, 0x0002), .driver_info = DEVTYPE_PANJIT},
++ {USB_DEVICE(0x134c, 0x0003), .driver_info = DEVTYPE_PANJIT},
++ {USB_DEVICE(0x134c, 0x0004), .driver_info = DEVTYPE_PANJIT},
++#endif
++
++#ifdef CONFIG_USB_TOUCHSCREEN_3M
++ {USB_DEVICE(0x0596, 0x0001), .driver_info = DEVTYPE_3M},
++#endif
++
++#ifdef CONFIG_USB_TOUCHSCREEN_ITM
++ {USB_DEVICE(0x0403, 0xf9e9), .driver_info = DEVTYPE_ITM},
++#endif
++
++ {}
++};
++
++
++/*****************************************************************************
++ * eGalax part
++ */
++
++#ifdef CONFIG_USB_TOUCHSCREEN_EGALAX
++
++#define EGALAX_PKT_TYPE_MASK 0xFE
++#define EGALAX_PKT_TYPE_REPT 0x80
++#define EGALAX_PKT_TYPE_DIAG 0x0A
++
++static int egalax_read_data(unsigned char *pkt, int *x, int *y, int *touch, int *press)
++{
++ if ((pkt[0] & EGALAX_PKT_TYPE_MASK) != EGALAX_PKT_TYPE_REPT)
++ return 0;
++
++ *x = ((pkt[3] & 0x0F) << 7) | (pkt[4] & 0x7F);
++ *y = ((pkt[1] & 0x0F) << 7) | (pkt[2] & 0x7F);
++ *touch = pkt[0] & 0x01;
++
++ return 1;
++
++}
++
++static int egalax_get_pkt_len(unsigned char *buf)
++{
++ switch (buf[0] & EGALAX_PKT_TYPE_MASK) {
++ case EGALAX_PKT_TYPE_REPT:
++ return 5;
++
++ case EGALAX_PKT_TYPE_DIAG:
++ return buf[1] + 2;
++ }
++
++ return 0;
++}
++
++static void egalax_process(struct usbtouch_usb *usbtouch, struct pt_regs *regs,
++ unsigned char *pkt, int len)
++{
++ unsigned char *buffer;
++ int pkt_len, buf_len, pos;
++
++ /* if the buffer contains data, append */
++ if (unlikely(usbtouch->buf_len)) {
++ int tmp;
++
++ /* if only 1 byte in buffer, add another one to get length */
++ if (usbtouch->buf_len == 1)
++ usbtouch->buffer[1] = pkt[0];
++
++ pkt_len = egalax_get_pkt_len(usbtouch->buffer);
++
++ /* unknown packet: drop everything */
++ if (!pkt_len)
++ return;
++
++ /* append, process */
++ tmp = pkt_len - usbtouch->buf_len;
++ memcpy(usbtouch->buffer + usbtouch->buf_len, pkt, tmp);
++ usbtouch_process_pkt(usbtouch, regs, usbtouch->buffer, pkt_len);
++
++ buffer = pkt + tmp;
++ buf_len = len - tmp;
++ } else {
++ buffer = pkt;
++ buf_len = len;
++ }
++
++ /* only one byte left in buffer */
++ if (unlikely(buf_len == 1)) {
++ usbtouch->buffer[0] = buffer[0];
++ usbtouch->buf_len = 1;
++ return;
++ }
++
++ /* loop over the buffer */
++ pos = 0;
++ while (pos < buf_len) {
++ /* get packet len */
++ pkt_len = egalax_get_pkt_len(buffer + pos);
++
++ /* unknown packet: drop everything */
++ if (unlikely(!pkt_len))
++ return;
++
++ /* full packet: process */
++ if (likely(pkt_len <= buf_len)) {
++ usbtouch_process_pkt(usbtouch, regs, buffer + pos, pkt_len);
++ } else {
++ /* incomplete packet: save in buffer */
++ memcpy(usbtouch->buffer, buffer + pos, buf_len - pos);
++ usbtouch->buf_len = buf_len - pos;
++ }
++ pos += pkt_len;
++ }
++}
++#endif
++
++
++/*****************************************************************************
++ * PanJit Part
++ */
++#ifdef CONFIG_USB_TOUCHSCREEN_PANJIT
++static int panjit_read_data(unsigned char *pkt, int *x, int *y, int *touch, int *press)
++{
++ *x = ((pkt[2] & 0x0F) << 8) | pkt[1];
++ *y = ((pkt[4] & 0x0F) << 8) | pkt[3];
++ *touch = pkt[0] & 0x01;
++
++ return 1;
++}
++#endif
++
++
++/*****************************************************************************
++ * 3M/Microtouch Part
++ */
++#ifdef CONFIG_USB_TOUCHSCREEN_3M
++
++#define MTOUCHUSB_ASYNC_REPORT 1
++#define MTOUCHUSB_RESET 7
++#define MTOUCHUSB_REQ_CTRLLR_ID 10
++
++static int mtouch_read_data(unsigned char *pkt, int *x, int *y, int *touch, int *press)
++{
++ *x = (pkt[8] << 8) | pkt[7];
++ *y = (pkt[10] << 8) | pkt[9];
++ *touch = (pkt[2] & 0x40) ? 1 : 0;
++
++ return 1;
++}
++
++static int mtouch_init(struct usbtouch_usb *usbtouch)
++{
++ int ret;
++
++ ret = usb_control_msg(usbtouch->udev, usb_rcvctrlpipe(usbtouch->udev, 0),
++ MTOUCHUSB_RESET,
++ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
++ 1, 0, NULL, 0, USB_CTRL_SET_TIMEOUT);
++ dbg("%s - usb_control_msg - MTOUCHUSB_RESET - bytes|err: %d",
++ __FUNCTION__, ret);
++ if (ret < 0)
++ return ret;
++
++ ret = usb_control_msg(usbtouch->udev, usb_rcvctrlpipe(usbtouch->udev, 0),
++ MTOUCHUSB_ASYNC_REPORT,
++ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
++ 1, 1, NULL, 0, USB_CTRL_SET_TIMEOUT);
++ dbg("%s - usb_control_msg - MTOUCHUSB_ASYNC_REPORT - bytes|err: %d",
++ __FUNCTION__, ret);
++ if (ret < 0)
++ return ret;
++
++ return 0;
++}
++#endif
++
++
++/*****************************************************************************
++ * ITM Part
++ */
++#ifdef CONFIG_USB_TOUCHSCREEN_ITM
++static int itm_read_data(unsigned char *pkt, int *x, int *y, int *touch, int *press)
++{
++ *x = ((pkt[0] & 0x1F) << 7) | (pkt[3] & 0x7F);
++ *x = ((pkt[1] & 0x1F) << 7) | (pkt[4] & 0x7F);
++ *press = ((pkt[2] & 0x1F) << 7) | (pkt[5] & 0x7F);
++ *touch = ~pkt[7] & 0x20;
++
++ return 1;
++}
++#endif
++
++
++/*****************************************************************************
++ * the different device descriptors
++ */
++static struct usbtouch_device_info usbtouch_dev_info[] = {
++#ifdef CONFIG_USB_TOUCHSCREEN_EGALAX
++ [DEVTYPE_EGALAX] = {
++ .min_xc = 0x0,
++ .max_xc = 0x07ff,
++ .min_yc = 0x0,
++ .max_yc = 0x07ff,
++ .rept_size = 16,
++ .flags = USBTOUCH_FLG_BUFFER,
++ .process_pkt = egalax_process,
++ .read_data = egalax_read_data,
++ },
++#endif
++
++#ifdef CONFIG_USB_TOUCHSCREEN_PANJIT
++ [DEVTYPE_PANJIT] = {
++ .min_xc = 0x0,
++ .max_xc = 0x0fff,
++ .min_yc = 0x0,
++ .max_yc = 0x0fff,
++ .rept_size = 8,
++ .read_data = panjit_read_data,
++ },
++#endif
++
++#ifdef CONFIG_USB_TOUCHSCREEN_3M
++ [DEVTYPE_3M] = {
++ .min_xc = 0x0,
++ .max_xc = 0x4000,
++ .min_yc = 0x0,
++ .max_yc = 0x4000,
++ .rept_size = 11,
++ .read_data = mtouch_read_data,
++ .init = mtouch_init,
++ },
++#endif
++
++#ifdef CONFIG_USB_TOUCHSCREEN_ITM
++ [DEVTYPE_ITM] = {
++ .min_xc = 0x0,
++ .max_xc = 0x0fff,
++ .min_yc = 0x0,
++ .max_yc = 0x0fff,
++ .max_press = 0xff,
++ .rept_size = 8,
++ .read_data = itm_read_data,
++ },
++#endif
++};
++
++
++/*****************************************************************************
++ * Generic Part
++ */
++static void usbtouch_process_pkt(struct usbtouch_usb *usbtouch,
++ struct pt_regs *regs, unsigned char *pkt, int len)
++{
++ int x, y, touch, press;
++ struct usbtouch_device_info *type = usbtouch->type;
++
++ if (!type->read_data(pkt, &x, &y, &touch, &press))
++ return;
++
++ input_regs(usbtouch->input, regs);
++ input_report_key(usbtouch->input, BTN_TOUCH, touch);
++
++ if (swap_xy) {
++ input_report_abs(usbtouch->input, ABS_X, y);
++ input_report_abs(usbtouch->input, ABS_Y, x);
++ } else {
++ input_report_abs(usbtouch->input, ABS_X, x);
++ input_report_abs(usbtouch->input, ABS_Y, y);
++ }
++ if (type->max_press)
++ input_report_abs(usbtouch->input, ABS_PRESSURE, press);
++ input_sync(usbtouch->input);
++}
++
++
++static void usbtouch_irq(struct urb *urb, struct pt_regs *regs)
++{
++ struct usbtouch_usb *usbtouch = urb->context;
++ int retval;
++
++ switch (urb->status) {
++ case 0:
++ /* success */
++ break;
++ case -ETIMEDOUT:
++ /* this urb is timing out */
++ dbg("%s - urb timed out - was the device unplugged?",
++ __FUNCTION__);
++ return;
++ 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;
++ }
++
++ usbtouch->type->process_pkt(usbtouch, regs, usbtouch->data, urb->actual_length);
++
++exit:
++ retval = usb_submit_urb(urb, GFP_ATOMIC);
++ if (retval)
++ err("%s - usb_submit_urb failed with result: %d",
++ __FUNCTION__, retval);
++}
++
++static int usbtouch_open(struct input_dev *input)
++{
++ struct usbtouch_usb *usbtouch = input->private;
++
++ usbtouch->irq->dev = usbtouch->udev;
++
++ if (usb_submit_urb(usbtouch->irq, GFP_KERNEL))
++ return -EIO;
++
++ return 0;
++}
++
++static void usbtouch_close(struct input_dev *input)
++{
++ struct usbtouch_usb *usbtouch = input->private;
++
++ usb_kill_urb(usbtouch->irq);
++}
++
++
++static void usbtouch_free_buffers(struct usb_device *udev,
++ struct usbtouch_usb *usbtouch)
++{
++ if (usbtouch->data)
++ usb_buffer_free(udev, usbtouch->type->rept_size,
++ usbtouch->data, usbtouch->data_dma);
++ kfree(usbtouch->buffer);
++}
++
++
++static int usbtouch_probe(struct usb_interface *intf,
++ const struct usb_device_id *id)
++{
++ struct usbtouch_usb *usbtouch;
++ struct input_dev *input_dev;
++ struct usb_host_interface *interface;
++ struct usb_endpoint_descriptor *endpoint;
++ struct usb_device *udev = interface_to_usbdev(intf);
++ struct usbtouch_device_info *type;
++ int err;
++
++ interface = intf->cur_altsetting;
++ endpoint = &interface->endpoint[0].desc;
++
++ usbtouch = kzalloc(sizeof(struct usbtouch_usb), GFP_KERNEL);
++ input_dev = input_allocate_device();
++ if (!usbtouch || !input_dev)
++ goto out_free;
++
++ type = &usbtouch_dev_info[id->driver_info];
++ usbtouch->type = type;
++ if (!type->process_pkt)
++ type->process_pkt = usbtouch_process_pkt;
++
++ usbtouch->data = usb_buffer_alloc(udev, type->rept_size,
++ SLAB_KERNEL, &usbtouch->data_dma);
++ if (!usbtouch->data)
++ goto out_free;
++
++ if (type->flags & USBTOUCH_FLG_BUFFER) {
++ usbtouch->buffer = kmalloc(type->rept_size, GFP_KERNEL);
++ if (!usbtouch->buffer)
++ goto out_free_buffers;
++ }
++
++ usbtouch->irq = usb_alloc_urb(0, GFP_KERNEL);
++ if (!usbtouch->irq) {
++ dbg("%s - usb_alloc_urb failed: usbtouch->irq", __FUNCTION__);
++ goto out_free_buffers;
++ }
++
++ usbtouch->udev = udev;
++ usbtouch->input = input_dev;
++
++ if (udev->manufacturer)
++ strlcpy(usbtouch->name, udev->manufacturer, sizeof(usbtouch->name));
++
++ if (udev->product) {
++ if (udev->manufacturer)
++ strlcat(usbtouch->name, " ", sizeof(usbtouch->name));
++ strlcat(usbtouch->name, udev->product, sizeof(usbtouch->name));
++ }
++
++ if (!strlen(usbtouch->name))
++ snprintf(usbtouch->name, sizeof(usbtouch->name),
++ "USB Touchscreen %04x:%04x",
++ le16_to_cpu(udev->descriptor.idVendor),
++ le16_to_cpu(udev->descriptor.idProduct));
++
++ usb_make_path(udev, usbtouch->phys, sizeof(usbtouch->phys));
++ strlcpy(usbtouch->phys, "/input0", sizeof(usbtouch->phys));
++
++ input_dev->name = usbtouch->name;
++ input_dev->phys = usbtouch->phys;
++ usb_to_input_id(udev, &input_dev->id);
++ input_dev->cdev.dev = &intf->dev;
++ input_dev->private = usbtouch;
++ input_dev->open = usbtouch_open;
++ input_dev->close = usbtouch_close;
++
++ input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
++ input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
++ input_set_abs_params(input_dev, ABS_X, type->min_xc, type->max_xc, 0, 0);
++ input_set_abs_params(input_dev, ABS_Y, type->min_yc, type->max_yc, 0, 0);
++ if (type->max_press)
++ input_set_abs_params(input_dev, ABS_PRESSURE, type->min_press,
++ type->max_press, 0, 0);
++
++ usb_fill_int_urb(usbtouch->irq, usbtouch->udev,
++ usb_rcvintpipe(usbtouch->udev, 0x81),
++ usbtouch->data, type->rept_size,
++ usbtouch_irq, usbtouch, endpoint->bInterval);
++
++ usbtouch->irq->transfer_dma = usbtouch->data_dma;
++ usbtouch->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
++
++ /* device specific init */
++ if (type->init) {
++ err = type->init(usbtouch);
++ if (err) {
++ dbg("%s - type->init() failed, err: %d", __FUNCTION__, err);
++ goto out_free_buffers;
++ }
++ }
++
++ err = input_register_device(usbtouch->input);
++ if (err) {
++ dbg("%s - input_register_device failed, err: %d", __FUNCTION__, err);
++ goto out_free_buffers;
++ }
++
++ usb_set_intfdata(intf, usbtouch);
++
++ return 0;
++
++out_free_buffers:
++ usbtouch_free_buffers(udev, usbtouch);
++out_free:
++ input_free_device(input_dev);
++ kfree(usbtouch);
++ return -ENOMEM;
++}
++
++static void usbtouch_disconnect(struct usb_interface *intf)
++{
++ struct usbtouch_usb *usbtouch = usb_get_intfdata(intf);
++
++ dbg("%s - called", __FUNCTION__);
++
++ if (!usbtouch)
++ return;
++
++ dbg("%s - usbtouch is initialized, cleaning up", __FUNCTION__);
++ usb_set_intfdata(intf, NULL);
++ usb_kill_urb(usbtouch->irq);
++ input_unregister_device(usbtouch->input);
++ usb_free_urb(usbtouch->irq);
++ usbtouch_free_buffers(interface_to_usbdev(intf), usbtouch);
++ kfree(usbtouch);
++}
++
++MODULE_DEVICE_TABLE(usb, usbtouch_devices);
++
++static struct usb_driver usbtouch_driver = {
++ .name = "usbtouchscreen",
++ .probe = usbtouch_probe,
++ .disconnect = usbtouch_disconnect,
++ .id_table = usbtouch_devices,
++};
++
++static int __init usbtouch_init(void)
++{
++ return usb_register(&usbtouch_driver);
++}
++
++static void __exit usbtouch_cleanup(void)
++{
++ usb_deregister(&usbtouch_driver);
++}
++
++module_init(usbtouch_init);
++module_exit(usbtouch_cleanup);
++
++MODULE_AUTHOR(DRIVER_AUTHOR);
++MODULE_DESCRIPTION(DRIVER_DESC);
++MODULE_LICENSE("GPL");
++
++MODULE_ALIAS("touchkitusb");
++MODULE_ALIAS("itmtouch");
++MODULE_ALIAS("mtouchusb");