]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 26 Mar 2009 18:17:39 +0000 (11:17 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 26 Mar 2009 18:17:39 +0000 (11:17 -0700)
* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6: (97 commits)
  USB: qcserial: add device id for HP devices
  USB: isp1760: Add a delay before reading the SKIPMAP registers in isp1760-hcd.c
  USB: allow malformed LANGID descriptors
  USB: pxa27x_udc: typo fixes and code cleanups
  USB: gadget: gadget zero uses new suspend/resume hooks
  USB: gadget: composite device-level suspend/resume hooks
  USB: r8a66597-hcd: suspend/resume support
  USB: more u32 conversion after transfer_buffer_length and actual_length
  USB: Fix cp2101 USB serial device driver termios functions for console use
  USB: CP2101 New Device ID
  USB: ipaq: handle 4 endpoint devices
  USB: S3C: Move usb-control.h to platform include
  USB: ohci-hcd: Add ARCH_S3C24XX to the ohci-s3c2410.c glue
  USB: pedantic: spelling correction in comment for ch9.h
  USB: host: fix sparse warning: Using plain integer as NULL pointer
  USB: ohci-s3c2410: fix name of bus clock
  USB: ohci-s3c2410: remove <mach/hardware.h> include
  USB: serial: rename cp2101 driver to cp210x
  USB: CP2101 Reduce Error Logging
  USB: CP2101 Support AN205 baud rates
  ...

157 files changed:
Documentation/usb/usbmon.txt
arch/arm/mach-s3c2410/usb-simtec.c
arch/arm/plat-s3c/include/plat/usb-control.h [moved from arch/arm/mach-s3c2410/include/mach/usb-control.h with 84% similarity]
drivers/block/ub.c
drivers/usb/Makefile
drivers/usb/class/usblp.c
drivers/usb/core/devices.c
drivers/usb/core/devio.c
drivers/usb/core/endpoint.c
drivers/usb/core/hcd.c
drivers/usb/core/hub.c
drivers/usb/core/message.c
drivers/usb/core/quirks.c
drivers/usb/core/sysfs.c
drivers/usb/core/urb.c
drivers/usb/gadget/Kconfig
drivers/usb/gadget/amd5536udc.c
drivers/usb/gadget/atmel_usba_udc.c
drivers/usb/gadget/cdc2.c
drivers/usb/gadget/ci13xxx_udc.c
drivers/usb/gadget/composite.c
drivers/usb/gadget/dummy_hcd.c
drivers/usb/gadget/epautoconf.c
drivers/usb/gadget/ether.c
drivers/usb/gadget/f_acm.c
drivers/usb/gadget/f_ecm.c
drivers/usb/gadget/f_loopback.c
drivers/usb/gadget/f_obex.c
drivers/usb/gadget/f_phonet.c
drivers/usb/gadget/f_rndis.c
drivers/usb/gadget/f_serial.c
drivers/usb/gadget/f_sourcesink.c
drivers/usb/gadget/f_subset.c
drivers/usb/gadget/file_storage.c
drivers/usb/gadget/fsl_usb2_udc.c
drivers/usb/gadget/g_zero.h
drivers/usb/gadget/gmidi.c
drivers/usb/gadget/goku_udc.c
drivers/usb/gadget/imx_udc.c
drivers/usb/gadget/imx_udc.h
drivers/usb/gadget/inode.c
drivers/usb/gadget/lh7a40x_udc.c
drivers/usb/gadget/net2280.c
drivers/usb/gadget/printer.c
drivers/usb/gadget/pxa27x_udc.c
drivers/usb/gadget/pxa27x_udc.h
drivers/usb/gadget/serial.c
drivers/usb/gadget/u_serial.c
drivers/usb/gadget/zero.c
drivers/usb/host/Kconfig
drivers/usb/host/ehci-hcd.c
drivers/usb/host/ehci-q.c
drivers/usb/host/ehci-sched.c
drivers/usb/host/ehci.h
drivers/usb/host/hwa-hc.c
drivers/usb/host/isp116x-hcd.c
drivers/usb/host/isp116x.h
drivers/usb/host/isp1760-hcd.c
drivers/usb/host/isp1760-hcd.h
drivers/usb/host/isp1760-if.c
drivers/usb/host/ohci-hcd.c
drivers/usb/host/ohci-s3c2410.c
drivers/usb/host/oxu210hp-hcd.c
drivers/usb/host/oxu210hp.h
drivers/usb/host/pci-quirks.c
drivers/usb/host/r8a66597-hcd.c
drivers/usb/host/r8a66597.h
drivers/usb/host/sl811-hcd.c
drivers/usb/host/uhci-debug.c
drivers/usb/host/uhci-hcd.h
drivers/usb/host/uhci-q.c
drivers/usb/image/mdc800.c
drivers/usb/misc/Kconfig
drivers/usb/misc/Makefile
drivers/usb/misc/ftdi-elan.c
drivers/usb/misc/phidget.c [deleted file]
drivers/usb/misc/phidget.h [deleted file]
drivers/usb/misc/phidgetkit.c [deleted file]
drivers/usb/misc/phidgetmotorcontrol.c [deleted file]
drivers/usb/misc/phidgetservo.c [deleted file]
drivers/usb/mon/mon_bin.c
drivers/usb/musb/Kconfig
drivers/usb/musb/davinci.c
drivers/usb/musb/davinci.h
drivers/usb/musb/musb_core.c
drivers/usb/musb/musb_core.h
drivers/usb/musb/musb_host.c
drivers/usb/musb/musb_virthub.c
drivers/usb/otg/Kconfig
drivers/usb/otg/Makefile
drivers/usb/otg/gpio_vbus.c
drivers/usb/otg/nop-usb-xceiv.c [new file with mode: 0644]
drivers/usb/otg/twl4030-usb.c
drivers/usb/serial/Kconfig
drivers/usb/serial/Makefile
drivers/usb/serial/ch341.c
drivers/usb/serial/cp210x.c [moved from drivers/usb/serial/cp2101.c with 85% similarity]
drivers/usb/serial/ftdi_sio.c
drivers/usb/serial/generic.c
drivers/usb/serial/ipaq.c
drivers/usb/serial/keyspan.c
drivers/usb/serial/opticon.c
drivers/usb/serial/option.c
drivers/usb/serial/qcserial.c [new file with mode: 0644]
drivers/usb/serial/symbolserial.c [new file with mode: 0644]
drivers/usb/serial/usb-serial.c
drivers/usb/storage/Kconfig
drivers/usb/storage/Makefile
drivers/usb/storage/alauda.c
drivers/usb/storage/alauda.h [deleted file]
drivers/usb/storage/cypress_atacb.c
drivers/usb/storage/datafab.c
drivers/usb/storage/datafab.h [deleted file]
drivers/usb/storage/freecom.c
drivers/usb/storage/isd200.c
drivers/usb/storage/jumpshot.c
drivers/usb/storage/jumpshot.h [deleted file]
drivers/usb/storage/karma.c
drivers/usb/storage/karma.h [deleted file]
drivers/usb/storage/libusual.c
drivers/usb/storage/onetouch.c
drivers/usb/storage/onetouch.h [deleted file]
drivers/usb/storage/protocol.c
drivers/usb/storage/scsiglue.c
drivers/usb/storage/sddr09.c
drivers/usb/storage/sddr09.h [deleted file]
drivers/usb/storage/sddr55.c
drivers/usb/storage/shuttle_usbat.c
drivers/usb/storage/shuttle_usbat.h [deleted file]
drivers/usb/storage/transport.c
drivers/usb/storage/unusual_alauda.h [moved from drivers/usb/storage/freecom.h with 60% similarity]
drivers/usb/storage/unusual_cypress.h [new file with mode: 0644]
drivers/usb/storage/unusual_datafab.h [new file with mode: 0644]
drivers/usb/storage/unusual_devs.h
drivers/usb/storage/unusual_freecom.h [moved from drivers/usb/storage/cypress_atacb.h with 68% similarity]
drivers/usb/storage/unusual_isd200.h [new file with mode: 0644]
drivers/usb/storage/unusual_jumpshot.h [moved from drivers/usb/storage/sddr55.h with 63% similarity]
drivers/usb/storage/unusual_karma.h [moved from drivers/usb/storage/isd200.h with 63% similarity]
drivers/usb/storage/unusual_onetouch.h [new file with mode: 0644]
drivers/usb/storage/unusual_sddr09.h [new file with mode: 0644]
drivers/usb/storage/unusual_sddr55.h [new file with mode: 0644]
drivers/usb/storage/unusual_usbat.h [new file with mode: 0644]
drivers/usb/storage/usb.c
drivers/usb/storage/usb.h
drivers/usb/storage/usual-tables.c [new file with mode: 0644]
drivers/usb/usb-skeleton.c
drivers/usb/wusbcore/cbaf.c
drivers/usb/wusbcore/devconnect.c
drivers/usb/wusbcore/security.c
include/linux/usb.h
include/linux/usb/ch9.h
include/linux/usb/composite.h
include/linux/usb/gadget.h
include/linux/usb/otg.h
include/linux/usb/quirks.h
include/linux/usb/serial.h
include/linux/usb_usual.h

index 270481906dc80d1b25a0c29f607ef55e83ae16be..6c3c625b7f30b260ceb5bf2363b63adced7c7d68 100644 (file)
@@ -229,16 +229,26 @@ struct usbmon_packet {
        int status;             /* 28: */
        unsigned int length;    /* 32: Length of data (submitted or actual) */
        unsigned int len_cap;   /* 36: Delivered length */
-       unsigned char setup[8]; /* 40: Only for Control 'S' */
-};                             /* 48 bytes total */
+       union {                 /* 40: */
+               unsigned char setup[SETUP_LEN]; /* Only for Control S-type */
+               struct iso_rec {                /* Only for ISO */
+                       int error_count;
+                       int numdesc;
+               } iso;
+       } s;
+       int interval;           /* 48: Only for Interrupt and ISO */
+       int start_frame;        /* 52: For ISO */
+       unsigned int xfer_flags; /* 56: copy of URB's transfer_flags */
+       unsigned int ndesc;     /* 60: Actual number of ISO descriptors */
+};                             /* 64 total length */
 
 These events can be received from a character device by reading with read(2),
-with an ioctl(2), or by accessing the buffer with mmap.
+with an ioctl(2), or by accessing the buffer with mmap. However, read(2)
+only returns first 48 bytes for compatibility reasons.
 
 The character device is usually called /dev/usbmonN, where N is the USB bus
 number. Number zero (/dev/usbmon0) is special and means "all buses".
-However, this feature is not implemented yet. Note that specific naming
-policy is set by your Linux distribution.
+Note that specific naming policy is set by your Linux distribution.
 
 If you create /dev/usbmon0 by hand, make sure that it is owned by root
 and has mode 0600. Otherwise, unpriviledged users will be able to snoop
@@ -279,9 +289,10 @@ size is out of [unspecified] bounds for this kernel, the call fails with
 This call returns the current size of the buffer in bytes.
 
  MON_IOCX_GET, defined as _IOW(MON_IOC_MAGIC, 6, struct mon_get_arg)
+ MON_IOCX_GETX, defined as _IOW(MON_IOC_MAGIC, 10, struct mon_get_arg)
 
-This call waits for events to arrive if none were in the kernel buffer,
-then returns the first event. Its argument is a pointer to the following
+These calls wait for events to arrive if none were in the kernel buffer,
+then return the first event. The argument is a pointer to the following
 structure:
 
 struct mon_get_arg {
@@ -294,6 +305,8 @@ Before the call, hdr, data, and alloc should be filled. Upon return, the area
 pointed by hdr contains the next event structure, and the data buffer contains
 the data, if any. The event is removed from the kernel buffer.
 
+The MON_IOCX_GET copies 48 bytes, MON_IOCX_GETX copies 64 bytes.
+
  MON_IOCX_MFETCH, defined as _IOWR(MON_IOC_MAGIC, 7, struct mon_mfetch_arg)
 
 This ioctl is primarily used when the application accesses the buffer
index 6078f09b7df5d9311cc42ab7796e9b16271cb10c..8331e8d97e20511e8926225df9fa1c5e7439718b 100644 (file)
 
 #include <mach/bast-map.h>
 #include <mach/bast-irq.h>
-#include <mach/usb-control.h>
 #include <mach/regs-gpio.h>
 
 #include <mach/hardware.h>
 #include <asm/irq.h>
 
+#include <plat/usb-control.h>
 #include <plat/devs.h>
+
 #include "usb-simtec.h"
 
 /* control power and monitor over-current events on various Simtec
similarity index 84%
rename from arch/arm/mach-s3c2410/include/mach/usb-control.h
rename to arch/arm/plat-s3c/include/plat/usb-control.h
index cd91d1591f31c7ae868a259d5bcc9033eae21f21..822c87fe948ebbf345c6f11cf4c17bb6a091d740 100644 (file)
@@ -1,9 +1,9 @@
-/* arch/arm/mach-s3c2410/include/mach/usb-control.h
+/* arch/arm/plat-s3c/include/plat/usb-control.h
  *
  * Copyright (c) 2004 Simtec Electronics
  *     Ben Dooks <ben@simtec.co.uk>
  *
- * S3C2410 - usb port information
+ * S3C - USB host port information
  *
  * 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
@@ -11,7 +11,7 @@
 */
 
 #ifndef __ASM_ARCH_USBCONTROL_H
-#define __ASM_ARCH_USBCONTROL_H "arch/arm/mach-s3c2410/include/mach/usb-control.h"
+#define __ASM_ARCH_USBCONTROL_H
 
 #define S3C_HCDFLG_USED        (1)
 
index 12fb816db7b0eaead4f086f229089338b6ca5745..69b7f8e77596eefa60d4e60bafb04391f0148510 100644 (file)
@@ -391,7 +391,7 @@ static int ub_probe_lun(struct ub_dev *sc, int lnum);
  */
 #ifdef CONFIG_USB_LIBUSUAL
 
-#define ub_usb_ids  storage_usb_ids
+#define ub_usb_ids  usb_storage_usb_ids
 #else
 
 static struct usb_device_id ub_usb_ids[] = {
@@ -2146,10 +2146,9 @@ static int ub_get_pipes(struct ub_dev *sc, struct usb_device *dev,
                ep = &altsetting->endpoint[i].desc;
 
                /* Is it a BULK endpoint? */
-               if ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
-                               == USB_ENDPOINT_XFER_BULK) {
+               if (usb_endpoint_xfer_bulk(ep)) {
                        /* BULK in or out? */
-                       if (ep->bEndpointAddress & USB_DIR_IN) {
+                       if (usb_endpoint_dir_in(ep)) {
                                if (ep_in == NULL)
                                        ep_in = ep;
                        } else {
@@ -2168,9 +2167,9 @@ static int ub_get_pipes(struct ub_dev *sc, struct usb_device *dev,
        sc->send_ctrl_pipe = usb_sndctrlpipe(dev, 0);
        sc->recv_ctrl_pipe = usb_rcvctrlpipe(dev, 0);
        sc->send_bulk_pipe = usb_sndbulkpipe(dev,
-               ep_out->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
+               usb_endpoint_num(ep_out));
        sc->recv_bulk_pipe = usb_rcvbulkpipe(dev, 
-               ep_in->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
+               usb_endpoint_num(ep_in));
 
        return 0;
 }
index b2ceb4aff2330423150fcb48e69e637e88dca548..89299a5ce1688cbf114f2ee68993cdca6febc619 100644 (file)
@@ -19,6 +19,7 @@ obj-$(CONFIG_USB_SL811_HCD)   += host/
 obj-$(CONFIG_USB_U132_HCD)     += host/
 obj-$(CONFIG_USB_R8A66597_HCD) += host/
 obj-$(CONFIG_USB_HWA_HCD)      += host/
+obj-$(CONFIG_USB_ISP1760_HCD)  += host/
 
 obj-$(CONFIG_USB_C67X00_HCD)   += c67x00/
 
index 3f3ee1351930ee44c01022e8251c172a15729355..d2747a49b9744bacf2962abbe2ea1b8bd3b087b5 100644 (file)
@@ -880,16 +880,19 @@ static int usblp_wwait(struct usblp *usblp, int nonblock)
                if (rc <= 0)
                        break;
 
-               if (usblp->flags & LP_ABORT) {
-                       if (schedule_timeout(msecs_to_jiffies(5000)) == 0) {
+               if (schedule_timeout(msecs_to_jiffies(1500)) == 0) {
+                       if (usblp->flags & LP_ABORT) {
                                err = usblp_check_status(usblp, err);
                                if (err == 1) { /* Paper out */
                                        rc = -ENOSPC;
                                        break;
                                }
+                       } else {
+                               /* Prod the printer, Gentoo#251237. */
+                               mutex_lock(&usblp->mut);
+                               usblp_read_status(usblp, usblp->statusbuf);
+                               mutex_unlock(&usblp->mut);
                        }
-               } else {
-                       schedule();
                }
        }
        set_current_state(TASK_RUNNING);
index 6ec38175a8170129a58f3954d7c438e488737a09..73c108d117b4b3da95587c5366a4498a695a8e74 100644 (file)
@@ -187,7 +187,7 @@ static char *usb_dump_endpoint_descriptor(int speed, char *start, char *end,
        }
 
        /* this isn't checking for illegal values */
-       switch (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
+       switch (usb_endpoint_type(desc)) {
        case USB_ENDPOINT_XFER_CONTROL:
                type = "Ctrl";
                if (speed == USB_SPEED_HIGH)    /* uframes per NAK */
index 6585f527e3817a7eca61726b76e7af22d683b535..df3c539f652ad68767d8ce7e424493e91d44d109 100644 (file)
@@ -104,7 +104,7 @@ MODULE_PARM_DESC(usbfs_snoop, "true to log all usbfs traffic");
 
 #define        MAX_USBFS_BUFFER_SIZE   16384
 
-static inline int connected(struct dev_state *ps)
+static int connected(struct dev_state *ps)
 {
        return (!list_empty(&ps->list) &&
                        ps->dev->state != USB_STATE_NOTATTACHED);
@@ -248,7 +248,7 @@ static void free_async(struct async *as)
        kfree(as);
 }
 
-static inline void async_newpending(struct async *as)
+static void async_newpending(struct async *as)
 {
        struct dev_state *ps = as->ps;
        unsigned long flags;
@@ -258,7 +258,7 @@ static inline void async_newpending(struct async *as)
        spin_unlock_irqrestore(&ps->lock, flags);
 }
 
-static inline void async_removepending(struct async *as)
+static void async_removepending(struct async *as)
 {
        struct dev_state *ps = as->ps;
        unsigned long flags;
@@ -268,7 +268,7 @@ static inline void async_removepending(struct async *as)
        spin_unlock_irqrestore(&ps->lock, flags);
 }
 
-static inline struct async *async_getcompleted(struct dev_state *ps)
+static struct async *async_getcompleted(struct dev_state *ps)
 {
        unsigned long flags;
        struct async *as = NULL;
@@ -283,7 +283,7 @@ static inline struct async *async_getcompleted(struct dev_state *ps)
        return as;
 }
 
-static inline struct async *async_getpending(struct dev_state *ps,
+static struct async *async_getpending(struct dev_state *ps,
                                             void __user *userurb)
 {
        unsigned long flags;
@@ -302,7 +302,7 @@ static inline struct async *async_getpending(struct dev_state *ps,
 
 static void snoop_urb(struct urb *urb, void __user *userurb)
 {
-       int j;
+       unsigned j;
        unsigned char *data = urb->transfer_buffer;
 
        if (!usbfs_snoop)
@@ -311,9 +311,9 @@ static void snoop_urb(struct urb *urb, void __user *userurb)
        dev_info(&urb->dev->dev, "direction=%s\n",
                        usb_urb_dir_in(urb) ? "IN" : "OUT");
        dev_info(&urb->dev->dev, "userurb=%p\n", userurb);
-       dev_info(&urb->dev->dev, "transfer_buffer_length=%d\n",
+       dev_info(&urb->dev->dev, "transfer_buffer_length=%u\n",
                 urb->transfer_buffer_length);
-       dev_info(&urb->dev->dev, "actual_length=%d\n", urb->actual_length);
+       dev_info(&urb->dev->dev, "actual_length=%u\n", urb->actual_length);
        dev_info(&urb->dev->dev, "data: ");
        for (j = 0; j < urb->transfer_buffer_length; ++j)
                printk("%02x ", data[j]);
@@ -376,7 +376,7 @@ static void destroy_async_on_interface(struct dev_state *ps,
        destroy_async(ps, &hitlist);
 }
 
-static inline void destroy_all_async(struct dev_state *ps)
+static void destroy_all_async(struct dev_state *ps)
 {
        destroy_async(ps, &ps->async_pending);
 }
@@ -525,7 +525,8 @@ static int check_ctrlrecip(struct dev_state *ps, unsigned int requesttype,
 {
        int ret = 0;
 
-       if (ps->dev->state != USB_STATE_ADDRESS
+       if (ps->dev->state != USB_STATE_UNAUTHENTICATED
+        && ps->dev->state != USB_STATE_ADDRESS
         && ps->dev->state != USB_STATE_CONFIGURED)
                return -EHOSTUNREACH;
        if (USB_TYPE_VENDOR == (USB_TYPE_MASK & requesttype))
index e1710f260b4fee1ad57a3cc41429f232506cd7d5..40dee2ac0133740ee97e37932a6181247b94e22a 100644 (file)
@@ -66,7 +66,7 @@ static ssize_t show_ep_type(struct device *dev, struct device_attribute *attr,
        struct ep_device *ep = to_ep_device(dev);
        char *type = "unknown";
 
-       switch (ep->desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
+       switch (usb_endpoint_type(ep->desc)) {
        case USB_ENDPOINT_XFER_CONTROL:
                type = "Control";
                break;
@@ -94,7 +94,7 @@ static ssize_t show_ep_interval(struct device *dev,
 
        in = (ep->desc->bEndpointAddress & USB_DIR_IN);
 
-       switch (ep->desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
+       switch (usb_endpoint_type(ep->desc)) {
        case USB_ENDPOINT_XFER_CONTROL:
                if (ep->udev->speed == USB_SPEED_HIGH)  /* uframes per NAK */
                        interval = ep->desc->bInterval;
@@ -131,10 +131,9 @@ static ssize_t show_ep_direction(struct device *dev,
        struct ep_device *ep = to_ep_device(dev);
        char *direction;
 
-       if ((ep->desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
-                       USB_ENDPOINT_XFER_CONTROL)
+       if (usb_endpoint_xfer_control(ep->desc))
                direction = "both";
-       else if (ep->desc->bEndpointAddress & USB_DIR_IN)
+       else if (usb_endpoint_dir_in(ep->desc))
                direction = "in";
        else
                direction = "out";
index 3c711db55d86b982663620d5966108884acefaa0..81fa8506825d444f424db8d506b8a67dc1b8709d 100644 (file)
@@ -279,9 +279,9 @@ static const u8 hs_rh_config_descriptor [] = {
  * helper routine for returning string descriptors in UTF-16LE
  * input can actually be ISO-8859-1; ASCII is its 7-bit subset
  */
-static int ascii2utf (char *s, u8 *utf, int utfmax)
+static unsigned ascii2utf(char *s, u8 *utf, int utfmax)
 {
-       int retval;
+       unsigned retval;
 
        for (retval = 0; *s && utfmax > 1; utfmax -= 2, retval += 2) {
                *utf++ = *s++;
@@ -304,19 +304,15 @@ static int ascii2utf (char *s, u8 *utf, int utfmax)
  * Produces either a manufacturer, product or serial number string for the
  * virtual root hub device.
  */
-static int rh_string (
-       int             id,
-       struct usb_hcd  *hcd,
-       u8              *data,
-       int             len
-) {
+static unsigned rh_string(int id, struct usb_hcd *hcd, u8 *data, unsigned len)
+{
        char buf [100];
 
        // language ids
        if (id == 0) {
                buf[0] = 4;    buf[1] = 3;      /* 4 bytes string data */
                buf[2] = 0x09; buf[3] = 0x04;   /* MSFT-speak for "en-us" */
-               len = min (len, 4);
+               len = min_t(unsigned, len, 4);
                memcpy (data, buf, len);
                return len;
 
@@ -332,10 +328,7 @@ static int rh_string (
        } else if (id == 3) {
                snprintf (buf, sizeof buf, "%s %s %s", init_utsname()->sysname,
                        init_utsname()->release, hcd->driver->description);
-
-       // unsupported IDs --> "protocol stall"
-       } else
-               return -EPIPE;
+       }
 
        switch (len) {          /* All cases fall through */
        default:
@@ -360,9 +353,8 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb)
        u8              tbuf [sizeof (struct usb_hub_descriptor)]
                __attribute__((aligned(4)));
        const u8        *bufp = tbuf;
-       int             len = 0;
+       unsigned        len = 0;
        int             status;
-       int             n;
        u8              patch_wakeup = 0;
        u8              patch_protocol = 0;
 
@@ -456,10 +448,11 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb)
                                patch_wakeup = 1;
                        break;
                case USB_DT_STRING << 8:
-                       n = rh_string (wValue & 0xff, hcd, ubuf, wLength);
-                       if (n < 0)
+                       if ((wValue & 0xff) < 4)
+                               urb->actual_length = rh_string(wValue & 0xff,
+                                               hcd, ubuf, wLength);
+                       else /* unsupported IDs --> "protocol stall" */
                                goto error;
-                       urb->actual_length = n;
                        break;
                default:
                        goto error;
@@ -629,7 +622,7 @@ static int rh_queue_status (struct usb_hcd *hcd, struct urb *urb)
 {
        int             retval;
        unsigned long   flags;
-       int             len = 1 + (urb->dev->maxchild / 8);
+       unsigned        len = 1 + (urb->dev->maxchild / 8);
 
        spin_lock_irqsave (&hcd_root_hub_lock, flags);
        if (hcd->status_urb || urb->transfer_buffer_length < len) {
@@ -901,7 +894,7 @@ static int register_root_hub(struct usb_hcd *hcd)
 
        mutex_lock(&usb_bus_list_lock);
 
-       usb_dev->ep0.desc.wMaxPacketSize = __constant_cpu_to_le16(64);
+       usb_dev->ep0.desc.wMaxPacketSize = cpu_to_le16(64);
        retval = usb_get_device_descriptor(usb_dev, USB_DT_DEVICE_SIZE);
        if (retval != sizeof usb_dev->descriptor) {
                mutex_unlock(&usb_bus_list_lock);
index cd50d86029e7a719ed5bff47db80e6fca3cb7e6b..be86ae3f40881516d529a894319ed52c71086b82 100644 (file)
@@ -392,7 +392,7 @@ static void hub_irq(struct urb *urb)
 {
        struct usb_hub *hub = urb->context;
        int status = urb->status;
-       int i;
+       unsigned i;
        unsigned long bits;
 
        switch (status) {
@@ -1305,6 +1305,7 @@ void usb_set_device_state(struct usb_device *udev,
                recursively_mark_NOTATTACHED(udev);
        spin_unlock_irqrestore(&device_state_lock, flags);
 }
+EXPORT_SYMBOL_GPL(usb_set_device_state);
 
 /*
  * WUSB devices are simple: they have no hubs behind, so the mapping
@@ -2471,20 +2472,20 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,
         */
        switch (udev->speed) {
        case USB_SPEED_VARIABLE:        /* fixed at 512 */
-               udev->ep0.desc.wMaxPacketSize = __constant_cpu_to_le16(512);
+               udev->ep0.desc.wMaxPacketSize = cpu_to_le16(512);
                break;
        case USB_SPEED_HIGH:            /* fixed at 64 */
-               udev->ep0.desc.wMaxPacketSize = __constant_cpu_to_le16(64);
+               udev->ep0.desc.wMaxPacketSize = cpu_to_le16(64);
                break;
        case USB_SPEED_FULL:            /* 8, 16, 32, or 64 */
                /* to determine the ep0 maxpacket size, try to read
                 * the device descriptor to get bMaxPacketSize0 and
                 * then correct our initial guess.
                 */
-               udev->ep0.desc.wMaxPacketSize = __constant_cpu_to_le16(64);
+               udev->ep0.desc.wMaxPacketSize = cpu_to_le16(64);
                break;
        case USB_SPEED_LOW:             /* fixed at 8 */
-               udev->ep0.desc.wMaxPacketSize = __constant_cpu_to_le16(8);
+               udev->ep0.desc.wMaxPacketSize = cpu_to_le16(8);
                break;
        default:
                goto fail;
@@ -3392,10 +3393,10 @@ static int usb_reset_and_verify_device(struct usb_device *udev)
                udev->descriptor = descriptor;  /* for disconnect() calls */
                goto re_enumerate;
        }
-  
+
+       /* Restore the device's previous configuration */
        if (!udev->actconfig)
                goto done;
-
        ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
                        USB_REQ_SET_CONFIGURATION, 0,
                        udev->actconfig->desc.bConfigurationValue, 0,
@@ -3408,16 +3409,25 @@ static int usb_reset_and_verify_device(struct usb_device *udev)
        }
        usb_set_device_state(udev, USB_STATE_CONFIGURED);
 
+       /* Put interfaces back into the same altsettings as before.
+        * Don't bother to send the Set-Interface request for interfaces
+        * that were already in altsetting 0; besides being unnecessary,
+        * many devices can't handle it.  Instead just reset the host-side
+        * endpoint state.
+        */
        for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) {
                struct usb_interface *intf = udev->actconfig->interface[i];
                struct usb_interface_descriptor *desc;
 
-               /* set_interface resets host side toggle even
-                * for altsetting zero.  the interface may have no driver.
-                */
                desc = &intf->cur_altsetting->desc;
-               ret = usb_set_interface(udev, desc->bInterfaceNumber,
-                       desc->bAlternateSetting);
+               if (desc->bAlternateSetting == 0) {
+                       usb_disable_interface(udev, intf, true);
+                       usb_enable_interface(udev, intf, true);
+                       ret = 0;
+               } else {
+                       ret = usb_set_interface(udev, desc->bInterfaceNumber,
+                                       desc->bAlternateSetting);
+               }
                if (ret < 0) {
                        dev_err(&udev->dev, "failed to restore interface %d "
                                "altsetting %d (error=%d)\n",
index 49e7f56e0d7f72ea14800a3caf719538897234e3..30a0690f3683b346215d3bbd3235cc7a8c87cba3 100644 (file)
@@ -59,7 +59,7 @@ static int usb_start_wait_urb(struct urb *urb, int timeout, int *actual_length)
                retval = (ctx.status == -ENOENT ? -ETIMEDOUT : ctx.status);
 
                dev_dbg(&urb->dev->dev,
-                       "%s timed out on ep%d%s len=%d/%d\n",
+                       "%s timed out on ep%d%s len=%u/%u\n",
                        current->comm,
                        usb_endpoint_num(&urb->ep->desc),
                        usb_urb_dir_in(urb) ? "in" : "out",
@@ -804,18 +804,16 @@ int usb_string(struct usb_device *dev, int index, char *buf, size_t size)
                        dev_err(&dev->dev,
                                "string descriptor 0 read error: %d\n",
                                err);
-                       goto errout;
                } else if (err < 4) {
                        dev_err(&dev->dev, "string descriptor 0 too short\n");
-                       err = -EINVAL;
-                       goto errout;
                } else {
-                       dev->have_langid = 1;
                        dev->string_langid = tbuf[2] | (tbuf[3] << 8);
                        /* always use the first langid listed */
                        dev_dbg(&dev->dev, "default language 0x%04x\n",
                                dev->string_langid);
                }
+
+               dev->have_langid = 1;
        }
 
        err = usb_string_sub(dev, dev->string_langid, index, tbuf);
@@ -1719,7 +1717,8 @@ free_interfaces:
        }
        kfree(new_interfaces);
 
-       if (cp->string == NULL)
+       if (cp->string == NULL &&
+                       !(dev->quirks & USB_QUIRK_CONFIG_INTF_STRINGS))
                cp->string = usb_cache_string(dev, cp->desc.iConfiguration);
 
        /* Now that all the interfaces are set up, register them
index c070b34b669de70da98c450eaf7ac4d48e85ec93..ab93918d92076dedec3575b49e5eaacfb2c32e71 100644 (file)
@@ -54,6 +54,10 @@ static const struct usb_device_id usb_quirk_list[] = {
        { USB_DEVICE(0x0638, 0x0a13), .driver_info =
          USB_QUIRK_STRING_FETCH_255 },
 
+       /* Saitek Cyborg Gold Joystick */
+       { USB_DEVICE(0x06a3, 0x0006), .driver_info =
+                       USB_QUIRK_CONFIG_INTF_STRINGS },
+
        /* M-Systems Flash Disk Pioneers */
        { USB_DEVICE(0x08ec, 0x1000), .driver_info = USB_QUIRK_RESET_RESUME },
 
index 4cc2456ef3be17fa88b16ac91bb29f1f9f30422e..c6678919792729b0c0548f6aa15592efc50e1fd1 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/usb.h>
+#include <linux/usb/quirks.h>
 #include "usb.h"
 
 /* Active configuration fields */
@@ -813,7 +814,8 @@ int usb_create_sysfs_intf_files(struct usb_interface *intf)
        if (intf->sysfs_files_created || intf->unregistering)
                return 0;
 
-       if (alt->string == NULL)
+       if (alt->string == NULL &&
+                       !(udev->quirks & USB_QUIRK_CONFIG_INTF_STRINGS))
                alt->string = usb_cache_string(udev, alt->desc.iInterface);
        if (alt->string)
                retval = device_create_file(&intf->dev, &dev_attr_interface);
index 58bc5e3c25603dcaf2cf073c85012006b61b6545..3376055f36e7349057531b41c080832c5bd04623 100644 (file)
@@ -295,7 +295,7 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
        if (!urb || urb->hcpriv || !urb->complete)
                return -EINVAL;
        dev = urb->dev;
-       if ((!dev) || (dev->state < USB_STATE_DEFAULT))
+       if ((!dev) || (dev->state < USB_STATE_UNAUTHENTICATED))
                return -ENODEV;
 
        /* For now, get the endpoint from the pipe.  Eventually drivers
@@ -370,7 +370,7 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
        }
 
        /* the I/O buffer must be mapped/unmapped, except when length=0 */
-       if (urb->transfer_buffer_length < 0)
+       if (urb->transfer_buffer_length > INT_MAX)
                return -EMSGSIZE;
 
 #ifdef DEBUG
index e55fef52a5dc5797c02121e0d7482d528a66144f..770b3eaa91847d633c2db26590480936f9c243a5 100644 (file)
@@ -254,6 +254,7 @@ config USB_PXA25X_SMALL
 config USB_GADGET_PXA27X
        boolean "PXA 27x"
        depends on ARCH_PXA && PXA27x
+       select USB_OTG_UTILS
        help
           Intel's PXA 27x series XScale ARM v5TE processors include
           an integrated full speed USB 1.1 device controller.
index abf8192f89e845696c6e1a32df16db86e926e387..826f3adde5d8a4ac0df29265d88cadd1ab541d05 100644 (file)
@@ -551,7 +551,7 @@ udc_alloc_request(struct usb_ep *usbep, gfp_t gfp)
                dma_desc->status = AMD_ADDBITS(dma_desc->status,
                                                UDC_DMA_STP_STS_BS_HOST_BUSY,
                                                UDC_DMA_STP_STS_BS);
-               dma_desc->bufptr = __constant_cpu_to_le32(DMA_DONT_USE);
+               dma_desc->bufptr = cpu_to_le32(DMA_DONT_USE);
                req->td_data = dma_desc;
                req->td_data_last = NULL;
                req->chain_len = 1;
index 65b03e3445a1784535098d942bb120034d7363d4..c22fab164113ff310ff168b919d78bc0bff21018 100644 (file)
@@ -1017,7 +1017,7 @@ static struct usb_endpoint_descriptor usba_ep0_desc = {
        .bDescriptorType = USB_DT_ENDPOINT,
        .bEndpointAddress = 0,
        .bmAttributes = USB_ENDPOINT_XFER_CONTROL,
-       .wMaxPacketSize = __constant_cpu_to_le16(64),
+       .wMaxPacketSize = cpu_to_le16(64),
        /* FIXME: I have no idea what to put here */
        .bInterval = 1,
 };
@@ -1207,21 +1207,21 @@ static int do_test_mode(struct usba_udc *udc)
 /* Avoid overly long expressions */
 static inline bool feature_is_dev_remote_wakeup(struct usb_ctrlrequest *crq)
 {
-       if (crq->wValue == __constant_cpu_to_le16(USB_DEVICE_REMOTE_WAKEUP))
+       if (crq->wValue == cpu_to_le16(USB_DEVICE_REMOTE_WAKEUP))
                return true;
        return false;
 }
 
 static inline bool feature_is_dev_test_mode(struct usb_ctrlrequest *crq)
 {
-       if (crq->wValue == __constant_cpu_to_le16(USB_DEVICE_TEST_MODE))
+       if (crq->wValue == cpu_to_le16(USB_DEVICE_TEST_MODE))
                return true;
        return false;
 }
 
 static inline bool feature_is_ep_halt(struct usb_ctrlrequest *crq)
 {
-       if (crq->wValue == __constant_cpu_to_le16(USB_ENDPOINT_HALT))
+       if (crq->wValue == cpu_to_le16(USB_ENDPOINT_HALT))
                return true;
        return false;
 }
@@ -1239,7 +1239,7 @@ static int handle_ep0_setup(struct usba_udc *udc, struct usba_ep *ep,
                        status = cpu_to_le16(udc->devstatus);
                } else if (crq->bRequestType
                                == (USB_DIR_IN | USB_RECIP_INTERFACE)) {
-                       status = __constant_cpu_to_le16(0);
+                       status = cpu_to_le16(0);
                } else if (crq->bRequestType
                                == (USB_DIR_IN | USB_RECIP_ENDPOINT)) {
                        struct usba_ep *target;
@@ -1250,12 +1250,12 @@ static int handle_ep0_setup(struct usba_udc *udc, struct usba_ep *ep,
 
                        status = 0;
                        if (is_stalled(udc, target))
-                               status |= __constant_cpu_to_le16(1);
+                               status |= cpu_to_le16(1);
                } else
                        goto delegate;
 
                /* Write directly to the FIFO. No queueing is done. */
-               if (crq->wLength != __constant_cpu_to_le16(sizeof(status)))
+               if (crq->wLength != cpu_to_le16(sizeof(status)))
                        goto stall;
                ep->state = DATA_STAGE_IN;
                __raw_writew(status, ep->fifo);
@@ -1274,7 +1274,7 @@ static int handle_ep0_setup(struct usba_udc *udc, struct usba_ep *ep,
                } else if (crq->bRequestType == USB_RECIP_ENDPOINT) {
                        struct usba_ep *target;
 
-                       if (crq->wLength != __constant_cpu_to_le16(0)
+                       if (crq->wLength != cpu_to_le16(0)
                                        || !feature_is_ep_halt(crq))
                                goto stall;
                        target = get_ep_by_addr(udc, le16_to_cpu(crq->wIndex));
@@ -1308,7 +1308,7 @@ static int handle_ep0_setup(struct usba_udc *udc, struct usba_ep *ep,
                } else if (crq->bRequestType == USB_RECIP_ENDPOINT) {
                        struct usba_ep *target;
 
-                       if (crq->wLength != __constant_cpu_to_le16(0)
+                       if (crq->wLength != cpu_to_le16(0)
                                        || !feature_is_ep_halt(crq))
                                goto stall;
 
@@ -1514,7 +1514,7 @@ restart:
                         */
                        ep->state = DATA_STAGE_IN;
                } else {
-                       if (crq.crq.wLength != __constant_cpu_to_le16(0))
+                       if (crq.crq.wLength != cpu_to_le16(0))
                                ep->state = DATA_STAGE_OUT;
                        else
                                ep->state = STATUS_STAGE_IN;
index 5495b171cf29b11a89dbe1918cf2efbf854fb30a..928137d3dbdc237e5b5ab6e84620324253e05259 100644 (file)
@@ -66,7 +66,7 @@ static struct usb_device_descriptor device_desc = {
        .bLength =              sizeof device_desc,
        .bDescriptorType =      USB_DT_DEVICE,
 
-       .bcdUSB =               __constant_cpu_to_le16(0x0200),
+       .bcdUSB =               cpu_to_le16(0x0200),
 
        .bDeviceClass =         USB_CLASS_COMM,
        .bDeviceSubClass =      0,
@@ -74,8 +74,8 @@ static struct usb_device_descriptor device_desc = {
        /* .bMaxPacketSize0 = f(hardware) */
 
        /* Vendor and product id can be overridden by module parameters.  */
-       .idVendor =             __constant_cpu_to_le16(CDC_VENDOR_NUM),
-       .idProduct =            __constant_cpu_to_le16(CDC_PRODUCT_NUM),
+       .idVendor =             cpu_to_le16(CDC_VENDOR_NUM),
+       .idProduct =            cpu_to_le16(CDC_PRODUCT_NUM),
        /* .bcdDevice = f(hardware) */
        /* .iManufacturer = DYNAMIC */
        /* .iProduct = DYNAMIC */
@@ -193,7 +193,7 @@ static int __init cdc_bind(struct usb_composite_dev *cdev)
                                gadget->name,
                                cdc_config_driver.label);
                device_desc.bcdDevice =
-                       __constant_cpu_to_le16(0x0300 | 0x0099);
+                       cpu_to_le16(0x0300 | 0x0099);
        }
 
 
index 7f4e5eb1dc805904e31ff21d72227e57a6faf51a..22c65960c42971c4d94bb3ff83bd09dbfa6cbd94 100644 (file)
@@ -56,7 +56,6 @@
 #include <linux/dma-mapping.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
-#include <linux/interrupt.h>
 #include <linux/io.h>
 #include <linux/irq.h>
 #include <linux/kernel.h>
index 5d11c291f1ad113da485076efb4ec9724f253178..59e85234fa0ad614cfb9a181d27007653c250a51 100644 (file)
@@ -149,16 +149,17 @@ done:
 int usb_function_deactivate(struct usb_function *function)
 {
        struct usb_composite_dev        *cdev = function->config->cdev;
+       unsigned long                   flags;
        int                             status = 0;
 
-       spin_lock(&cdev->lock);
+       spin_lock_irqsave(&cdev->lock, flags);
 
        if (cdev->deactivations == 0)
                status = usb_gadget_disconnect(cdev->gadget);
        if (status == 0)
                cdev->deactivations++;
 
-       spin_unlock(&cdev->lock);
+       spin_unlock_irqrestore(&cdev->lock, flags);
        return status;
 }
 
@@ -1013,7 +1014,7 @@ composite_suspend(struct usb_gadget *gadget)
        struct usb_composite_dev        *cdev = get_gadget_data(gadget);
        struct usb_function             *f;
 
-       /* REVISIT:  should we have config and device level
+       /* REVISIT:  should we have config level
         * suspend/resume callbacks?
         */
        DBG(cdev, "suspend\n");
@@ -1023,6 +1024,8 @@ composite_suspend(struct usb_gadget *gadget)
                                f->suspend(f);
                }
        }
+       if (composite->suspend)
+               composite->suspend(cdev);
 }
 
 static void
@@ -1031,10 +1034,12 @@ composite_resume(struct usb_gadget *gadget)
        struct usb_composite_dev        *cdev = get_gadget_data(gadget);
        struct usb_function             *f;
 
-       /* REVISIT:  should we have config and device level
+       /* REVISIT:  should we have config level
         * suspend/resume callbacks?
         */
        DBG(cdev, "resume\n");
+       if (composite->resume)
+               composite->resume(cdev);
        if (cdev->config) {
                list_for_each_entry(f, &cdev->config->functions, list) {
                        if (f->resume)
index 9064696636acad99b03453a9126ea1b77f539b47..a56b24d305f8209e869e8877091720b4b880e9b0 100644 (file)
@@ -1437,7 +1437,7 @@ restart:
                                        }
                                        if (urb->transfer_buffer_length > 1)
                                                buf [1] = 0;
-                                       urb->actual_length = min (2,
+                                       urb->actual_length = min_t(u32, 2,
                                                urb->transfer_buffer_length);
                                        value = 0;
                                        status = 0;
@@ -1626,7 +1626,7 @@ static int dummy_hub_control (
                hub_descriptor ((struct usb_hub_descriptor *) buf);
                break;
        case GetHubStatus:
-               *(__le32 *) buf = __constant_cpu_to_le32 (0);
+               *(__le32 *) buf = cpu_to_le32 (0);
                break;
        case GetPortStatus:
                if (wIndex != 1)
index a36b1175b18db276a21bad2f086099be87ccd44f..cd0914ec898eff0c6591914b74e5118fad4f5c09 100644 (file)
@@ -148,7 +148,7 @@ ep_matches (
                        return 0;
 
                /* BOTH:  "high bandwidth" works only at high speed */
-               if ((desc->wMaxPacketSize & __constant_cpu_to_le16(3<<11))) {
+               if ((desc->wMaxPacketSize & cpu_to_le16(3<<11))) {
                        if (!gadget->is_dualspeed)
                                return 0;
                        /* configure your hardware with enough buffering!! */
index 37252d0012a77ae6ef616c3db23065e0beee6b84..d006dc652e025558e3157691b0f855b43452a6ad 100644 (file)
@@ -156,7 +156,7 @@ static struct usb_device_descriptor device_desc = {
        .bLength =              sizeof device_desc,
        .bDescriptorType =      USB_DT_DEVICE,
 
-       .bcdUSB =               __constant_cpu_to_le16 (0x0200),
+       .bcdUSB =               cpu_to_le16 (0x0200),
 
        .bDeviceClass =         USB_CLASS_COMM,
        .bDeviceSubClass =      0,
@@ -167,8 +167,8 @@ static struct usb_device_descriptor device_desc = {
         * we support.  (As does bNumConfigurations.)  These values can
         * also be overridden by module parameters.
         */
-       .idVendor =             __constant_cpu_to_le16 (CDC_VENDOR_NUM),
-       .idProduct =            __constant_cpu_to_le16 (CDC_PRODUCT_NUM),
+       .idVendor =             cpu_to_le16 (CDC_VENDOR_NUM),
+       .idProduct =            cpu_to_le16 (CDC_PRODUCT_NUM),
        /* .bcdDevice = f(hardware) */
        /* .iManufacturer = DYNAMIC */
        /* .iProduct = DYNAMIC */
@@ -318,7 +318,7 @@ static int __init eth_bind(struct usb_composite_dev *cdev)
                                gadget->name,
                                eth_config_driver.label);
                device_desc.bcdDevice =
-                       __constant_cpu_to_le16(0x0300 | 0x0099);
+                       cpu_to_le16(0x0300 | 0x0099);
        }
 
 
index c1d34df0b157c45f533b03b794bd14a929055f70..7953948bfe4a3e93892447dace87e774ec3cc09c 100644 (file)
@@ -125,7 +125,7 @@ static struct usb_cdc_header_desc acm_header_desc __initdata = {
        .bLength =              sizeof(acm_header_desc),
        .bDescriptorType =      USB_DT_CS_INTERFACE,
        .bDescriptorSubType =   USB_CDC_HEADER_TYPE,
-       .bcdCDC =               __constant_cpu_to_le16(0x0110),
+       .bcdCDC =               cpu_to_le16(0x0110),
 };
 
 static struct usb_cdc_call_mgmt_descriptor
@@ -159,7 +159,7 @@ static struct usb_endpoint_descriptor acm_fs_notify_desc __initdata = {
        .bDescriptorType =      USB_DT_ENDPOINT,
        .bEndpointAddress =     USB_DIR_IN,
        .bmAttributes =         USB_ENDPOINT_XFER_INT,
-       .wMaxPacketSize =       __constant_cpu_to_le16(GS_NOTIFY_MAXPACKET),
+       .wMaxPacketSize =       cpu_to_le16(GS_NOTIFY_MAXPACKET),
        .bInterval =            1 << GS_LOG2_NOTIFY_INTERVAL,
 };
 
@@ -197,7 +197,7 @@ static struct usb_endpoint_descriptor acm_hs_notify_desc __initdata = {
        .bDescriptorType =      USB_DT_ENDPOINT,
        .bEndpointAddress =     USB_DIR_IN,
        .bmAttributes =         USB_ENDPOINT_XFER_INT,
-       .wMaxPacketSize =       __constant_cpu_to_le16(GS_NOTIFY_MAXPACKET),
+       .wMaxPacketSize =       cpu_to_le16(GS_NOTIFY_MAXPACKET),
        .bInterval =            GS_LOG2_NOTIFY_INTERVAL+4,
 };
 
@@ -205,14 +205,14 @@ static struct usb_endpoint_descriptor acm_hs_in_desc __initdata = {
        .bLength =              USB_DT_ENDPOINT_SIZE,
        .bDescriptorType =      USB_DT_ENDPOINT,
        .bmAttributes =         USB_ENDPOINT_XFER_BULK,
-       .wMaxPacketSize =       __constant_cpu_to_le16(512),
+       .wMaxPacketSize =       cpu_to_le16(512),
 };
 
 static struct usb_endpoint_descriptor acm_hs_out_desc __initdata = {
        .bLength =              USB_DT_ENDPOINT_SIZE,
        .bDescriptorType =      USB_DT_ENDPOINT,
        .bmAttributes =         USB_ENDPOINT_XFER_BULK,
-       .wMaxPacketSize =       __constant_cpu_to_le16(512),
+       .wMaxPacketSize =       cpu_to_le16(512),
 };
 
 static struct usb_descriptor_header *acm_hs_function[] __initdata = {
index 4ae579948e54dc67288499cea56929b220e98ebe..ecf5bdd0ae069d277e41a26aa613a6dac28678e3 100644 (file)
@@ -130,7 +130,7 @@ static struct usb_cdc_header_desc ecm_header_desc __initdata = {
        .bDescriptorType =      USB_DT_CS_INTERFACE,
        .bDescriptorSubType =   USB_CDC_HEADER_TYPE,
 
-       .bcdCDC =               __constant_cpu_to_le16(0x0110),
+       .bcdCDC =               cpu_to_le16(0x0110),
 };
 
 static struct usb_cdc_union_desc ecm_union_desc __initdata = {
@@ -148,9 +148,9 @@ static struct usb_cdc_ether_desc ecm_desc __initdata = {
 
        /* this descriptor actually adds value, surprise! */
        /* .iMACAddress = DYNAMIC */
-       .bmEthernetStatistics = __constant_cpu_to_le32(0), /* no statistics */
-       .wMaxSegmentSize =      __constant_cpu_to_le16(ETH_FRAME_LEN),
-       .wNumberMCFilters =     __constant_cpu_to_le16(0),
+       .bmEthernetStatistics = cpu_to_le32(0), /* no statistics */
+       .wMaxSegmentSize =      cpu_to_le16(ETH_FRAME_LEN),
+       .wNumberMCFilters =     cpu_to_le16(0),
        .bNumberPowerFilters =  0,
 };
 
@@ -192,7 +192,7 @@ static struct usb_endpoint_descriptor fs_ecm_notify_desc __initdata = {
 
        .bEndpointAddress =     USB_DIR_IN,
        .bmAttributes =         USB_ENDPOINT_XFER_INT,
-       .wMaxPacketSize =       __constant_cpu_to_le16(ECM_STATUS_BYTECOUNT),
+       .wMaxPacketSize =       cpu_to_le16(ECM_STATUS_BYTECOUNT),
        .bInterval =            1 << LOG2_STATUS_INTERVAL_MSEC,
 };
 
@@ -236,7 +236,7 @@ static struct usb_endpoint_descriptor hs_ecm_notify_desc __initdata = {
 
        .bEndpointAddress =     USB_DIR_IN,
        .bmAttributes =         USB_ENDPOINT_XFER_INT,
-       .wMaxPacketSize =       __constant_cpu_to_le16(ECM_STATUS_BYTECOUNT),
+       .wMaxPacketSize =       cpu_to_le16(ECM_STATUS_BYTECOUNT),
        .bInterval =            LOG2_STATUS_INTERVAL_MSEC + 4,
 };
 static struct usb_endpoint_descriptor hs_ecm_in_desc __initdata = {
@@ -245,7 +245,7 @@ static struct usb_endpoint_descriptor hs_ecm_in_desc __initdata = {
 
        .bEndpointAddress =     USB_DIR_IN,
        .bmAttributes =         USB_ENDPOINT_XFER_BULK,
-       .wMaxPacketSize =       __constant_cpu_to_le16(512),
+       .wMaxPacketSize =       cpu_to_le16(512),
 };
 
 static struct usb_endpoint_descriptor hs_ecm_out_desc __initdata = {
@@ -254,7 +254,7 @@ static struct usb_endpoint_descriptor hs_ecm_out_desc __initdata = {
 
        .bEndpointAddress =     USB_DIR_OUT,
        .bmAttributes =         USB_ENDPOINT_XFER_BULK,
-       .wMaxPacketSize =       __constant_cpu_to_le16(512),
+       .wMaxPacketSize =       cpu_to_le16(512),
 };
 
 static struct usb_descriptor_header *ecm_hs_function[] __initdata = {
index 8affe1dfc2c11200a8a7962ffac1e6381af3124a..eb6ddfc20857741354ca959702dfbdae0f55103f 100644 (file)
@@ -100,7 +100,7 @@ static struct usb_endpoint_descriptor hs_loop_source_desc = {
        .bDescriptorType =      USB_DT_ENDPOINT,
 
        .bmAttributes =         USB_ENDPOINT_XFER_BULK,
-       .wMaxPacketSize =       __constant_cpu_to_le16(512),
+       .wMaxPacketSize =       cpu_to_le16(512),
 };
 
 static struct usb_endpoint_descriptor hs_loop_sink_desc = {
@@ -108,7 +108,7 @@ static struct usb_endpoint_descriptor hs_loop_sink_desc = {
        .bDescriptorType =      USB_DT_ENDPOINT,
 
        .bmAttributes =         USB_ENDPOINT_XFER_BULK,
-       .wMaxPacketSize =       __constant_cpu_to_le16(512),
+       .wMaxPacketSize =       cpu_to_le16(512),
 };
 
 static struct usb_descriptor_header *hs_loopback_descs[] = {
@@ -359,7 +359,7 @@ static struct usb_configuration loopback_driver = {
  * loopback_add - add a loopback testing configuration to a device
  * @cdev: the device to support the loopback configuration
  */
-int __init loopback_add(struct usb_composite_dev *cdev)
+int __init loopback_add(struct usb_composite_dev *cdev, bool autoresume)
 {
        int id;
 
@@ -372,6 +372,10 @@ int __init loopback_add(struct usb_composite_dev *cdev)
        loopback_intf.iInterface = id;
        loopback_driver.iConfiguration = id;
 
+       /* support autoresume for remote wakeup testing */
+       if (autoresume)
+               sourcesink_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
+
        /* support OTG systems */
        if (gadget_is_otg(cdev->gadget)) {
                loopback_driver.descriptors = otg_desc;
index 38aa896cc5db36317c8e4b7e03a1dc4734bb5c1c..46d6266f30ec6f788b0adcf491d162de6f02c80f 100644 (file)
@@ -123,7 +123,7 @@ static struct usb_cdc_header_desc obex_cdc_header_desc __initdata = {
        .bLength                = sizeof(obex_cdc_header_desc),
        .bDescriptorType        = USB_DT_CS_INTERFACE,
        .bDescriptorSubType     = USB_CDC_HEADER_TYPE,
-       .bcdCDC                 = __constant_cpu_to_le16(0x0120),
+       .bcdCDC                 = cpu_to_le16(0x0120),
 };
 
 static struct usb_cdc_union_desc obex_cdc_union_desc __initdata = {
@@ -138,7 +138,7 @@ static struct usb_cdc_obex_desc obex_desc __initdata = {
        .bLength                = sizeof(obex_desc),
        .bDescriptorType        = USB_DT_CS_INTERFACE,
        .bDescriptorSubType     = USB_CDC_OBEX_TYPE,
-       .bcdVersion             = __constant_cpu_to_le16(0x0100),
+       .bcdVersion             = cpu_to_le16(0x0100),
 };
 
 /* High-Speed Support */
@@ -149,7 +149,7 @@ static struct usb_endpoint_descriptor obex_hs_ep_out_desc __initdata = {
 
        .bEndpointAddress       = USB_DIR_OUT,
        .bmAttributes           = USB_ENDPOINT_XFER_BULK,
-       .wMaxPacketSize         = __constant_cpu_to_le16(512),
+       .wMaxPacketSize         = cpu_to_le16(512),
 };
 
 static struct usb_endpoint_descriptor obex_hs_ep_in_desc __initdata = {
@@ -158,7 +158,7 @@ static struct usb_endpoint_descriptor obex_hs_ep_in_desc __initdata = {
 
        .bEndpointAddress       = USB_DIR_IN,
        .bmAttributes           = USB_ENDPOINT_XFER_BULK,
-       .wMaxPacketSize         = __constant_cpu_to_le16(512),
+       .wMaxPacketSize         = cpu_to_le16(512),
 };
 
 static struct usb_descriptor_header *hs_function[] __initdata = {
index c0916c7b217e406a2fd91966eed9463bf3b829ae..c1abeb89b413f101d38174726f713c666581600b 100644 (file)
@@ -79,7 +79,7 @@ pn_header_desc = {
        .bLength =              sizeof pn_header_desc,
        .bDescriptorType =      USB_DT_CS_INTERFACE,
        .bDescriptorSubType =   USB_CDC_HEADER_TYPE,
-       .bcdCDC =               __constant_cpu_to_le16(0x0110),
+       .bcdCDC =               cpu_to_le16(0x0110),
 };
 
 static const struct usb_cdc_header_desc
@@ -87,7 +87,7 @@ pn_phonet_desc = {
        .bLength =              sizeof pn_phonet_desc,
        .bDescriptorType =      USB_DT_CS_INTERFACE,
        .bDescriptorSubType =   USB_CDC_PHONET_TYPE,
-       .bcdCDC =               __constant_cpu_to_le16(0x1505), /* ??? */
+       .bcdCDC =               cpu_to_le16(0x1505), /* ??? */
 };
 
 static struct usb_cdc_union_desc
@@ -138,7 +138,7 @@ pn_hs_sink_desc = {
 
        .bEndpointAddress =     USB_DIR_OUT,
        .bmAttributes =         USB_ENDPOINT_XFER_BULK,
-       .wMaxPacketSize =       __constant_cpu_to_le16(512),
+       .wMaxPacketSize =       cpu_to_le16(512),
 };
 
 static struct usb_endpoint_descriptor
@@ -157,7 +157,7 @@ pn_hs_source_desc = {
 
        .bEndpointAddress =     USB_DIR_IN,
        .bmAttributes =         USB_ENDPOINT_XFER_BULK,
-       .wMaxPacketSize =       __constant_cpu_to_le16(512),
+       .wMaxPacketSize =       cpu_to_le16(512),
 };
 
 static struct usb_descriptor_header *fs_pn_function[] = {
index 3a8bb53fc473269e31366d0c11069490a30cb7bf..3279a47260428a1122cc409ae64ac8994f4c3eee 100644 (file)
@@ -137,7 +137,7 @@ static struct usb_cdc_header_desc header_desc __initdata = {
        .bDescriptorType =      USB_DT_CS_INTERFACE,
        .bDescriptorSubType =   USB_CDC_HEADER_TYPE,
 
-       .bcdCDC =               __constant_cpu_to_le16(0x0110),
+       .bcdCDC =               cpu_to_le16(0x0110),
 };
 
 static struct usb_cdc_call_mgmt_descriptor call_mgmt_descriptor __initdata = {
@@ -187,7 +187,7 @@ static struct usb_endpoint_descriptor fs_notify_desc __initdata = {
 
        .bEndpointAddress =     USB_DIR_IN,
        .bmAttributes =         USB_ENDPOINT_XFER_INT,
-       .wMaxPacketSize =       __constant_cpu_to_le16(STATUS_BYTECOUNT),
+       .wMaxPacketSize =       cpu_to_le16(STATUS_BYTECOUNT),
        .bInterval =            1 << LOG2_STATUS_INTERVAL_MSEC,
 };
 
@@ -230,7 +230,7 @@ static struct usb_endpoint_descriptor hs_notify_desc __initdata = {
 
        .bEndpointAddress =     USB_DIR_IN,
        .bmAttributes =         USB_ENDPOINT_XFER_INT,
-       .wMaxPacketSize =       __constant_cpu_to_le16(STATUS_BYTECOUNT),
+       .wMaxPacketSize =       cpu_to_le16(STATUS_BYTECOUNT),
        .bInterval =            LOG2_STATUS_INTERVAL_MSEC + 4,
 };
 static struct usb_endpoint_descriptor hs_in_desc __initdata = {
@@ -239,7 +239,7 @@ static struct usb_endpoint_descriptor hs_in_desc __initdata = {
 
        .bEndpointAddress =     USB_DIR_IN,
        .bmAttributes =         USB_ENDPOINT_XFER_BULK,
-       .wMaxPacketSize =       __constant_cpu_to_le16(512),
+       .wMaxPacketSize =       cpu_to_le16(512),
 };
 
 static struct usb_endpoint_descriptor hs_out_desc __initdata = {
@@ -248,7 +248,7 @@ static struct usb_endpoint_descriptor hs_out_desc __initdata = {
 
        .bEndpointAddress =     USB_DIR_OUT,
        .bmAttributes =         USB_ENDPOINT_XFER_BULK,
-       .wMaxPacketSize =       __constant_cpu_to_le16(512),
+       .wMaxPacketSize =       cpu_to_le16(512),
 };
 
 static struct usb_descriptor_header *eth_hs_function[] __initdata = {
@@ -437,7 +437,7 @@ invalid:
                DBG(cdev, "rndis req%02x.%02x v%04x i%04x l%d\n",
                        ctrl->bRequestType, ctrl->bRequest,
                        w_value, w_index, w_length);
-               req->zero = 0;
+               req->zero = (value < w_length);
                req->length = value;
                value = usb_ep_queue(cdev->gadget->ep0, req, GFP_ATOMIC);
                if (value < 0)
index fe5674db344bf862fccd98b91d1afc16a4579bec..db0aa93606ef90b4615e4acb5d908ba79944f5ce 100644 (file)
@@ -89,14 +89,14 @@ static struct usb_endpoint_descriptor gser_hs_in_desc __initdata = {
        .bLength =              USB_DT_ENDPOINT_SIZE,
        .bDescriptorType =      USB_DT_ENDPOINT,
        .bmAttributes =         USB_ENDPOINT_XFER_BULK,
-       .wMaxPacketSize =       __constant_cpu_to_le16(512),
+       .wMaxPacketSize =       cpu_to_le16(512),
 };
 
 static struct usb_endpoint_descriptor gser_hs_out_desc __initdata = {
        .bLength =              USB_DT_ENDPOINT_SIZE,
        .bDescriptorType =      USB_DT_ENDPOINT,
        .bmAttributes =         USB_ENDPOINT_XFER_BULK,
-       .wMaxPacketSize =       __constant_cpu_to_le16(512),
+       .wMaxPacketSize =       cpu_to_le16(512),
 };
 
 static struct usb_descriptor_header *gser_hs_function[] __initdata = {
index dc84d26d283575be85097611dc044b8e0aaa1374..bffe91d525f977ba2fa32dec574996e99f67ad72 100644 (file)
@@ -59,7 +59,6 @@ struct f_sourcesink {
 
        struct usb_ep           *in_ep;
        struct usb_ep           *out_ep;
-       struct timer_list       resume;
 };
 
 static inline struct f_sourcesink *func_to_ss(struct usb_function *f)
@@ -67,10 +66,6 @@ static inline struct f_sourcesink *func_to_ss(struct usb_function *f)
        return container_of(f, struct f_sourcesink, function);
 }
 
-static unsigned autoresume;
-module_param(autoresume, uint, 0);
-MODULE_PARM_DESC(autoresume, "zero, or seconds before remote wakeup");
-
 static unsigned pattern;
 module_param(pattern, uint, 0);
 MODULE_PARM_DESC(pattern, "0 = all zeroes, 1 = mod63 ");
@@ -118,7 +113,7 @@ static struct usb_endpoint_descriptor hs_source_desc = {
        .bDescriptorType =      USB_DT_ENDPOINT,
 
        .bmAttributes =         USB_ENDPOINT_XFER_BULK,
-       .wMaxPacketSize =       __constant_cpu_to_le16(512),
+       .wMaxPacketSize =       cpu_to_le16(512),
 };
 
 static struct usb_endpoint_descriptor hs_sink_desc = {
@@ -126,7 +121,7 @@ static struct usb_endpoint_descriptor hs_sink_desc = {
        .bDescriptorType =      USB_DT_ENDPOINT,
 
        .bmAttributes =         USB_ENDPOINT_XFER_BULK,
-       .wMaxPacketSize =       __constant_cpu_to_le16(512),
+       .wMaxPacketSize =       cpu_to_le16(512),
 };
 
 static struct usb_descriptor_header *hs_source_sink_descs[] = {
@@ -155,21 +150,6 @@ static struct usb_gadget_strings *sourcesink_strings[] = {
 
 /*-------------------------------------------------------------------------*/
 
-static void sourcesink_autoresume(unsigned long _c)
-{
-       struct usb_composite_dev *cdev = (void *)_c;
-       struct usb_gadget       *g = cdev->gadget;
-
-       /* Normally the host would be woken up for something
-        * more significant than just a timer firing; likely
-        * because of some direct user request.
-        */
-       if (g->speed != USB_SPEED_UNKNOWN) {
-               int status = usb_gadget_wakeup(g);
-               DBG(cdev, "%s --> %d\n", __func__, status);
-       }
-}
-
 static int __init
 sourcesink_bind(struct usb_configuration *c, struct usb_function *f)
 {
@@ -198,9 +178,6 @@ autoconf_fail:
                goto autoconf_fail;
        ss->out_ep->driver_data = cdev; /* claim */
 
-       setup_timer(&ss->resume, sourcesink_autoresume,
-                       (unsigned long) c->cdev);
-
        /* support high speed hardware */
        if (gadget_is_dualspeed(c->cdev->gadget)) {
                hs_source_desc.bEndpointAddress =
@@ -359,7 +336,6 @@ static void disable_source_sink(struct f_sourcesink *ss)
 
        cdev = ss->function.config->cdev;
        disable_endpoints(cdev, ss->in_ep, ss->out_ep);
-       del_timer(&ss->resume);
        VDBG(cdev, "%s disabled\n", ss->function.name);
 }
 
@@ -426,30 +402,6 @@ static void sourcesink_disable(struct usb_function *f)
        disable_source_sink(ss);
 }
 
-static void sourcesink_suspend(struct usb_function *f)
-{
-       struct f_sourcesink     *ss = func_to_ss(f);
-       struct usb_composite_dev *cdev = f->config->cdev;
-
-       if (cdev->gadget->speed == USB_SPEED_UNKNOWN)
-               return;
-
-       if (autoresume) {
-               mod_timer(&ss->resume, jiffies + (HZ * autoresume));
-               DBG(cdev, "suspend, wakeup in %d seconds\n", autoresume);
-       } else
-               DBG(cdev, "%s\n", __func__);
-}
-
-static void sourcesink_resume(struct usb_function *f)
-{
-       struct f_sourcesink     *ss = func_to_ss(f);
-       struct usb_composite_dev *cdev = f->config->cdev;
-
-       DBG(cdev, "%s\n", __func__);
-       del_timer(&ss->resume);
-}
-
 /*-------------------------------------------------------------------------*/
 
 static int __init sourcesink_bind_config(struct usb_configuration *c)
@@ -467,8 +419,6 @@ static int __init sourcesink_bind_config(struct usb_configuration *c)
        ss->function.unbind = sourcesink_unbind;
        ss->function.set_alt = sourcesink_set_alt;
        ss->function.disable = sourcesink_disable;
-       ss->function.suspend = sourcesink_suspend;
-       ss->function.resume = sourcesink_resume;
 
        status = usb_add_function(c, &ss->function);
        if (status)
@@ -559,7 +509,7 @@ static struct usb_configuration sourcesink_driver = {
  * sourcesink_add - add a source/sink testing configuration to a device
  * @cdev: the device to support the configuration
  */
-int __init sourcesink_add(struct usb_composite_dev *cdev)
+int __init sourcesink_add(struct usb_composite_dev *cdev, bool autoresume)
 {
        int id;
 
index fe1832875771539ec72d0fa693968a548a26fd79..a9c98fdb626d75e855eb1515cef19dfb8100e299 100644 (file)
@@ -108,7 +108,7 @@ static struct usb_cdc_header_desc mdlm_header_desc __initdata = {
        .bDescriptorType =      USB_DT_CS_INTERFACE,
        .bDescriptorSubType =   USB_CDC_HEADER_TYPE,
 
-       .bcdCDC =               __constant_cpu_to_le16(0x0110),
+       .bcdCDC =               cpu_to_le16(0x0110),
 };
 
 static struct usb_cdc_mdlm_desc mdlm_desc __initdata = {
@@ -116,7 +116,7 @@ static struct usb_cdc_mdlm_desc mdlm_desc __initdata = {
        .bDescriptorType =      USB_DT_CS_INTERFACE,
        .bDescriptorSubType =   USB_CDC_MDLM_TYPE,
 
-       .bcdVersion =           __constant_cpu_to_le16(0x0100),
+       .bcdVersion =           cpu_to_le16(0x0100),
        .bGUID = {
                0x5d, 0x34, 0xcf, 0x66, 0x11, 0x18, 0x11, 0xd6,
                0xa2, 0x1a, 0x00, 0x01, 0x02, 0xca, 0x9a, 0x7f,
@@ -144,9 +144,9 @@ static struct usb_cdc_ether_desc ether_desc __initdata = {
 
        /* this descriptor actually adds value, surprise! */
        /* .iMACAddress = DYNAMIC */
-       .bmEthernetStatistics = __constant_cpu_to_le32(0), /* no statistics */
-       .wMaxSegmentSize =      __constant_cpu_to_le16(ETH_FRAME_LEN),
-       .wNumberMCFilters =     __constant_cpu_to_le16(0),
+       .bmEthernetStatistics = cpu_to_le32(0), /* no statistics */
+       .wMaxSegmentSize =      cpu_to_le16(ETH_FRAME_LEN),
+       .wNumberMCFilters =     cpu_to_le16(0),
        .bNumberPowerFilters =  0,
 };
 
@@ -186,7 +186,7 @@ static struct usb_endpoint_descriptor hs_subset_in_desc __initdata = {
        .bDescriptorType =      USB_DT_ENDPOINT,
 
        .bmAttributes =         USB_ENDPOINT_XFER_BULK,
-       .wMaxPacketSize =       __constant_cpu_to_le16(512),
+       .wMaxPacketSize =       cpu_to_le16(512),
 };
 
 static struct usb_endpoint_descriptor hs_subset_out_desc __initdata = {
@@ -194,7 +194,7 @@ static struct usb_endpoint_descriptor hs_subset_out_desc __initdata = {
        .bDescriptorType =      USB_DT_ENDPOINT,
 
        .bmAttributes =         USB_ENDPOINT_XFER_BULK,
-       .wMaxPacketSize =       __constant_cpu_to_le16(512),
+       .wMaxPacketSize =       cpu_to_le16(512),
 };
 
 static struct usb_descriptor_header *hs_eth_function[] __initdata = {
index 1ab9dac7e12df8eec07e5ed278e48ca90cdd3bc5..d3c2464dee82b9cded5a658f07e224bd39c7051b 100644 (file)
@@ -847,13 +847,13 @@ device_desc = {
        .bLength =              sizeof device_desc,
        .bDescriptorType =      USB_DT_DEVICE,
 
-       .bcdUSB =               __constant_cpu_to_le16(0x0200),
+       .bcdUSB =               cpu_to_le16(0x0200),
        .bDeviceClass =         USB_CLASS_PER_INTERFACE,
 
        /* The next three values can be overridden by module parameters */
-       .idVendor =             __constant_cpu_to_le16(DRIVER_VENDOR_ID),
-       .idProduct =            __constant_cpu_to_le16(DRIVER_PRODUCT_ID),
-       .bcdDevice =            __constant_cpu_to_le16(0xffff),
+       .idVendor =             cpu_to_le16(DRIVER_VENDOR_ID),
+       .idProduct =            cpu_to_le16(DRIVER_PRODUCT_ID),
+       .bcdDevice =            cpu_to_le16(0xffff),
 
        .iManufacturer =        STRING_MANUFACTURER,
        .iProduct =             STRING_PRODUCT,
@@ -926,7 +926,7 @@ fs_intr_in_desc = {
 
        .bEndpointAddress =     USB_DIR_IN,
        .bmAttributes =         USB_ENDPOINT_XFER_INT,
-       .wMaxPacketSize =       __constant_cpu_to_le16(2),
+       .wMaxPacketSize =       cpu_to_le16(2),
        .bInterval =            32,     // frames -> 32 ms
 };
 
@@ -954,7 +954,7 @@ dev_qualifier = {
        .bLength =              sizeof dev_qualifier,
        .bDescriptorType =      USB_DT_DEVICE_QUALIFIER,
 
-       .bcdUSB =               __constant_cpu_to_le16(0x0200),
+       .bcdUSB =               cpu_to_le16(0x0200),
        .bDeviceClass =         USB_CLASS_PER_INTERFACE,
 
        .bNumConfigurations =   1,
@@ -967,7 +967,7 @@ hs_bulk_in_desc = {
 
        /* bEndpointAddress copied from fs_bulk_in_desc during fsg_bind() */
        .bmAttributes =         USB_ENDPOINT_XFER_BULK,
-       .wMaxPacketSize =       __constant_cpu_to_le16(512),
+       .wMaxPacketSize =       cpu_to_le16(512),
 };
 
 static struct usb_endpoint_descriptor
@@ -977,7 +977,7 @@ hs_bulk_out_desc = {
 
        /* bEndpointAddress copied from fs_bulk_out_desc during fsg_bind() */
        .bmAttributes =         USB_ENDPOINT_XFER_BULK,
-       .wMaxPacketSize =       __constant_cpu_to_le16(512),
+       .wMaxPacketSize =       cpu_to_le16(512),
        .bInterval =            1,      // NAK every 1 uframe
 };
 
@@ -988,7 +988,7 @@ hs_intr_in_desc = {
 
        /* bEndpointAddress copied from fs_intr_in_desc during fsg_bind() */
        .bmAttributes =         USB_ENDPOINT_XFER_INT,
-       .wMaxPacketSize =       __constant_cpu_to_le16(2),
+       .wMaxPacketSize =       cpu_to_le16(2),
        .bInterval =            9,      // 2**(9-1) = 256 uframes -> 32 ms
 };
 
@@ -2646,7 +2646,7 @@ static int send_status(struct fsg_dev *fsg)
                struct bulk_cs_wrap     *csw = bh->buf;
 
                /* Store and send the Bulk-only CSW */
-               csw->Signature = __constant_cpu_to_le32(USB_BULK_CS_SIG);
+               csw->Signature = cpu_to_le32(USB_BULK_CS_SIG);
                csw->Tag = fsg->tag;
                csw->Residue = cpu_to_le32(fsg->residue);
                csw->Status = status;
@@ -3089,7 +3089,7 @@ static int received_cbw(struct fsg_dev *fsg, struct fsg_buffhd *bh)
 
        /* Is the CBW valid? */
        if (req->actual != USB_BULK_CB_WRAP_LEN ||
-                       cbw->Signature != __constant_cpu_to_le32(
+                       cbw->Signature != cpu_to_le32(
                                USB_BULK_CB_SIG)) {
                DBG(fsg, "invalid CBW: len %u sig 0x%x\n",
                                req->actual,
index d8d9a52a44b34e5a517c3a8dd923478e3b88b198..9d7b95d4e3d2e523b7792f6b412b39bf6958b914 100644 (file)
@@ -1802,7 +1802,8 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
 
 out:
        if (retval)
-               printk("gadget driver register failed %d\n", retval);
+               printk(KERN_WARNING "gadget driver register failed %d\n",
+                      retval);
        return retval;
 }
 EXPORT_SYMBOL(usb_gadget_register_driver);
@@ -1847,7 +1848,8 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
        udc_controller->gadget.dev.driver = NULL;
        udc_controller->driver = NULL;
 
-       printk("unregistered gadget driver '%s'\n", driver->driver.name);
+       printk(KERN_WARNING "unregistered gadget driver '%s'\n",
+              driver->driver.name);
        return 0;
 }
 EXPORT_SYMBOL(usb_gadget_unregister_driver);
@@ -2455,7 +2457,7 @@ module_init(udc_init);
 static void __exit udc_exit(void)
 {
        platform_driver_unregister(&udc_driver);
-       printk("%s unregistered\n", driver_desc);
+       printk(KERN_WARNING "%s unregistered\n", driver_desc);
 }
 
 module_exit(udc_exit);
index dd2f16ad5a888541da09071f83a7b963c59f962e..e84b3c47ed3c3da1d9676b5a32055eac8caad6fd 100644 (file)
@@ -19,7 +19,7 @@ void disable_endpoints(struct usb_composite_dev *cdev,
                struct usb_ep *in, struct usb_ep *out);
 
 /* configuration-specific linkup */
-int sourcesink_add(struct usb_composite_dev *cdev);
-int loopback_add(struct usb_composite_dev *cdev);
+int sourcesink_add(struct usb_composite_dev *cdev, bool autoresume);
+int loopback_add(struct usb_composite_dev *cdev, bool autoresume);
 
 #endif /* __G_ZERO_H */
index 14e09abbddfcb0463e701a08cc3ec48702686875..b9312dc6e04151f60c4dea4dce27b36c74e3ae87 100644 (file)
@@ -199,10 +199,10 @@ DECLARE_USB_MS_ENDPOINT_DESCRIPTOR(1);
 static struct usb_device_descriptor device_desc = {
        .bLength =              USB_DT_DEVICE_SIZE,
        .bDescriptorType =      USB_DT_DEVICE,
-       .bcdUSB =               __constant_cpu_to_le16(0x0200),
+       .bcdUSB =               cpu_to_le16(0x0200),
        .bDeviceClass =         USB_CLASS_PER_INTERFACE,
-       .idVendor =             __constant_cpu_to_le16(DRIVER_VENDOR_NUM),
-       .idProduct =            __constant_cpu_to_le16(DRIVER_PRODUCT_NUM),
+       .idVendor =             cpu_to_le16(DRIVER_VENDOR_NUM),
+       .idProduct =            cpu_to_le16(DRIVER_PRODUCT_NUM),
        .iManufacturer =        STRING_MANUFACTURER,
        .iProduct =             STRING_PRODUCT,
        .bNumConfigurations =   1,
@@ -241,8 +241,8 @@ static const struct usb_ac_header_descriptor_1 ac_header_desc = {
        .bLength =              USB_DT_AC_HEADER_SIZE(1),
        .bDescriptorType =      USB_DT_CS_INTERFACE,
        .bDescriptorSubtype =   USB_MS_HEADER,
-       .bcdADC =               __constant_cpu_to_le16(0x0100),
-       .wTotalLength =         __constant_cpu_to_le16(USB_DT_AC_HEADER_SIZE(1)),
+       .bcdADC =               cpu_to_le16(0x0100),
+       .wTotalLength =         cpu_to_le16(USB_DT_AC_HEADER_SIZE(1)),
        .bInCollection =        1,
        .baInterfaceNr = {
                [0] =           GMIDI_MS_INTERFACE,
@@ -265,8 +265,8 @@ static const struct usb_ms_header_descriptor ms_header_desc = {
        .bLength =              USB_DT_MS_HEADER_SIZE,
        .bDescriptorType =      USB_DT_CS_INTERFACE,
        .bDescriptorSubtype =   USB_MS_HEADER,
-       .bcdMSC =               __constant_cpu_to_le16(0x0100),
-       .wTotalLength =         __constant_cpu_to_le16(USB_DT_MS_HEADER_SIZE
+       .bcdMSC =               cpu_to_le16(0x0100),
+       .wTotalLength =         cpu_to_le16(USB_DT_MS_HEADER_SIZE
                                + 2*USB_DT_MIDI_IN_SIZE
                                + 2*USB_DT_MIDI_OUT_SIZE(1)),
 };
@@ -1226,7 +1226,7 @@ autoconf_fail:
                 */
                pr_warning("%s: controller '%s' not recognized\n",
                        shortname, gadget->name);
-               device_desc.bcdDevice = __constant_cpu_to_le16(0x9999);
+               device_desc.bcdDevice = cpu_to_le16(0x9999);
        }
 
 
index 63419c4d503c3876649e57221a9073f58cf2e8be..de010c939dbbca672c5f992f85471aab5d0b6dec 100644 (file)
@@ -1472,7 +1472,7 @@ static void ep0_setup(struct goku_udc *dev)
                                /* active endpoint */
                                if (tmp > 3 || (!dev->ep[tmp].desc && tmp != 0))
                                        goto stall;
-                               if (ctrl.wIndex & __constant_cpu_to_le16(
+                               if (ctrl.wIndex & cpu_to_le16(
                                                USB_DIR_IN)) {
                                        if (!dev->ep[tmp].is_in)
                                                goto stall;
@@ -1480,7 +1480,7 @@ static void ep0_setup(struct goku_udc *dev)
                                        if (dev->ep[tmp].is_in)
                                                goto stall;
                                }
-                               if (ctrl.wValue != __constant_cpu_to_le16(
+                               if (ctrl.wValue != cpu_to_le16(
                                                USB_ENDPOINT_HALT))
                                        goto stall;
                                if (tmp)
@@ -1493,7 +1493,7 @@ succeed:
                                return;
                        case USB_RECIP_DEVICE:
                                /* device remote wakeup: always clear */
-                               if (ctrl.wValue != __constant_cpu_to_le16(1))
+                               if (ctrl.wValue != cpu_to_le16(1))
                                        goto stall;
                                VDBG(dev, "clear dev remote wakeup\n");
                                goto succeed;
@@ -1519,7 +1519,7 @@ succeed:
        dev->req_config = (ctrl.bRequest == USB_REQ_SET_CONFIGURATION
                                && ctrl.bRequestType == USB_RECIP_DEVICE);
        if (unlikely(dev->req_config))
-               dev->configured = (ctrl.wValue != __constant_cpu_to_le16(0));
+               dev->configured = (ctrl.wValue != cpu_to_le16(0));
 
        /* delegate everything to the gadget driver.
         * it may respond after this irq handler returns.
index cd67ac75e6241097796399a415449084885b63eb..168658b4b4e26d2bc7b2614cf5b8cb891a3614e5 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *     driver/usb/gadget/imx_udc.c
  *
- *     Copyright (C) 2005 Mike Lee(eemike@gmail.com)
+ *     Copyright (C) 2005 Mike Lee <eemike@gmail.com>
  *     Copyright (C) 2008 Darius Augulis <augulis.darius@gmail.com>
  *
  *     This program is free software; you can redistribute it and/or modify
@@ -28,6 +28,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/clk.h>
 #include <linux/delay.h>
+#include <linux/timer.h>
 
 #include <linux/usb/ch9.h>
 #include <linux/usb/gadget.h>
@@ -51,7 +52,8 @@ void ep0_chg_stat(const char *label, struct imx_udc_struct *imx_usb,
 void imx_udc_enable(struct imx_udc_struct *imx_usb)
 {
        int temp = __raw_readl(imx_usb->base + USB_CTRL);
-       __raw_writel(temp | CTRL_FE_ENA | CTRL_AFE_ENA, imx_usb->base + USB_CTRL);
+       __raw_writel(temp | CTRL_FE_ENA | CTRL_AFE_ENA,
+                                               imx_usb->base + USB_CTRL);
        imx_usb->gadget.speed = USB_SPEED_FULL;
 }
 
@@ -126,7 +128,8 @@ void imx_udc_config(struct imx_udc_struct *imx_usb)
                        for (j = 0; j < 5; j++) {
                                __raw_writeb(ep_conf[j],
                                        imx_usb->base + USB_DDAT);
-                               do {} while (__raw_readl(imx_usb->base + USB_DADR)
+                               do {} while (__raw_readl(imx_usb->base
+                                                               + USB_DADR)
                                        & DADR_BSY);
                        }
                }
@@ -183,7 +186,8 @@ void imx_udc_init_ep(struct imx_udc_struct *imx_usb)
                temp = (EP_DIR(imx_ep) << 7) | (max << 5)
                        | (imx_ep->bmAttributes << 3);
                __raw_writel(temp, imx_usb->base + USB_EP_STAT(i));
-               __raw_writel(temp | EPSTAT_FLUSH, imx_usb->base + USB_EP_STAT(i));
+               __raw_writel(temp | EPSTAT_FLUSH,
+                                               imx_usb->base + USB_EP_STAT(i));
                D_INI(imx_usb->dev, "<%s> ep%d_stat %08x\n", __func__, i,
                        __raw_readl(imx_usb->base + USB_EP_STAT(i)));
        }
@@ -278,15 +282,18 @@ void imx_ep_stall(struct imx_ep_struct *imx_ep)
        struct imx_udc_struct *imx_usb = imx_ep->imx_usb;
        int temp, i;
 
-       D_ERR(imx_usb->dev, "<%s> Forced stall on %s\n", __func__, imx_ep->ep.name);
+       D_ERR(imx_usb->dev,
+               "<%s> Forced stall on %s\n", __func__, imx_ep->ep.name);
 
        imx_flush(imx_ep);
 
        /* Special care for ep0 */
-       if (EP_NO(imx_ep)) {
+       if (!EP_NO(imx_ep)) {
                temp = __raw_readl(imx_usb->base + USB_CTRL);
-               __raw_writel(temp | CTRL_CMDOVER | CTRL_CMDERROR, imx_usb->base + USB_CTRL);
-               do { } while (__raw_readl(imx_usb->base + USB_CTRL) & CTRL_CMDOVER);
+               __raw_writel(temp | CTRL_CMDOVER | CTRL_CMDERROR,
+                                               imx_usb->base + USB_CTRL);
+               do { } while (__raw_readl(imx_usb->base + USB_CTRL)
+                                               & CTRL_CMDOVER);
                temp = __raw_readl(imx_usb->base + USB_CTRL);
                __raw_writel(temp & ~CTRL_CMDERROR, imx_usb->base + USB_CTRL);
        }
@@ -296,12 +303,13 @@ void imx_ep_stall(struct imx_ep_struct *imx_ep)
                        imx_usb->base + USB_EP_STAT(EP_NO(imx_ep)));
 
                for (i = 0; i < 100; i ++) {
-                       temp = __raw_readl(imx_usb->base + USB_EP_STAT(EP_NO(imx_ep)));
+                       temp = __raw_readl(imx_usb->base
+                                               + USB_EP_STAT(EP_NO(imx_ep)));
                        if (!(temp & EPSTAT_STALL))
                                break;
                        udelay(20);
                }
-               if (i == 50)
+               if (i == 100)
                        D_ERR(imx_usb->dev, "<%s> Non finished stall on %s\n",
                                __func__, imx_ep->ep.name);
        }
@@ -325,7 +333,8 @@ static int imx_udc_wakeup(struct usb_gadget *_gadget)
  *******************************************************************************
  */
 
-static void ep_add_request(struct imx_ep_struct *imx_ep, struct imx_request *req)
+static void ep_add_request(struct imx_ep_struct *imx_ep,
+                                                       struct imx_request *req)
 {
        if (unlikely(!req))
                return;
@@ -334,7 +343,8 @@ static void ep_add_request(struct imx_ep_struct *imx_ep, struct imx_request *req
        list_add_tail(&req->queue, &imx_ep->queue);
 }
 
-static void ep_del_request(struct imx_ep_struct *imx_ep, struct imx_request *req)
+static void ep_del_request(struct imx_ep_struct *imx_ep,
+                                                       struct imx_request *req)
 {
        if (unlikely(!req))
                return;
@@ -343,7 +353,8 @@ static void ep_del_request(struct imx_ep_struct *imx_ep, struct imx_request *req
        req->in_use = 0;
 }
 
-static void done(struct imx_ep_struct *imx_ep, struct imx_request *req, int status)
+static void done(struct imx_ep_struct *imx_ep,
+                                       struct imx_request *req, int status)
 {
        ep_del_request(imx_ep, req);
 
@@ -494,7 +505,8 @@ static int write_fifo(struct imx_ep_struct *imx_ep, struct imx_request *req)
                                __func__, imx_ep->ep.name, req,
                                completed ? "completed" : "not completed");
                        if (!EP_NO(imx_ep))
-                               ep0_chg_stat(__func__, imx_ep->imx_usb, EP0_IDLE);
+                               ep0_chg_stat(__func__,
+                                               imx_ep->imx_usb, EP0_IDLE);
                }
        }
 
@@ -539,10 +551,9 @@ static int handle_ep0(struct imx_ep_struct *imx_ep)
        struct imx_request *req = NULL;
        int ret = 0;
 
-       if (!list_empty(&imx_ep->queue))
+       if (!list_empty(&imx_ep->queue)) {
                req = list_entry(imx_ep->queue.next, struct imx_request, queue);
 
-       if (req) {
                switch (imx_ep->imx_usb->ep0state) {
 
                case EP0_IN_DATA_PHASE:                 /* GET_DESCRIPTOR */
@@ -561,6 +572,10 @@ static int handle_ep0(struct imx_ep_struct *imx_ep)
                }
        }
 
+       else
+               D_ERR(imx_ep->imx_usb->dev, "<%s> no request on %s\n",
+                                               __func__, imx_ep->ep.name);
+
        return ret;
 }
 
@@ -583,7 +598,8 @@ static void handle_ep0_devreq(struct imx_udc_struct *imx_usb)
                                "<%s> no setup packet received\n", __func__);
                        goto stall;
                }
-               u.word[i] = __raw_readl(imx_usb->base + USB_EP_FDAT(EP_NO(imx_ep)));
+               u.word[i] = __raw_readl(imx_usb->base
+                                               + USB_EP_FDAT(EP_NO(imx_ep)));
        }
 
        temp = imx_ep_empty(imx_ep);
@@ -759,7 +775,7 @@ static int imx_ep_queue
        */
        if (imx_usb->set_config && !EP_NO(imx_ep)) {
                imx_usb->set_config = 0;
-               D_EPX(imx_usb->dev,
+               D_ERR(imx_usb->dev,
                        "<%s> gadget reply set config\n", __func__);
                return 0;
        }
@@ -779,28 +795,29 @@ static int imx_ep_queue
                return -ESHUTDOWN;
        }
 
-       local_irq_save(flags);
-
        /* Debug */
        D_REQ(imx_usb->dev, "<%s> ep%d %s request for [%d] bytes\n",
                __func__, EP_NO(imx_ep),
-               ((!EP_NO(imx_ep) && imx_ep->imx_usb->ep0state == EP0_IN_DATA_PHASE)
-               || (EP_NO(imx_ep) && EP_DIR(imx_ep))) ? "IN" : "OUT", usb_req->length);
+               ((!EP_NO(imx_ep) && imx_ep->imx_usb->ep0state
+                                                       == EP0_IN_DATA_PHASE)
+               || (EP_NO(imx_ep) && EP_DIR(imx_ep)))
+                                       ? "IN" : "OUT", usb_req->length);
        dump_req(__func__, imx_ep, usb_req);
 
        if (imx_ep->stopped) {
                usb_req->status = -ESHUTDOWN;
-               ret = -ESHUTDOWN;
-               goto out;
+               return -ESHUTDOWN;
        }
 
        if (req->in_use) {
                D_ERR(imx_usb->dev,
                        "<%s> refusing to queue req %p (already queued)\n",
                        __func__, req);
-               goto out;
+               return 0;
        }
 
+       local_irq_save(flags);
+
        usb_req->status = -EINPROGRESS;
        usb_req->actual = 0;
 
@@ -810,7 +827,7 @@ static int imx_ep_queue
                ret = handle_ep0(imx_ep);
        else
                ret = handle_ep(imx_ep);
-out:
+
        local_irq_restore(flags);
        return ret;
 }
@@ -997,71 +1014,32 @@ static void udc_stop_activity(struct imx_udc_struct *imx_usb,
  *******************************************************************************
  */
 
-static irqreturn_t imx_udc_irq(int irq, void *dev)
+/*
+ * Called when timer expires.
+ * Timer is started when CFG_CHG is received.
+ */
+static void handle_config(unsigned long data)
 {
-       struct imx_udc_struct *imx_usb = dev;
+       struct imx_udc_struct *imx_usb = (void *)data;
        struct usb_ctrlrequest u;
        int temp, cfg, intf, alt;
-       int intr = __raw_readl(imx_usb->base + USB_INTR);
-
-       if (intr & (INTR_WAKEUP | INTR_SUSPEND | INTR_RESUME | INTR_RESET_START
-                       | INTR_RESET_STOP | INTR_CFG_CHG)) {
-                               dump_intr(__func__, intr, imx_usb->dev);
-                               dump_usb_stat(__func__, imx_usb);
-       }
-
-       if (!imx_usb->driver) {
-               /*imx_udc_disable(imx_usb);*/
-               goto end_irq;
-       }
-
-       if (intr & INTR_WAKEUP) {
-               if (imx_usb->gadget.speed == USB_SPEED_UNKNOWN
-                       && imx_usb->driver && imx_usb->driver->resume)
-                               imx_usb->driver->resume(&imx_usb->gadget);
-               imx_usb->set_config = 0;
-               imx_usb->gadget.speed = USB_SPEED_FULL;
-       }
-
-       if (intr & INTR_SUSPEND) {
-               if (imx_usb->gadget.speed != USB_SPEED_UNKNOWN
-                       && imx_usb->driver && imx_usb->driver->suspend)
-                               imx_usb->driver->suspend(&imx_usb->gadget);
-               imx_usb->set_config = 0;
-               imx_usb->gadget.speed = USB_SPEED_UNKNOWN;
-       }
 
-       if (intr & INTR_RESET_START) {
-               __raw_writel(intr, imx_usb->base + USB_INTR);
-               udc_stop_activity(imx_usb, imx_usb->driver);
-               imx_usb->set_config = 0;
-               imx_usb->gadget.speed = USB_SPEED_UNKNOWN;
-       }
-
-       if (intr & INTR_RESET_STOP)
-               imx_usb->gadget.speed = USB_SPEED_FULL;
+       local_irq_disable();
 
-       if (intr & INTR_CFG_CHG) {
-               __raw_writel(INTR_CFG_CHG, imx_usb->base + USB_INTR);
-               temp = __raw_readl(imx_usb->base + USB_STAT);
-               cfg  = (temp & STAT_CFG) >> 5;
-               intf = (temp & STAT_INTF) >> 3;
-               alt  =  temp & STAT_ALTSET;
+       temp = __raw_readl(imx_usb->base + USB_STAT);
+       cfg  = (temp & STAT_CFG) >> 5;
+       intf = (temp & STAT_INTF) >> 3;
+       alt  =  temp & STAT_ALTSET;
 
-               D_REQ(imx_usb->dev,
-                       "<%s> orig config C=%d, I=%d, A=%d / "
-                       "req config C=%d, I=%d, A=%d\n",
-                       __func__, imx_usb->cfg, imx_usb->intf, imx_usb->alt,
-                       cfg, intf, alt);
+       D_REQ(imx_usb->dev,
+               "<%s> orig config C=%d, I=%d, A=%d / "
+               "req config C=%d, I=%d, A=%d\n",
+               __func__, imx_usb->cfg, imx_usb->intf, imx_usb->alt,
+               cfg, intf, alt);
 
-               if (cfg != 1 && cfg != 2)
-                       goto end_irq;
+       if (cfg == 1 || cfg == 2) {
 
-               imx_usb->set_config = 0;
-
-               /* Config setup */
                if (imx_usb->cfg != cfg) {
-                       D_REQ(imx_usb->dev, "<%s> Change config start\n",__func__);
                        u.bRequest = USB_REQ_SET_CONFIGURATION;
                        u.bRequestType = USB_DIR_OUT |
                                        USB_TYPE_STANDARD |
@@ -1070,14 +1048,10 @@ static irqreturn_t imx_udc_irq(int irq, void *dev)
                        u.wIndex = 0;
                        u.wLength = 0;
                        imx_usb->cfg = cfg;
-                       imx_usb->set_config = 1;
                        imx_usb->driver->setup(&imx_usb->gadget, &u);
-                       imx_usb->set_config = 0;
-                       D_REQ(imx_usb->dev, "<%s> Change config done\n",__func__);
 
                }
                if (imx_usb->intf != intf || imx_usb->alt != alt) {
-                       D_REQ(imx_usb->dev, "<%s> Change interface start\n",__func__);
                        u.bRequest = USB_REQ_SET_INTERFACE;
                        u.bRequestType = USB_DIR_OUT |
                                          USB_TYPE_STANDARD |
@@ -1087,20 +1061,92 @@ static irqreturn_t imx_udc_irq(int irq, void *dev)
                        u.wLength = 0;
                        imx_usb->intf = intf;
                        imx_usb->alt = alt;
-                       imx_usb->set_config = 1;
                        imx_usb->driver->setup(&imx_usb->gadget, &u);
-                       imx_usb->set_config = 0;
-                       D_REQ(imx_usb->dev, "<%s> Change interface done\n",__func__);
                }
        }
 
+       imx_usb->set_config = 0;
+
+       local_irq_enable();
+}
+
+static irqreturn_t imx_udc_irq(int irq, void *dev)
+{
+       struct imx_udc_struct *imx_usb = dev;
+       int intr = __raw_readl(imx_usb->base + USB_INTR);
+       int temp;
+
+       if (intr & (INTR_WAKEUP | INTR_SUSPEND | INTR_RESUME | INTR_RESET_START
+                       | INTR_RESET_STOP | INTR_CFG_CHG)) {
+                               dump_intr(__func__, intr, imx_usb->dev);
+                               dump_usb_stat(__func__, imx_usb);
+       }
+
+       if (!imx_usb->driver)
+               goto end_irq;
+
        if (intr & INTR_SOF) {
+               /* Copy from Freescale BSP.
+                  We must enable SOF intr and set CMDOVER.
+                  Datasheet don't specifiy this action, but it
+                  is done in Freescale BSP, so just copy it.
+               */
                if (imx_usb->ep0state == EP0_IDLE) {
                        temp = __raw_readl(imx_usb->base + USB_CTRL);
-                       __raw_writel(temp | CTRL_CMDOVER, imx_usb->base + USB_CTRL);
+                       __raw_writel(temp | CTRL_CMDOVER,
+                                               imx_usb->base + USB_CTRL);
                }
        }
 
+       if (intr & INTR_CFG_CHG) {
+               /* A workaround of serious IMX UDC bug.
+                  Handling of CFG_CHG should be delayed for some time, because
+                  IMX does not NACK the host when CFG_CHG interrupt is pending.
+                  There is no time to handle current CFG_CHG
+                  if next CFG_CHG or SETUP packed is send immediately.
+                  We have to clear CFG_CHG, start the timer and
+                  NACK the host by setting CTRL_CMDOVER
+                  if it sends any SETUP packet.
+                  When timer expires, handler is called to handle configuration
+                  changes. While CFG_CHG is not handled (set_config=1),
+                  we must NACK the host to every SETUP packed.
+                  This delay prevents from going out of sync with host.
+                */
+               __raw_writel(INTR_CFG_CHG, imx_usb->base + USB_INTR);
+               imx_usb->set_config = 1;
+               mod_timer(&imx_usb->timer, jiffies + 5);
+               goto end_irq;
+       }
+
+       if (intr & INTR_WAKEUP) {
+               if (imx_usb->gadget.speed == USB_SPEED_UNKNOWN
+                       && imx_usb->driver && imx_usb->driver->resume)
+                               imx_usb->driver->resume(&imx_usb->gadget);
+               imx_usb->set_config = 0;
+               del_timer(&imx_usb->timer);
+               imx_usb->gadget.speed = USB_SPEED_FULL;
+       }
+
+       if (intr & INTR_SUSPEND) {
+               if (imx_usb->gadget.speed != USB_SPEED_UNKNOWN
+                       && imx_usb->driver && imx_usb->driver->suspend)
+                               imx_usb->driver->suspend(&imx_usb->gadget);
+               imx_usb->set_config = 0;
+               del_timer(&imx_usb->timer);
+               imx_usb->gadget.speed = USB_SPEED_UNKNOWN;
+       }
+
+       if (intr & INTR_RESET_START) {
+               __raw_writel(intr, imx_usb->base + USB_INTR);
+               udc_stop_activity(imx_usb, imx_usb->driver);
+               imx_usb->set_config = 0;
+               del_timer(&imx_usb->timer);
+               imx_usb->gadget.speed = USB_SPEED_UNKNOWN;
+       }
+
+       if (intr & INTR_RESET_STOP)
+               imx_usb->gadget.speed = USB_SPEED_FULL;
+
 end_irq:
        __raw_writel(intr, imx_usb->base + USB_INTR);
        return IRQ_HANDLED;
@@ -1109,6 +1155,7 @@ end_irq:
 static irqreturn_t imx_udc_ctrl_irq(int irq, void *dev)
 {
        struct imx_udc_struct *imx_usb = dev;
+       struct imx_ep_struct *imx_ep = &imx_usb->imx_ep[0];
        int intr = __raw_readl(imx_usb->base + USB_EP_INTR(0));
 
        dump_ep_intr(__func__, 0, intr, imx_usb->dev);
@@ -1118,16 +1165,15 @@ static irqreturn_t imx_udc_ctrl_irq(int irq, void *dev)
                return IRQ_HANDLED;
        }
 
-       /* DEVREQ IRQ has highest priority */
+       /* DEVREQ has highest priority */
        if (intr & (EPINTR_DEVREQ | EPINTR_MDEVREQ))
                handle_ep0_devreq(imx_usb);
        /* Seem i.MX is missing EOF interrupt sometimes.
-        * Therefore we monitor both EOF and FIFO_EMPTY interrups
-        * when transmiting, and both EOF and FIFO_FULL when
-        * receiving data.
+        * Therefore we don't monitor EOF.
+        * We call handle_ep0() only if a request is queued for ep0.
         */
-       else if (intr & (EPINTR_EOF | EPINTR_FIFO_EMPTY | EPINTR_FIFO_FULL))
-               handle_ep0(&imx_usb->imx_ep[0]);
+       else if (!list_empty(&imx_ep->queue))
+               handle_ep0(imx_ep);
 
        __raw_writel(intr, imx_usb->base + USB_EP_INTR(0));
 
@@ -1318,6 +1364,7 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
 
        udc_stop_activity(imx_usb, driver);
        imx_udc_disable(imx_usb);
+       del_timer(&imx_usb->timer);
 
        driver->unbind(&imx_usb->gadget);
        imx_usb->gadget.dev.driver = NULL;
@@ -1435,6 +1482,10 @@ static int __init imx_udc_probe(struct platform_device *pdev)
        usb_init_data(imx_usb);
        imx_udc_init(imx_usb);
 
+       init_timer(&imx_usb->timer);
+       imx_usb->timer.function = handle_config;
+       imx_usb->timer.data = (unsigned long)imx_usb;
+
        return 0;
 
 fail3:
@@ -1457,6 +1508,7 @@ static int __exit imx_udc_remove(struct platform_device *pdev)
        int i;
 
        imx_udc_disable(imx_usb);
+       del_timer(&imx_usb->timer);
 
        for (i = 0; i < IMX_USB_NB_EP + 1; i++)
                free_irq(imx_usb->usbd_int[i], imx_usb);
index 850076937d8d717d8edf6153054f4f99f3ac4e5c..b48ad59603d1c6f32a21d85131c477119ea4a9f1 100644 (file)
@@ -23,7 +23,8 @@
 /* Helper macros */
 #define EP_NO(ep)      ((ep->bEndpointAddress) & ~USB_DIR_IN) /* IN:1, OUT:0 */
 #define EP_DIR(ep)     ((ep->bEndpointAddress) & USB_DIR_IN ? 1 : 0)
-#define irq_to_ep(irq) (((irq) >= USBD_INT0) || ((irq) <= USBD_INT6) ? ((irq) - USBD_INT0) : (USBD_INT6)) /*should not happen*/
+#define irq_to_ep(irq) (((irq) >= USBD_INT0) || ((irq) <= USBD_INT6) \
+               ? ((irq) - USBD_INT0) : (USBD_INT6)) /*should not happen*/
 #define ep_to_irq(ep)  (EP_NO((ep)) + USBD_INT0)
 #define IMX_USB_NB_EP  6
 
@@ -58,6 +59,7 @@ struct imx_udc_struct {
        struct device                           *dev;
        struct imx_ep_struct                    imx_ep[IMX_USB_NB_EP];
        struct clk                              *clk;
+       struct timer_list                       timer;
        enum ep0_state                          ep0state;
        struct resource                         *res;
        void __iomem                            *base;
@@ -88,8 +90,8 @@ struct imx_udc_struct {
 #define  USB_EP_FDAT3(x)       (0x3F + (x*0x30)) /* USB FIFO data */
 #define  USB_EP_FSTAT(x)       (0x40 + (x*0x30)) /* USB FIFO status */
 #define  USB_EP_FCTRL(x)       (0x44 + (x*0x30)) /* USB FIFO control */
-#define  USB_EP_LRFP(x)                (0x48 + (x*0x30)) /* USB last read frame pointer */
-#define  USB_EP_LWFP(x)                (0x4C + (x*0x30)) /* USB last write frame pointer */
+#define  USB_EP_LRFP(x)                (0x48 + (x*0x30)) /* USB last rd f. pointer */
+#define  USB_EP_LWFP(x)                (0x4C + (x*0x30)) /* USB last wr f. pointer */
 #define  USB_EP_FALRM(x)       (0x50 + (x*0x30)) /* USB FIFO alarm */
 #define  USB_EP_FRDP(x)                (0x54 + (x*0x30)) /* USB FIFO read pointer */
 #define  USB_EP_FWRP(x)                (0x58 + (x*0x30)) /* USB FIFO write pointer */
@@ -170,7 +172,7 @@ struct imx_udc_struct {
 /* #define DEBUG_IRQ */
 /* #define DEBUG_EPIRQ */
 /* #define DEBUG_DUMP */
-#define DEBUG_ERR
+/* #define DEBUG_ERR */
 
 #ifdef DEBUG_REQ
        #define D_REQ(dev, args...)     dev_dbg(dev, ## args)
@@ -228,7 +230,8 @@ struct imx_udc_struct {
 #endif /* DEBUG_IRQ */
 
 #ifdef DEBUG_EPIRQ
-       static void dump_ep_intr(const char *label, int nr, int irqreg, struct device *dev)
+       static void dump_ep_intr(const char *label, int nr, int irqreg,
+                                                       struct device *dev)
        {
                dev_dbg(dev, "<%s> EP%d_INTR=[%s%s%s%s%s%s%s%s%s]\n", label, nr,
                        (irqreg & EPINTR_FIFO_FULL) ? " full" : "",
@@ -246,7 +249,8 @@ struct imx_udc_struct {
 #endif /* DEBUG_IRQ */
 
 #ifdef DEBUG_DUMP
-       static void dump_usb_stat(const char *label, struct imx_udc_struct *imx_usb)
+       static void dump_usb_stat(const char *label,
+                                               struct imx_udc_struct *imx_usb)
        {
                int temp = __raw_readl(imx_usb->base + USB_STAT);
 
@@ -259,12 +263,15 @@ struct imx_udc_struct {
                        (temp & STAT_ALTSET));
        }
 
-       static void dump_ep_stat(const char *label, struct imx_ep_struct *imx_ep)
+       static void dump_ep_stat(const char *label,
+                                               struct imx_ep_struct *imx_ep)
        {
-               int temp = __raw_readl(imx_ep->imx_usb->base + USB_EP_INTR(EP_NO(imx_ep)));
+               int temp = __raw_readl(imx_ep->imx_usb->base
+                                               + USB_EP_INTR(EP_NO(imx_ep)));
 
                dev_dbg(imx_ep->imx_usb->dev,
-                       "<%s> EP%d_INTR=[%s%s%s%s%s%s%s%s%s]\n", label, EP_NO(imx_ep),
+                       "<%s> EP%d_INTR=[%s%s%s%s%s%s%s%s%s]\n",
+                       label, EP_NO(imx_ep),
                        (temp & EPINTR_FIFO_FULL) ? " full" : "",
                        (temp & EPINTR_FIFO_EMPTY) ? " fempty" : "",
                        (temp & EPINTR_FIFO_ERROR) ? " ferr" : "",
@@ -275,18 +282,22 @@ struct imx_udc_struct {
                        (temp & EPINTR_DEVREQ) ? " devreq" : "",
                        (temp & EPINTR_EOT) ? " eot" : "");
 
-               temp = __raw_readl(imx_ep->imx_usb->base + USB_EP_STAT(EP_NO(imx_ep)));
+               temp = __raw_readl(imx_ep->imx_usb->base
+                                               + USB_EP_STAT(EP_NO(imx_ep)));
 
                dev_dbg(imx_ep->imx_usb->dev,
-                       "<%s> EP%d_STAT=[%s%s bcount=%d]\n", label, EP_NO(imx_ep),
+                       "<%s> EP%d_STAT=[%s%s bcount=%d]\n",
+                       label, EP_NO(imx_ep),
                        (temp & EPSTAT_SIP) ? " sip" : "",
                        (temp & EPSTAT_STALL) ? " stall" : "",
                        (temp & EPSTAT_BCOUNT) >> 16);
 
-               temp = __raw_readl(imx_ep->imx_usb->base + USB_EP_FSTAT(EP_NO(imx_ep)));
+               temp = __raw_readl(imx_ep->imx_usb->base
+                                               + USB_EP_FSTAT(EP_NO(imx_ep)));
 
                dev_dbg(imx_ep->imx_usb->dev,
-                       "<%s> EP%d_FSTAT=[%s%s%s%s%s%s%s]\n", label, EP_NO(imx_ep),
+                       "<%s> EP%d_FSTAT=[%s%s%s%s%s%s%s]\n",
+                       label, EP_NO(imx_ep),
                        (temp & FSTAT_ERR) ? " ferr" : "",
                        (temp & FSTAT_UF) ? " funder" : "",
                        (temp & FSTAT_OF) ? " fover" : "",
@@ -296,19 +307,23 @@ struct imx_udc_struct {
                        (temp & FSTAT_EMPTY) ? " fempty" : "");
        }
 
-       static void dump_req(const char *label, struct imx_ep_struct *imx_ep, struct usb_request *req)
+       static void dump_req(const char *label, struct imx_ep_struct *imx_ep,
+                                                       struct usb_request *req)
        {
                int i;
 
                if (!req || !req->buf) {
-                       dev_dbg(imx_ep->imx_usb->dev, "<%s> req or req buf is free\n", label);
+                       dev_dbg(imx_ep->imx_usb->dev,
+                                       "<%s> req or req buf is free\n", label);
                        return;
                }
 
-               if ((!EP_NO(imx_ep) && imx_ep->imx_usb->ep0state == EP0_IN_DATA_PHASE)
+               if ((!EP_NO(imx_ep) && imx_ep->imx_usb->ep0state
+                       == EP0_IN_DATA_PHASE)
                        || (EP_NO(imx_ep) && EP_DIR(imx_ep))) {
 
-                       dev_dbg(imx_ep->imx_usb->dev, "<%s> request dump <", label);
+                       dev_dbg(imx_ep->imx_usb->dev,
+                                               "<%s> request dump <", label);
                        for (i = 0; i < req->length; i++)
                                printk("%02x-", *((u8 *)req->buf + i));
                        printk(">\n");
index 317b48fdbf01b302bd9442d13b9bb923408a1c17..d20937f28a1988209557a356f061900ec2706d35 100644 (file)
@@ -1334,7 +1334,7 @@ static void make_qualifier (struct dev_data *dev)
 
        qual.bLength = sizeof qual;
        qual.bDescriptorType = USB_DT_DEVICE_QUALIFIER;
-       qual.bcdUSB = __constant_cpu_to_le16 (0x0200);
+       qual.bcdUSB = cpu_to_le16 (0x0200);
 
        desc = dev->dev;
        qual.bDeviceClass = desc->bDeviceClass;
@@ -1908,7 +1908,7 @@ dev_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
                        || dev->dev->bNumConfigurations != 1)
                goto fail;
        dev->dev->bNumConfigurations = 1;
-       dev->dev->bcdUSB = __constant_cpu_to_le16 (0x0200);
+       dev->dev->bcdUSB = cpu_to_le16 (0x0200);
 
        /* triggers gadgetfs_bind(); then we can enumerate. */
        spin_unlock_irq (&dev->lock);
index d554b08956031c15c6bb633ec99005239d5529ce..6cd3d54f56409d9255da3620e624f500b75511ed 100644 (file)
@@ -432,8 +432,8 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
        device_add(&dev->gadget.dev);
        retval = driver->bind(&dev->gadget);
        if (retval) {
-               printk("%s: bind to driver %s --> error %d\n", dev->gadget.name,
-                      driver->driver.name, retval);
+               printk(KERN_WARNING "%s: bind to driver %s --> error %d\n",
+                      dev->gadget.name, driver->driver.name, retval);
                device_del(&dev->gadget.dev);
 
                dev->driver = 0;
@@ -445,8 +445,8 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
         * for set_configuration as well as eventual disconnect.
         * NOTE:  this shouldn't power up until later.
         */
-       printk("%s: registered gadget driver '%s'\n", dev->gadget.name,
-              driver->driver.name);
+       printk(KERN_WARNING "%s: registered gadget driver '%s'\n",
+              dev->gadget.name, driver->driver.name);
 
        udc_enable(dev);
 
@@ -581,7 +581,8 @@ static int read_fifo(struct lh7a40x_ep *ep, struct lh7a40x_request *req)
                         * discard the extra data.
                         */
                        if (req->req.status != -EOVERFLOW)
-                               printk("%s overflow %d\n", ep->ep.name, count);
+                               printk(KERN_WARNING "%s overflow %d\n",
+                                      ep->ep.name, count);
                        req->req.status = -EOVERFLOW;
                } else {
                        *buf++ = byte;
@@ -831,7 +832,8 @@ static void lh7a40x_out_epn(struct lh7a40x_udc *dev, u32 ep_idx, u32 intr)
                                                       queue);
 
                                if (!req) {
-                                       printk("%s: NULL REQ %d\n",
+                                       printk(KERN_WARNING
+                                              "%s: NULL REQ %d\n",
                                               __func__, ep_idx);
                                        flush(ep);
                                        break;
@@ -844,7 +846,7 @@ static void lh7a40x_out_epn(struct lh7a40x_udc *dev, u32 ep_idx, u32 intr)
 
        } else {
                /* Throw packet away.. */
-               printk("%s: No descriptor?!?\n", __func__);
+               printk(KERN_WARNING "%s: No descriptor?!?\n", __func__);
                flush(ep);
        }
 }
index 12c6d83b218c07ae26c241aa5fc3b4540def2e59..9498be87a72450dd2e31c9945351a1924f753c90 100644 (file)
@@ -142,8 +142,8 @@ static char *type_string (u8 bmAttributes)
 
 #include "net2280.h"
 
-#define valid_bit      __constant_cpu_to_le32 (1 << VALID_BIT)
-#define dma_done_ie    __constant_cpu_to_le32 (1 << DMA_DONE_INTERRUPT_ENABLE)
+#define valid_bit      cpu_to_le32 (1 << VALID_BIT)
+#define dma_done_ie    cpu_to_le32 (1 << DMA_DONE_INTERRUPT_ENABLE)
 
 /*-------------------------------------------------------------------------*/
 
@@ -425,7 +425,7 @@ net2280_alloc_request (struct usb_ep *_ep, gfp_t gfp_flags)
                        return NULL;
                }
                td->dmacount = 0;       /* not VALID */
-               td->dmaaddr = __constant_cpu_to_le32 (DMA_ADDR_INVALID);
+               td->dmaaddr = cpu_to_le32 (DMA_ADDR_INVALID);
                td->dmadesc = td->dmaaddr;
                req->td = td;
        }
@@ -775,7 +775,7 @@ static void start_dma (struct net2280_ep *ep, struct net2280_request *req)
        fill_dma_desc (ep, req, 1);
 
        if (!use_dma_chaining)
-               req->td->dmacount |= __constant_cpu_to_le32 (1 << END_OF_CHAIN);
+               req->td->dmacount |= cpu_to_le32 (1 << END_OF_CHAIN);
 
        start_queue (ep, tmp, req->td_dma);
 }
@@ -2407,9 +2407,9 @@ static void handle_stat0_irqs (struct net2280 *dev, u32 stat)
 
                        if (readl (&e->regs->ep_rsp)
                                        & (1 << SET_ENDPOINT_HALT))
-                               status = __constant_cpu_to_le32 (1);
+                               status = cpu_to_le32 (1);
                        else
-                               status = __constant_cpu_to_le32 (0);
+                               status = cpu_to_le32 (0);
 
                        /* don't bother with a request object! */
                        writel (0, &dev->epregs [0].ep_irqenb);
@@ -2667,7 +2667,7 @@ static void handle_stat1_irqs (struct net2280 *dev, u32 stat)
                                req = list_entry (ep->queue.next,
                                                struct net2280_request, queue);
                                dmacount = req->td->dmacount;
-                               dmacount &= __constant_cpu_to_le32 (
+                               dmacount &= cpu_to_le32 (
                                                (1 << VALID_BIT)
                                                | DMA_BYTE_COUNT_MASK);
                                if (dmacount && (dmacount & valid_bit) == 0)
@@ -2881,7 +2881,7 @@ static int net2280_probe (struct pci_dev *pdev, const struct pci_device_id *id)
                        goto done;
                }
                td->dmacount = 0;       /* not VALID */
-               td->dmaaddr = __constant_cpu_to_le32 (DMA_ADDR_INVALID);
+               td->dmaaddr = cpu_to_le32 (DMA_ADDR_INVALID);
                td->dmadesc = td->dmaaddr;
                dev->ep [i].dummy = td;
        }
index 5a3034fdfe473f0f777e80bd426d2882a8e9fd53..29500154d00c57d5f74a299fcfaa90610fecad03 100644 (file)
@@ -225,12 +225,12 @@ module_param(qlen, uint, S_IRUGO|S_IWUSR);
 static struct usb_device_descriptor device_desc = {
        .bLength =              sizeof device_desc,
        .bDescriptorType =      USB_DT_DEVICE,
-       .bcdUSB =               __constant_cpu_to_le16(0x0200),
+       .bcdUSB =               cpu_to_le16(0x0200),
        .bDeviceClass =         USB_CLASS_PER_INTERFACE,
        .bDeviceSubClass =      0,
        .bDeviceProtocol =      0,
-       .idVendor =             __constant_cpu_to_le16(PRINTER_VENDOR_NUM),
-       .idProduct =            __constant_cpu_to_le16(PRINTER_PRODUCT_NUM),
+       .idVendor =             cpu_to_le16(PRINTER_VENDOR_NUM),
+       .idProduct =            cpu_to_le16(PRINTER_PRODUCT_NUM),
        .iManufacturer =        STRING_MANUFACTURER,
        .iProduct =             STRING_PRODUCT,
        .iSerialNumber =        STRING_SERIALNUM,
@@ -299,20 +299,20 @@ static struct usb_endpoint_descriptor hs_ep_in_desc = {
        .bLength =              USB_DT_ENDPOINT_SIZE,
        .bDescriptorType =      USB_DT_ENDPOINT,
        .bmAttributes =         USB_ENDPOINT_XFER_BULK,
-       .wMaxPacketSize =       __constant_cpu_to_le16(512)
+       .wMaxPacketSize =       cpu_to_le16(512)
 };
 
 static struct usb_endpoint_descriptor hs_ep_out_desc = {
        .bLength =              USB_DT_ENDPOINT_SIZE,
        .bDescriptorType =      USB_DT_ENDPOINT,
        .bmAttributes =         USB_ENDPOINT_XFER_BULK,
-       .wMaxPacketSize =       __constant_cpu_to_le16(512)
+       .wMaxPacketSize =       cpu_to_le16(512)
 };
 
 static struct usb_qualifier_descriptor dev_qualifier = {
        .bLength =              sizeof dev_qualifier,
        .bDescriptorType =      USB_DT_DEVICE_QUALIFIER,
-       .bcdUSB =               __constant_cpu_to_le16(0x0200),
+       .bcdUSB =               cpu_to_le16(0x0200),
        .bDeviceClass =         USB_CLASS_PRINTER,
        .bNumConfigurations =   1
 };
@@ -1406,16 +1406,16 @@ printer_bind(struct usb_gadget *gadget)
                        gadget->name);
                /* unrecognized, but safe unless bulk is REALLY quirky */
                device_desc.bcdDevice =
-                       __constant_cpu_to_le16(0xFFFF);
+                       cpu_to_le16(0xFFFF);
        }
        snprintf(manufacturer, sizeof(manufacturer), "%s %s with %s",
                init_utsname()->sysname, init_utsname()->release,
                gadget->name);
 
        device_desc.idVendor =
-               __constant_cpu_to_le16(PRINTER_VENDOR_NUM);
+               cpu_to_le16(PRINTER_VENDOR_NUM);
        device_desc.idProduct =
-               __constant_cpu_to_le16(PRINTER_PRODUCT_NUM);
+               cpu_to_le16(PRINTER_PRODUCT_NUM);
 
        /* support optional vendor/distro customization */
        if (idVendor) {
index 990f40f988d4334d69683f3533d3347013c7b84a..8cc676ecbb23ca28f2200575271be80e7b83faee 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/proc_fs.h>
 #include <linux/clk.h>
 #include <linux/irq.h>
+#include <linux/gpio.h>
 
 #include <asm/byteorder.h>
 #include <mach/hardware.h>
@@ -278,7 +279,7 @@ static void pxa_init_debugfs(struct pxa_udc *udc)
                goto err_queues;
        eps = debugfs_create_file("epstate", 0400, root, udc,
                        &eps_dbg_fops);
-       if (!queues)
+       if (!eps)
                goto err_eps;
 
        udc->debugfs_root = root;
@@ -747,13 +748,13 @@ static void req_done(struct pxa_ep *ep, struct pxa27x_request *req, int status)
 }
 
 /**
- * ep_end_out_req - Ends control endpoint in request
+ * ep_end_out_req - Ends endpoint OUT request
  * @ep: physical endpoint
  * @req: pxa request
  *
  * Context: ep->lock held
  *
- * Ends endpoint in request (completes usb request).
+ * Ends endpoint OUT request (completes usb request).
  */
 static void ep_end_out_req(struct pxa_ep *ep, struct pxa27x_request *req)
 {
@@ -762,13 +763,13 @@ static void ep_end_out_req(struct pxa_ep *ep, struct pxa27x_request *req)
 }
 
 /**
- * ep0_end_out_req - Ends control endpoint in request (ends data stage)
+ * ep0_end_out_req - Ends control endpoint OUT request (ends data stage)
  * @ep: physical endpoint
  * @req: pxa request
  *
  * Context: ep->lock held
  *
- * Ends control endpoint in request (completes usb request), and puts
+ * Ends control endpoint OUT request (completes usb request), and puts
  * control endpoint into idle state
  */
 static void ep0_end_out_req(struct pxa_ep *ep, struct pxa27x_request *req)
@@ -779,13 +780,13 @@ static void ep0_end_out_req(struct pxa_ep *ep, struct pxa27x_request *req)
 }
 
 /**
- * ep_end_in_req - Ends endpoint out request
+ * ep_end_in_req - Ends endpoint IN request
  * @ep: physical endpoint
  * @req: pxa request
  *
  * Context: ep->lock held
  *
- * Ends endpoint out request (completes usb request).
+ * Ends endpoint IN request (completes usb request).
  */
 static void ep_end_in_req(struct pxa_ep *ep, struct pxa27x_request *req)
 {
@@ -794,20 +795,18 @@ static void ep_end_in_req(struct pxa_ep *ep, struct pxa27x_request *req)
 }
 
 /**
- * ep0_end_in_req - Ends control endpoint out request (ends data stage)
+ * ep0_end_in_req - Ends control endpoint IN request (ends data stage)
  * @ep: physical endpoint
  * @req: pxa request
  *
  * Context: ep->lock held
  *
- * Ends control endpoint out request (completes usb request), and puts
+ * Ends control endpoint IN request (completes usb request), and puts
  * control endpoint into status state
  */
 static void ep0_end_in_req(struct pxa_ep *ep, struct pxa27x_request *req)
 {
-       struct pxa_udc *udc = ep->dev;
-
-       set_ep0state(udc, IN_STATUS_STAGE);
+       set_ep0state(ep->dev, IN_STATUS_STAGE);
        ep_end_in_req(ep, req);
 }
 
@@ -1167,7 +1166,7 @@ static int pxa_ep_queue(struct usb_ep *_ep, struct usb_request *_req,
                                ep_end_in_req(ep, req);
                        } else {
                                ep_err(ep, "got a request of %d bytes while"
-                                       "in state WATI_ACK_SET_CONF_INTERF\n",
+                                       "in state WAIT_ACK_SET_CONF_INTERF\n",
                                        length);
                                ep_del_request(ep, req);
                                rc = -EL2HLT;
@@ -1213,30 +1212,26 @@ static int pxa_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req)
        struct udc_usb_ep       *udc_usb_ep;
        struct pxa27x_request   *req;
        unsigned long           flags;
-       int                     rc;
+       int                     rc = -EINVAL;
 
        if (!_ep)
-               return -EINVAL;
+               return rc;
        udc_usb_ep = container_of(_ep, struct udc_usb_ep, usb_ep);
        ep = udc_usb_ep->pxa_ep;
        if (!ep || is_ep0(ep))
-               return -EINVAL;
+               return rc;
 
        spin_lock_irqsave(&ep->lock, flags);
 
        /* make sure it's actually queued on this endpoint */
        list_for_each_entry(req, &ep->queue, queue) {
-               if (&req->req == _req)
+               if (&req->req == _req) {
+                       req_done(ep, req, -ECONNRESET);
+                       rc = 0;
                        break;
+               }
        }
 
-       rc = -EINVAL;
-       if (&req->req != _req)
-               goto out;
-
-       rc = 0;
-       req_done(ep, req, -ECONNRESET);
-out:
        spin_unlock_irqrestore(&ep->lock, flags);
        return rc;
 }
@@ -1471,6 +1466,32 @@ static struct usb_ep_ops pxa_ep_ops = {
        .fifo_flush     = pxa_ep_fifo_flush,
 };
 
+/**
+ * dplus_pullup - Connect or disconnect pullup resistor to D+ pin
+ * @udc: udc device
+ * @on: 0 if disconnect pullup resistor, 1 otherwise
+ * Context: any
+ *
+ * Handle D+ pullup resistor, make the device visible to the usb bus, and
+ * declare it as a full speed usb device
+ */
+static void dplus_pullup(struct pxa_udc *udc, int on)
+{
+       if (on) {
+               if (gpio_is_valid(udc->mach->gpio_pullup))
+                       gpio_set_value(udc->mach->gpio_pullup,
+                                      !udc->mach->gpio_pullup_inverted);
+               if (udc->mach->udc_command)
+                       udc->mach->udc_command(PXA2XX_UDC_CMD_CONNECT);
+       } else {
+               if (gpio_is_valid(udc->mach->gpio_pullup))
+                       gpio_set_value(udc->mach->gpio_pullup,
+                                      udc->mach->gpio_pullup_inverted);
+               if (udc->mach->udc_command)
+                       udc->mach->udc_command(PXA2XX_UDC_CMD_DISCONNECT);
+       }
+       udc->pullup_on = on;
+}
 
 /**
  * pxa_udc_get_frame - Returns usb frame number
@@ -1500,21 +1521,145 @@ static int pxa_udc_wakeup(struct usb_gadget *_gadget)
        return 0;
 }
 
+static void udc_enable(struct pxa_udc *udc);
+static void udc_disable(struct pxa_udc *udc);
+
+/**
+ * should_enable_udc - Tells if UDC should be enabled
+ * @udc: udc device
+ * Context: any
+ *
+ * The UDC should be enabled if :
+
+ *  - the pullup resistor is connected
+ *  - and a gadget driver is bound
+ *  - and vbus is sensed (or no vbus sense is available)
+ *
+ * Returns 1 if UDC should be enabled, 0 otherwise
+ */
+static int should_enable_udc(struct pxa_udc *udc)
+{
+       int put_on;
+
+       put_on = ((udc->pullup_on) && (udc->driver));
+       put_on &= ((udc->vbus_sensed) || (!udc->transceiver));
+       return put_on;
+}
+
+/**
+ * should_disable_udc - Tells if UDC should be disabled
+ * @udc: udc device
+ * Context: any
+ *
+ * The UDC should be disabled if :
+ *  - the pullup resistor is not connected
+ *  - or no gadget driver is bound
+ *  - or no vbus is sensed (when vbus sesing is available)
+ *
+ * Returns 1 if UDC should be disabled
+ */
+static int should_disable_udc(struct pxa_udc *udc)
+{
+       int put_off;
+
+       put_off = ((!udc->pullup_on) || (!udc->driver));
+       put_off |= ((!udc->vbus_sensed) && (udc->transceiver));
+       return put_off;
+}
+
+/**
+ * pxa_udc_pullup - Offer manual D+ pullup control
+ * @_gadget: usb gadget using the control
+ * @is_active: 0 if disconnect, else connect D+ pullup resistor
+ * Context: !in_interrupt()
+ *
+ * Returns 0 if OK, -EOPNOTSUPP if udc driver doesn't handle D+ pullup
+ */
+static int pxa_udc_pullup(struct usb_gadget *_gadget, int is_active)
+{
+       struct pxa_udc *udc = to_gadget_udc(_gadget);
+
+       if (!gpio_is_valid(udc->mach->gpio_pullup) && !udc->mach->udc_command)
+               return -EOPNOTSUPP;
+
+       dplus_pullup(udc, is_active);
+
+       if (should_enable_udc(udc))
+               udc_enable(udc);
+       if (should_disable_udc(udc))
+               udc_disable(udc);
+       return 0;
+}
+
+static void udc_enable(struct pxa_udc *udc);
+static void udc_disable(struct pxa_udc *udc);
+
+/**
+ * pxa_udc_vbus_session - Called by external transceiver to enable/disable udc
+ * @_gadget: usb gadget
+ * @is_active: 0 if should disable the udc, 1 if should enable
+ *
+ * Enables the udc, and optionnaly activates D+ pullup resistor. Or disables the
+ * udc, and deactivates D+ pullup resistor.
+ *
+ * Returns 0
+ */
+static int pxa_udc_vbus_session(struct usb_gadget *_gadget, int is_active)
+{
+       struct pxa_udc *udc = to_gadget_udc(_gadget);
+
+       udc->vbus_sensed = is_active;
+       if (should_enable_udc(udc))
+               udc_enable(udc);
+       if (should_disable_udc(udc))
+               udc_disable(udc);
+
+       return 0;
+}
+
+/**
+ * pxa_udc_vbus_draw - Called by gadget driver after SET_CONFIGURATION completed
+ * @_gadget: usb gadget
+ * @mA: current drawn
+ *
+ * Context: !in_interrupt()
+ *
+ * Called after a configuration was chosen by a USB host, to inform how much
+ * current can be drawn by the device from VBus line.
+ *
+ * Returns 0 or -EOPNOTSUPP if no transceiver is handling the udc
+ */
+static int pxa_udc_vbus_draw(struct usb_gadget *_gadget, unsigned mA)
+{
+       struct pxa_udc *udc;
+
+       udc = to_gadget_udc(_gadget);
+       if (udc->transceiver)
+               return otg_set_power(udc->transceiver, mA);
+       return -EOPNOTSUPP;
+}
+
 static const struct usb_gadget_ops pxa_udc_ops = {
        .get_frame      = pxa_udc_get_frame,
        .wakeup         = pxa_udc_wakeup,
-       /* current versions must always be self-powered */
+       .pullup         = pxa_udc_pullup,
+       .vbus_session   = pxa_udc_vbus_session,
+       .vbus_draw      = pxa_udc_vbus_draw,
 };
 
 /**
  * udc_disable - disable udc device controller
  * @udc: udc device
+ * Context: any
  *
  * Disables the udc device : disables clocks, udc interrupts, control endpoint
  * interrupts.
  */
 static void udc_disable(struct pxa_udc *udc)
 {
+       if (!udc->enabled)
+               return;
+
        udc_writel(udc, UDCICR0, 0);
        udc_writel(udc, UDCICR1, 0);
 
@@ -1523,8 +1668,8 @@ static void udc_disable(struct pxa_udc *udc)
 
        ep0_idle(udc);
        udc->gadget.speed = USB_SPEED_UNKNOWN;
-       if (udc->mach->udc_command)
-               udc->mach->udc_command(PXA2XX_UDC_CMD_DISCONNECT);
+
+       udc->enabled = 0;
 }
 
 /**
@@ -1555,10 +1700,9 @@ static __init void udc_init_data(struct pxa_udc *dev)
        }
 
        /* USB endpoints init */
-       for (i = 0; i < NR_USB_ENDPOINTS; i++)
-               if (i != 0)
-                       list_add_tail(&dev->udc_usb_ep[i].usb_ep.ep_list,
-                                       &dev->gadget.ep_list);
+       for (i = 1; i < NR_USB_ENDPOINTS; i++)
+               list_add_tail(&dev->udc_usb_ep[i].usb_ep.ep_list,
+                               &dev->gadget.ep_list);
 }
 
 /**
@@ -1570,6 +1714,9 @@ static __init void udc_init_data(struct pxa_udc *dev)
  */
 static void udc_enable(struct pxa_udc *udc)
 {
+       if (udc->enabled)
+               return;
+
        udc_writel(udc, UDCICR0, 0);
        udc_writel(udc, UDCICR1, 0);
        udc_clear_mask_UDCCR(udc, UDCCR_UDE);
@@ -1598,9 +1745,7 @@ static void udc_enable(struct pxa_udc *udc)
        /* enable ep0 irqs */
        pio_irq_enable(&udc->pxa_ep[0]);
 
-       dev_info(udc->dev, "UDC connecting\n");
-       if (udc->mach->udc_command)
-               udc->mach->udc_command(PXA2XX_UDC_CMD_CONNECT);
+       udc->enabled = 1;
 }
 
 /**
@@ -1612,6 +1757,9 @@ static void udc_enable(struct pxa_udc *udc)
  * usb traffic follows until a disconnect is reported.  Then a host may connect
  * again, or the driver might get unbound.
  *
+ * Note that the udc is not automatically enabled. Check function
+ * should_enable_udc().
+ *
  * Returns 0 if no error, -EINVAL, -ENODEV, -EBUSY otherwise
  */
 int usb_gadget_register_driver(struct usb_gadget_driver *driver)
@@ -1630,6 +1778,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
        /* first hook up the driver ... */
        udc->driver = driver;
        udc->gadget.dev.driver = &driver->driver;
+       dplus_pullup(udc, 1);
 
        retval = device_add(&udc->gadget.dev);
        if (retval) {
@@ -1645,9 +1794,21 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
        dev_dbg(udc->dev, "registered gadget driver '%s'\n",
                driver->driver.name);
 
-       udc_enable(udc);
+       if (udc->transceiver) {
+               retval = otg_set_peripheral(udc->transceiver, &udc->gadget);
+               if (retval) {
+                       dev_err(udc->dev, "can't bind to transceiver\n");
+                       goto transceiver_fail;
+               }
+       }
+
+       if (should_enable_udc(udc))
+               udc_enable(udc);
        return 0;
 
+transceiver_fail:
+       if (driver->unbind)
+               driver->unbind(&udc->gadget);
 bind_fail:
        device_del(&udc->gadget.dev);
 add_fail:
@@ -1699,14 +1860,17 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
 
        stop_activity(udc, driver);
        udc_disable(udc);
+       dplus_pullup(udc, 0);
 
        driver->unbind(&udc->gadget);
        udc->driver = NULL;
 
        device_del(&udc->gadget.dev);
-
        dev_info(udc->dev, "unregistered gadget driver '%s'\n",
                 driver->driver.name);
+
+       if (udc->transceiver)
+               return otg_set_peripheral(udc->transceiver, NULL);
        return 0;
 }
 EXPORT_SYMBOL(usb_gadget_unregister_driver);
@@ -1823,14 +1987,14 @@ static void handle_ep0(struct pxa_udc *udc, int fifo_irq, int opc_irq)
        struct pxa27x_request   *req = NULL;
        int                     completed = 0;
 
+       if (!list_empty(&ep->queue))
+               req = list_entry(ep->queue.next, struct pxa27x_request, queue);
+
        udccsr0 = udc_ep_readl(ep, UDCCSR);
        ep_dbg(ep, "state=%s, req=%p, udccsr0=0x%03x, udcbcr=%d, irq_msk=%x\n",
                EP0_STNAME(udc), req, udccsr0, udc_ep_readl(ep, UDCBCR),
                (fifo_irq << 1 | opc_irq));
 
-       if (!list_empty(&ep->queue))
-               req = list_entry(ep->queue.next, struct pxa27x_request, queue);
-
        if (udccsr0 & UDCCSR0_SST) {
                ep_dbg(ep, "clearing stall status\n");
                nuke(ep, -EPIPE);
@@ -2212,7 +2376,7 @@ static int __init pxa_udc_probe(struct platform_device *pdev)
 {
        struct resource *regs;
        struct pxa_udc *udc = &memory;
-       int retval;
+       int retval = 0, gpio;
 
        regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        if (!regs)
@@ -2223,6 +2387,20 @@ static int __init pxa_udc_probe(struct platform_device *pdev)
 
        udc->dev = &pdev->dev;
        udc->mach = pdev->dev.platform_data;
+       udc->transceiver = otg_get_transceiver();
+
+       gpio = udc->mach->gpio_pullup;
+       if (gpio_is_valid(gpio)) {
+               retval = gpio_request(gpio, "USB D+ pullup");
+               if (retval == 0)
+                       gpio_direction_output(gpio,
+                                      udc->mach->gpio_pullup_inverted);
+       }
+       if (retval) {
+               dev_err(&pdev->dev, "Couldn't request gpio %d : %d\n",
+                       gpio, retval);
+               return retval;
+       }
 
        udc->clk = clk_get(&pdev->dev, NULL);
        if (IS_ERR(udc->clk)) {
@@ -2240,6 +2418,7 @@ static int __init pxa_udc_probe(struct platform_device *pdev)
        device_initialize(&udc->gadget.dev);
        udc->gadget.dev.parent = &pdev->dev;
        udc->gadget.dev.dma_mask = NULL;
+       udc->vbus_sensed = 0;
 
        the_controller = udc;
        platform_set_drvdata(pdev, udc);
@@ -2273,14 +2452,21 @@ err_clk:
 static int __exit pxa_udc_remove(struct platform_device *_dev)
 {
        struct pxa_udc *udc = platform_get_drvdata(_dev);
+       int gpio = udc->mach->gpio_pullup;
 
        usb_gadget_unregister_driver(udc->driver);
        free_irq(udc->irq, udc);
        pxa_cleanup_debugfs(udc);
+       if (gpio_is_valid(gpio))
+               gpio_free(gpio);
+
+       otg_put_transceiver(udc->transceiver);
 
+       udc->transceiver = NULL;
        platform_set_drvdata(_dev, NULL);
        the_controller = NULL;
        clk_put(udc->clk);
+       iounmap(udc->regs);
 
        return 0;
 }
@@ -2319,6 +2505,8 @@ static int pxa_udc_suspend(struct platform_device *_dev, pm_message_t state)
        }
 
        udc_disable(udc);
+       udc->pullup_resume = udc->pullup_on;
+       dplus_pullup(udc, 0);
 
        return 0;
 }
@@ -2346,7 +2534,9 @@ static int pxa_udc_resume(struct platform_device *_dev)
                                ep->udccsr_value, ep->udccr_value);
        }
 
-       udc_enable(udc);
+       dplus_pullup(udc, udc->pullup_resume);
+       if (should_enable_udc(udc))
+               udc_enable(udc);
        /*
         * We do not handle OTG yet.
         *
index 1d1b7936ee113fdb7a9ee7628fe104dff268fb7d..db58125331dad5d3788d5b3774a34f1637c893df 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/types.h>
 #include <linux/spinlock.h>
 #include <linux/io.h>
+#include <linux/usb/otg.h>
 
 /*
  * Register definitions
@@ -421,10 +422,14 @@ struct udc_stats {
  * @driver: bound gadget (zero, g_ether, g_file_storage, ...)
  * @dev: device
  * @mach: machine info, used to activate specific GPIO
+ * @transceiver: external transceiver to handle vbus sense and D+ pullup
  * @ep0state: control endpoint state machine state
  * @stats: statistics on udc usage
  * @udc_usb_ep: array of usb endpoints offered by the gadget
  * @pxa_ep: array of pxa available endpoints
+ * @enabled: UDC was enabled by a previous udc_enable()
+ * @pullup_on: if pullup resistor connected to D+ pin
+ * @pullup_resume: if pullup resistor should be connected to D+ pin on resume
  * @config: UDC active configuration
  * @last_interface: UDC interface of the last SET_INTERFACE host request
  * @last_alternate: UDC altsetting of the last SET_INTERFACE host request
@@ -443,6 +448,7 @@ struct pxa_udc {
        struct usb_gadget_driver                *driver;
        struct device                           *dev;
        struct pxa2xx_udc_mach_info             *mach;
+       struct otg_transceiver                  *transceiver;
 
        enum ep0_state                          ep0state;
        struct udc_stats                        stats;
@@ -450,6 +456,10 @@ struct pxa_udc {
        struct udc_usb_ep                       udc_usb_ep[NR_USB_ENDPOINTS];
        struct pxa_ep                           pxa_ep[NR_PXA_ENDPOINTS];
 
+       unsigned                                enabled:1;
+       unsigned                                pullup_on:1;
+       unsigned                                pullup_resume:1;
+       unsigned                                vbus_sensed:1;
        unsigned                                config:2;
        unsigned                                last_interface:3;
        unsigned                                last_alternate:3;
index 37879af1c4334c12090c0f544d1ae472f0c88540..f46a60962dab72bd03fa83b9a79325369040c8bc 100644 (file)
@@ -87,12 +87,12 @@ static struct usb_gadget_strings *dev_strings[] = {
 static struct usb_device_descriptor device_desc = {
        .bLength =              USB_DT_DEVICE_SIZE,
        .bDescriptorType =      USB_DT_DEVICE,
-       .bcdUSB =               __constant_cpu_to_le16(0x0200),
+       .bcdUSB =               cpu_to_le16(0x0200),
        /* .bDeviceClass = f(use_acm) */
        .bDeviceSubClass =      0,
        .bDeviceProtocol =      0,
        /* .bMaxPacketSize0 = f(hardware) */
-       .idVendor =             __constant_cpu_to_le16(GS_VENDOR_ID),
+       .idVendor =             cpu_to_le16(GS_VENDOR_ID),
        /* .idProduct = f(use_acm) */
        /* .bcdDevice = f(hardware) */
        /* .iManufacturer = DYNAMIC */
@@ -216,7 +216,7 @@ static int __init gs_bind(struct usb_composite_dev *cdev)
                pr_warning("gs_bind: controller '%s' not recognized\n",
                        gadget->name);
                device_desc.bcdDevice =
-                       __constant_cpu_to_le16(GS_VERSION_NUM | 0x0099);
+                       cpu_to_le16(GS_VERSION_NUM | 0x0099);
        }
 
        if (gadget_is_otg(cdev->gadget)) {
@@ -255,19 +255,19 @@ static int __init init(void)
                serial_config_driver.bConfigurationValue = 2;
                device_desc.bDeviceClass = USB_CLASS_COMM;
                device_desc.idProduct =
-                               __constant_cpu_to_le16(GS_CDC_PRODUCT_ID);
+                               cpu_to_le16(GS_CDC_PRODUCT_ID);
        } else if (use_obex) {
                serial_config_driver.label = "CDC OBEX config";
                serial_config_driver.bConfigurationValue = 3;
                device_desc.bDeviceClass = USB_CLASS_COMM;
                device_desc.idProduct =
-                       __constant_cpu_to_le16(GS_CDC_OBEX_PRODUCT_ID);
+                       cpu_to_le16(GS_CDC_OBEX_PRODUCT_ID);
        } else {
                serial_config_driver.label = "Generic Serial config";
                serial_config_driver.bConfigurationValue = 1;
                device_desc.bDeviceClass = USB_CLASS_VENDOR_SPEC;
                device_desc.idProduct =
-                               __constant_cpu_to_le16(GS_PRODUCT_ID);
+                               cpu_to_le16(GS_PRODUCT_ID);
        }
        strings_dev[STRING_DESCRIPTION_IDX].s = serial_config_driver.label;
 
index 53d59287f2bc8fcd0599e3bd597d2bcd26280ece..0a4d99ab40d8c0c224a78d060e93574b63fcbd2e 100644 (file)
@@ -1092,7 +1092,7 @@ int __init gserial_setup(struct usb_gadget *g, unsigned count)
        gs_tty_driver->init_termios.c_ispeed = 9600;
        gs_tty_driver->init_termios.c_ospeed = 9600;
 
-       coding.dwDTERate = __constant_cpu_to_le32(9600);
+       coding.dwDTERate = cpu_to_le32(9600);
        coding.bCharFormat = 8;
        coding.bParityType = USB_CDC_NO_PARITY;
        coding.bDataBits = USB_CDC_1_STOP_BITS;
index 361d9659ac48726aa583d69accd2196edc3bd9df..2d772401b7ad4879762d118e8ff12231d103a912 100644 (file)
@@ -102,22 +102,32 @@ module_param(loopdefault, bool, S_IRUGO|S_IWUSR);
 #ifndef        CONFIG_USB_ZERO_HNPTEST
 #define DRIVER_VENDOR_NUM      0x0525          /* NetChip */
 #define DRIVER_PRODUCT_NUM     0xa4a0          /* Linux-USB "Gadget Zero" */
+#define DEFAULT_AUTORESUME     0
 #else
 #define DRIVER_VENDOR_NUM      0x1a0a          /* OTG test device IDs */
 #define DRIVER_PRODUCT_NUM     0xbadd
+#define DEFAULT_AUTORESUME     5
 #endif
 
+/* If the optional "autoresume" mode is enabled, it provides good
+ * functional coverage for the "USBCV" test harness from USB-IF.
+ * It's always set if OTG mode is enabled.
+ */
+unsigned autoresume = DEFAULT_AUTORESUME;
+module_param(autoresume, uint, S_IRUGO);
+MODULE_PARM_DESC(autoresume, "zero, or seconds before remote wakeup");
+
 /*-------------------------------------------------------------------------*/
 
 static struct usb_device_descriptor device_desc = {
        .bLength =              sizeof device_desc,
        .bDescriptorType =      USB_DT_DEVICE,
 
-       .bcdUSB =               __constant_cpu_to_le16(0x0200),
+       .bcdUSB =               cpu_to_le16(0x0200),
        .bDeviceClass =         USB_CLASS_VENDOR_SPEC,
 
-       .idVendor =             __constant_cpu_to_le16(DRIVER_VENDOR_NUM),
-       .idProduct =            __constant_cpu_to_le16(DRIVER_PRODUCT_NUM),
+       .idVendor =             cpu_to_le16(DRIVER_VENDOR_NUM),
+       .idProduct =            cpu_to_le16(DRIVER_PRODUCT_NUM),
        .bNumConfigurations =   2,
 };
 
@@ -212,6 +222,47 @@ void disable_endpoints(struct usb_composite_dev *cdev,
 
 /*-------------------------------------------------------------------------*/
 
+static struct timer_list       autoresume_timer;
+
+static void zero_autoresume(unsigned long _c)
+{
+       struct usb_composite_dev        *cdev = (void *)_c;
+       struct usb_gadget               *g = cdev->gadget;
+
+       /* unconfigured devices can't issue wakeups */
+       if (!cdev->config)
+               return;
+
+       /* Normally the host would be woken up for something
+        * more significant than just a timer firing; likely
+        * because of some direct user request.
+        */
+       if (g->speed != USB_SPEED_UNKNOWN) {
+               int status = usb_gadget_wakeup(g);
+               INFO(cdev, "%s --> %d\n", __func__, status);
+       }
+}
+
+static void zero_suspend(struct usb_composite_dev *cdev)
+{
+       if (cdev->gadget->speed == USB_SPEED_UNKNOWN)
+               return;
+
+       if (autoresume) {
+               mod_timer(&autoresume_timer, jiffies + (HZ * autoresume));
+               DBG(cdev, "suspend, wakeup in %d seconds\n", autoresume);
+       } else
+               DBG(cdev, "%s\n", __func__);
+}
+
+static void zero_resume(struct usb_composite_dev *cdev)
+{
+       DBG(cdev, "%s\n", __func__);
+       del_timer(&autoresume_timer);
+}
+
+/*-------------------------------------------------------------------------*/
+
 static int __init zero_bind(struct usb_composite_dev *cdev)
 {
        int                     gcnum;
@@ -239,17 +290,19 @@ static int __init zero_bind(struct usb_composite_dev *cdev)
        strings_dev[STRING_SERIAL_IDX].id = id;
        device_desc.iSerialNumber = id;
 
+       setup_timer(&autoresume_timer, zero_autoresume, (unsigned long) cdev);
+
        /* Register primary, then secondary configuration.  Note that
         * SH3 only allows one config...
         */
        if (loopdefault) {
-               loopback_add(cdev);
+               loopback_add(cdev, autoresume != 0);
                if (!gadget_is_sh(gadget))
-                       sourcesink_add(cdev);
+                       sourcesink_add(cdev, autoresume != 0);
        } else {
-               sourcesink_add(cdev);
+               sourcesink_add(cdev, autoresume != 0);
                if (!gadget_is_sh(gadget))
-                       loopback_add(cdev);
+                       loopback_add(cdev, autoresume != 0);
        }
 
        gcnum = usb_gadget_controller_number(gadget);
@@ -265,7 +318,7 @@ static int __init zero_bind(struct usb_composite_dev *cdev)
                 */
                pr_warning("%s: controller '%s' not recognized\n",
                        longname, gadget->name);
-               device_desc.bcdDevice = __constant_cpu_to_le16(0x9999);
+               device_desc.bcdDevice = cpu_to_le16(0x9999);
        }
 
 
@@ -278,11 +331,20 @@ static int __init zero_bind(struct usb_composite_dev *cdev)
        return 0;
 }
 
+static int zero_unbind(struct usb_composite_dev *cdev)
+{
+       del_timer_sync(&autoresume_timer);
+       return 0;
+}
+
 static struct usb_composite_driver zero_driver = {
        .name           = "zero",
        .dev            = &device_desc,
        .strings        = dev_strings,
        .bind           = zero_bind,
+       .unbind         = zero_unbind,
+       .suspend        = zero_suspend,
+       .resume         = zero_resume,
 };
 
 MODULE_AUTHOR("David Brownell");
index 2c63bfb1f8d94e8a5e6c6db5a0fd45fcaa508aa7..845479f7c70773cacff061d3a04c0f3ca0b21d86 100644 (file)
@@ -24,10 +24,7 @@ config USB_EHCI_HCD
          The Enhanced Host Controller Interface (EHCI) is standard for USB 2.0
          "high speed" (480 Mbit/sec, 60 Mbyte/sec) host controller hardware.
          If your USB host controller supports USB 2.0, you will likely want to
-         configure this Host Controller Driver.  At the time of this writing, 
-         the primary implementation of EHCI is a chip from NEC, widely available
-         in add-on PCI cards, but implementations are in the works from other 
-         vendors including Intel and Philips.  Motherboard support is appearing.
+         configure this Host Controller Driver.
 
          EHCI controllers are packaged with "companion" host controllers (OHCI
          or UHCI) to handle USB 1.1 devices connected to root hub ports.  Ports
@@ -123,7 +120,7 @@ config USB_ISP116X_HCD
 
 config USB_ISP1760_HCD
        tristate "ISP 1760 HCD support"
-       depends on USB && EXPERIMENTAL && (PCI || PPC_OF)
+       depends on USB && EXPERIMENTAL
        ---help---
          The ISP1760 chip is a USB 2.0 host controller.
 
index e551bb38852be35eefeb532a23c260ecff6109ff..f2618d17710d248938632cee6278a2a3bb690a8b 100644 (file)
@@ -110,6 +110,42 @@ MODULE_PARM_DESC (ignore_oc, "ignore bogus hardware overcurrent indications");
 
 /*-------------------------------------------------------------------------*/
 
+static void
+timer_action(struct ehci_hcd *ehci, enum ehci_timer_action action)
+{
+       /* Don't override timeouts which shrink or (later) disable
+        * the async ring; just the I/O watchdog.  Note that if a
+        * SHRINK were pending, OFF would never be requested.
+        */
+       if (timer_pending(&ehci->watchdog)
+                       && ((BIT(TIMER_ASYNC_SHRINK) | BIT(TIMER_ASYNC_OFF))
+                               & ehci->actions))
+               return;
+
+       if (!test_and_set_bit(action, &ehci->actions)) {
+               unsigned long t;
+
+               switch (action) {
+               case TIMER_IO_WATCHDOG:
+                       t = EHCI_IO_JIFFIES;
+                       break;
+               case TIMER_ASYNC_OFF:
+                       t = EHCI_ASYNC_JIFFIES;
+                       break;
+               /* case TIMER_ASYNC_SHRINK: */
+               default:
+                       /* add a jiffie since we synch against the
+                        * 8 KHz uframe counter.
+                        */
+                       t = DIV_ROUND_UP(EHCI_SHRINK_FRAMES * HZ, 1000) + 1;
+                       break;
+               }
+               mod_timer(&ehci->watchdog, t + jiffies);
+       }
+}
+
+/*-------------------------------------------------------------------------*/
+
 /*
  * handshake - spin reading hc until handshake completes or fails
  * @ptr: address of hc register to be read
index ecc9b66c03cd38323377c6f3f6b27275d02d58e5..1976b1b3778cd3de2d7946733fbda37edb6a7108 100644 (file)
@@ -333,12 +333,40 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh)
                token = hc32_to_cpu(ehci, qtd->hw_token);
 
                /* always clean up qtds the hc de-activated */
+ retry_xacterr:
                if ((token & QTD_STS_ACTIVE) == 0) {
 
                        /* on STALL, error, and short reads this urb must
                         * complete and all its qtds must be recycled.
                         */
                        if ((token & QTD_STS_HALT) != 0) {
+
+                               /* retry transaction errors until we
+                                * reach the software xacterr limit
+                                */
+                               if ((token & QTD_STS_XACT) &&
+                                               QTD_CERR(token) == 0 &&
+                                               --qh->xacterrs > 0 &&
+                                               !urb->unlinked) {
+                                       ehci_dbg(ehci,
+       "detected XactErr len %zu/%zu retry %d\n",
+       qtd->length - QTD_LENGTH(token), qtd->length,
+       QH_XACTERR_MAX - qh->xacterrs);
+
+                                       /* reset the token in the qtd and the
+                                        * qh overlay (which still contains
+                                        * the qtd) so that we pick up from
+                                        * where we left off
+                                        */
+                                       token &= ~QTD_STS_HALT;
+                                       token |= QTD_STS_ACTIVE |
+                                                       (EHCI_TUNE_CERR << 10);
+                                       qtd->hw_token = cpu_to_hc32(ehci,
+                                                       token);
+                                       wmb();
+                                       qh->hw_token = cpu_to_hc32(ehci, token);
+                                       goto retry_xacterr;
+                               }
                                stopped = 1;
 
                        /* magic dummy for some short reads; qh won't advance.
@@ -421,6 +449,9 @@ halt:
                /* remove qtd; it's recycled after possible urb completion */
                list_del (&qtd->qtd_list);
                last = qtd;
+
+               /* reinit the xacterr counter for the next qtd */
+               qh->xacterrs = QH_XACTERR_MAX;
        }
 
        /* last urb's completion might still need calling */
@@ -862,6 +893,7 @@ static void qh_link_async (struct ehci_hcd *ehci, struct ehci_qh *qh)
        head->qh_next.qh = qh;
        head->hw_next = dma;
 
+       qh->xacterrs = QH_XACTERR_MAX;
        qh->qh_state = QH_STATE_LINKED;
        /* qtd completions reported later by interrupt */
 }
index 1d0b49e3f1928e230703d76cca04225ae1ba6213..ada5d2ba297be1353bf60a8f1c5dc3d5199078df 100644 (file)
@@ -563,7 +563,7 @@ static int qh_unlink_periodic(struct ehci_hcd *ehci, struct ehci_qh *qh)
        //   and this qh is active in the current uframe
        //   (and overlay token SplitXstate is false?)
        // THEN
-       //   qh->hw_info1 |= __constant_cpu_to_hc32(1 << 7 /* "ignore" */);
+       //   qh->hw_info1 |= cpu_to_hc32(1 << 7 /* "ignore" */);
 
        /* high bandwidth, or otherwise part of every microframe */
        if ((period = qh->period) == 0)
index 262b00c9b334286583d8fb84d394bac07a86a304..6cff195e1a365e46d739bc42263b57381365bb3b 100644 (file)
@@ -190,40 +190,6 @@ timer_action_done (struct ehci_hcd *ehci, enum ehci_timer_action action)
        clear_bit (action, &ehci->actions);
 }
 
-static inline void
-timer_action (struct ehci_hcd *ehci, enum ehci_timer_action action)
-{
-       /* Don't override timeouts which shrink or (later) disable
-        * the async ring; just the I/O watchdog.  Note that if a
-        * SHRINK were pending, OFF would never be requested.
-        */
-       if (timer_pending(&ehci->watchdog)
-                       && ((BIT(TIMER_ASYNC_SHRINK) | BIT(TIMER_ASYNC_OFF))
-                               & ehci->actions))
-               return;
-
-       if (!test_and_set_bit (action, &ehci->actions)) {
-               unsigned long t;
-
-               switch (action) {
-               case TIMER_IO_WATCHDOG:
-                       t = EHCI_IO_JIFFIES;
-                       break;
-               case TIMER_ASYNC_OFF:
-                       t = EHCI_ASYNC_JIFFIES;
-                       break;
-               // case TIMER_ASYNC_SHRINK:
-               default:
-                       /* add a jiffie since we synch against the
-                        * 8 KHz uframe counter.
-                        */
-                       t = DIV_ROUND_UP(EHCI_SHRINK_FRAMES * HZ, 1000) + 1;
-                       break;
-               }
-               mod_timer(&ehci->watchdog, t + jiffies);
-       }
-}
-
 static void free_cached_itd_list(struct ehci_hcd *ehci);
 
 /*-------------------------------------------------------------------------*/
@@ -287,7 +253,7 @@ struct ehci_qtd {
 
 /*
  * Now the following defines are not converted using the
- * __constant_cpu_to_le32() macro anymore, since we have to support
+ * cpu_to_le32() macro anymore, since we have to support
  * "dynamic" switching between be and le support, so that the driver
  * can be used on one system with SoC EHCI controller using big-endian
  * descriptors as well as a normal little-endian PCI EHCI controller.
@@ -376,6 +342,9 @@ struct ehci_qh {
 #define        QH_STATE_UNLINK_WAIT    4               /* LINKED and on reclaim q */
 #define        QH_STATE_COMPLETING     5               /* don't touch token.HALT */
 
+       u8                      xacterrs;       /* XactErr retry counter */
+#define        QH_XACTERR_MAX          32              /* XactErr retry limit */
+
        /* periodic schedule info */
        u8                      usecs;          /* intr bandwidth */
        u8                      gap_uf;         /* uframes split/csplit gap */
index 8582236e4cad412d0c8fb507c5e278363da461ee..cbf30e515f29f2e7f7668f1143c8f09d02a45738 100644 (file)
@@ -464,8 +464,7 @@ static int __hwahc_dev_set_key(struct wusbhc *wusbhc, u8 port_idx, u32 tkid,
                        port_idx << 8 | iface_no,
                        keyd, keyd_len, 1000 /* FIXME: arbitrary */);
 
-       memset(keyd, 0, sizeof(*keyd)); /* clear keys etc. */
-       kfree(keyd);
+       kzfree(keyd); /* clear keys etc. */
        return result;
 }
 
index 4dda31b268929e4b74e7828d9d4af04764a475ee..a2b305477afef25b1a37c0e03a7cfeff42e6acf6 100644 (file)
@@ -772,7 +772,7 @@ static int isp116x_urb_enqueue(struct usb_hcd *hcd,
                break;
        case PIPE_INTERRUPT:
                urb->interval = ep->period;
-               ep->length = min((int)ep->maxpacket,
+               ep->length = min_t(u32, ep->maxpacket,
                                 urb->transfer_buffer_length);
 
                /* urb submitted for already existing endpoint */
index aa211bafcff9dacc41457d10894f9eb6e8c82812..12db961acdfbba78e6a11ae6764feb2fb9c89386 100644 (file)
@@ -563,7 +563,7 @@ static void urb_dbg(struct urb *urb, char *msg)
 */
 static inline void dump_ptd(struct ptd *ptd)
 {
-       printk("td: %x %d%c%d %d,%d,%d  %x %x%x%x\n",
+       printk(KERN_WARNING "td: %x %d%c%d %d,%d,%d  %x %x%x%x\n",
               PTD_GET_CC(ptd), PTD_GET_FA(ptd),
               PTD_DIR_STR(ptd), PTD_GET_EP(ptd),
               PTD_GET_COUNT(ptd), PTD_GET_LEN(ptd), PTD_GET_MPS(ptd),
@@ -576,7 +576,7 @@ static inline void dump_ptd_out_data(struct ptd *ptd, u8 * buf)
        int k;
 
        if (PTD_GET_DIR(ptd) != PTD_DIR_IN && PTD_GET_LEN(ptd)) {
-               printk("-> ");
+               printk(KERN_WARNING "-> ");
                for (k = 0; k < PTD_GET_LEN(ptd); ++k)
                        printk("%02x ", ((u8 *) buf)[k]);
                printk("\n");
@@ -588,13 +588,13 @@ static inline void dump_ptd_in_data(struct ptd *ptd, u8 * buf)
        int k;
 
        if (PTD_GET_DIR(ptd) == PTD_DIR_IN && PTD_GET_COUNT(ptd)) {
-               printk("<- ");
+               printk(KERN_WARNING "<- ");
                for (k = 0; k < PTD_GET_COUNT(ptd); ++k)
                        printk("%02x ", ((u8 *) buf)[k]);
                printk("\n");
        }
        if (PTD_GET_LAST(ptd))
-               printk("-\n");
+               printk(KERN_WARNING "-\n");
 }
 
 #else
index b899f1a59c262fd322b5b44caace1f8d6948b5ac..cd07ea3f0c6332444013aae444dcbf3e0bcdfc4a 100644 (file)
@@ -644,7 +644,7 @@ static void transform_add_int(struct isp1760_hcd *priv, struct isp1760_qh *qh,
 
        if (urb->dev->speed != USB_SPEED_HIGH) {
                /* split */
-               ptd->dw5 = __constant_cpu_to_le32(0x1c);
+               ptd->dw5 = cpu_to_le32(0x1c);
 
                if (qh->period >= 32)
                        period = qh->period / 2;
@@ -819,6 +819,13 @@ static void enqueue_an_ATL_packet(struct usb_hcd *hcd, struct isp1760_qh *qh,
        u32 atl_regs, payload;
        u32 buffstatus;
 
+       /*
+        * When this function is called from the interrupt handler to enqueue
+        * a follow-up packet, the SKIP register gets written and read back
+        * almost immediately. With ISP1761, this register requires a delay of
+        * 195ns between a write and subsequent read (see section 15.1.1.3).
+        */
+       ndelay(195);
        skip_map = isp1760_readl(hcd->regs + HC_ATL_PTD_SKIPMAP_REG);
 
        BUG_ON(!skip_map);
@@ -853,6 +860,13 @@ static void enqueue_an_INT_packet(struct usb_hcd *hcd, struct isp1760_qh *qh,
        u32 int_regs, payload;
        u32 buffstatus;
 
+       /*
+        * When this function is called from the interrupt handler to enqueue
+        * a follow-up packet, the SKIP register gets written and read back
+        * almost immediately. With ISP1761, this register requires a delay of
+        * 195ns between a write and subsequent read (see section 15.1.1.3).
+        */
+       ndelay(195);
        skip_map = isp1760_readl(hcd->regs + HC_INT_PTD_SKIPMAP_REG);
 
        BUG_ON(!skip_map);
@@ -1054,7 +1068,7 @@ static void do_atl_int(struct usb_hcd *usb_hcd)
                        priv_write_copy(priv, (u32 *)&ptd, usb_hcd->regs +
                                        atl_regs, sizeof(ptd));
 
-                       ptd.dw0 |= __constant_cpu_to_le32(PTD_VALID);
+                       ptd.dw0 |= cpu_to_le32(PTD_VALID);
                        priv_write_copy(priv, (u32 *)&ptd, usb_hcd->regs +
                                        atl_regs, sizeof(ptd));
 
@@ -2235,9 +2249,10 @@ void deinit_kmem_cache(void)
        kmem_cache_destroy(qh_cachep);
 }
 
-struct usb_hcd *isp1760_register(u64 res_start, u64 res_len, int irq,
-               u64 irqflags, struct device *dev, const char *busname,
-               unsigned int devflags)
+struct usb_hcd *isp1760_register(phys_addr_t res_start, resource_size_t res_len,
+                                int irq, unsigned long irqflags,
+                                struct device *dev, const char *busname,
+                                unsigned int devflags)
 {
        struct usb_hcd *hcd;
        struct isp1760_hcd *priv;
index a9daea5879627d7d3e27a2a1572f2b3b326fbc22..462f4943cb1b8d4d65cb3675a6bc9a2ae40d968c 100644 (file)
@@ -2,9 +2,10 @@
 #define _ISP1760_HCD_H_
 
 /* exports for if */
-struct usb_hcd *isp1760_register(u64 res_start, u64 res_len, int irq,
-               u64 irqflags, struct device *dev, const char *busname,
-               unsigned int devflags);
+struct usb_hcd *isp1760_register(phys_addr_t res_start, resource_size_t res_len,
+                                int irq, unsigned long irqflags,
+                                struct device *dev, const char *busname,
+                                unsigned int devflags);
 int init_kmem_once(void);
 void deinit_kmem_cache(void);
 
index 4cf7ca428b335ce049e86e27fcaa824ea65a607b..3fa3a17027963af75a2d15d5c5da7990b7c5fc7f 100644 (file)
@@ -10,6 +10,7 @@
 
 #include <linux/usb.h>
 #include <linux/io.h>
+#include <linux/platform_device.h>
 
 #include "../core/hcd.h"
 #include "isp1760-hcd.h"
@@ -300,39 +301,101 @@ static struct pci_driver isp1761_pci_driver = {
 };
 #endif
 
+static int __devinit isp1760_plat_probe(struct platform_device *pdev)
+{
+       int ret = 0;
+       struct usb_hcd *hcd;
+       struct resource *mem_res;
+       struct resource *irq_res;
+       resource_size_t mem_size;
+       unsigned long irqflags = IRQF_SHARED | IRQF_DISABLED;
+
+       mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!mem_res) {
+               pr_warning("isp1760: Memory resource not available\n");
+               ret = -ENODEV;
+               goto out;
+       }
+       mem_size = resource_size(mem_res);
+       if (!request_mem_region(mem_res->start, mem_size, "isp1760")) {
+               pr_warning("isp1760: Cannot reserve the memory resource\n");
+               ret = -EBUSY;
+               goto out;
+       }
+
+       irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+       if (!irq_res) {
+               pr_warning("isp1760: IRQ resource not available\n");
+               return -ENODEV;
+       }
+       irqflags |= irq_res->flags & IRQF_TRIGGER_MASK;
+
+       hcd = isp1760_register(mem_res->start, mem_size, irq_res->start,
+                              irqflags, &pdev->dev, dev_name(&pdev->dev), 0);
+       if (IS_ERR(hcd)) {
+               pr_warning("isp1760: Failed to register the HCD device\n");
+               ret = -ENODEV;
+               goto cleanup;
+       }
+
+       pr_info("ISP1760 USB device initialised\n");
+       return ret;
+
+cleanup:
+       release_mem_region(mem_res->start, mem_size);
+out:
+       return ret;
+}
+
+static int __devexit isp1760_plat_remove(struct platform_device *pdev)
+{
+       struct resource *mem_res;
+       resource_size_t mem_size;
+
+       mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       mem_size = resource_size(mem_res);
+       release_mem_region(mem_res->start, mem_size);
+
+       return 0;
+}
+
+static struct platform_driver isp1760_plat_driver = {
+       .probe  = isp1760_plat_probe,
+       .remove = isp1760_plat_remove,
+       .driver = {
+               .name   = "isp1760",
+       },
+};
+
 static int __init isp1760_init(void)
 {
-       int ret;
+       int ret, any_ret = -ENODEV;
 
        init_kmem_once();
 
+       ret = platform_driver_register(&isp1760_plat_driver);
+       if (!ret)
+               any_ret = 0;
 #ifdef CONFIG_PPC_OF
        ret = of_register_platform_driver(&isp1760_of_driver);
-       if (ret) {
-               deinit_kmem_cache();
-               return ret;
-       }
+       if (!ret)
+               any_ret = 0;
 #endif
 #ifdef CONFIG_PCI
        ret = pci_register_driver(&isp1761_pci_driver);
-       if (ret)
-               goto unreg_of;
+       if (!ret)
+               any_ret = 0;
 #endif
-       return ret;
 
-#ifdef CONFIG_PCI
-unreg_of:
-#endif
-#ifdef CONFIG_PPC_OF
-       of_unregister_platform_driver(&isp1760_of_driver);
-#endif
-       deinit_kmem_cache();
-       return ret;
+       if (any_ret)
+               deinit_kmem_cache();
+       return any_ret;
 }
 module_init(isp1760_init);
 
 static void __exit isp1760_exit(void)
 {
+       platform_driver_unregister(&isp1760_plat_driver);
 #ifdef CONFIG_PPC_OF
        of_unregister_platform_driver(&isp1760_of_driver);
 #endif
index 7658589edb1c289007f124fa07ebf44512f0244b..25db704f3a2aa8c7d60ae1c48eab54270abab45e 100644 (file)
@@ -997,7 +997,7 @@ MODULE_LICENSE ("GPL");
 #define SA1111_DRIVER          ohci_hcd_sa1111_driver
 #endif
 
-#ifdef CONFIG_ARCH_S3C2410
+#if defined(CONFIG_ARCH_S3C2410) || defined(CONFIG_ARCH_S3C64XX)
 #include "ohci-s3c2410.c"
 #define PLATFORM_DRIVER                ohci_hcd_s3c2410_driver
 #endif
index f46af7a718d416a548b565c142ccf8d229c1505f..a68af2dd55ca2aa93d6a5f6ddbb904911e0263b8 100644 (file)
@@ -21,9 +21,7 @@
 
 #include <linux/platform_device.h>
 #include <linux/clk.h>
-
-#include <mach/hardware.h>
-#include <mach/usb-control.h>
+#include <plat/usb-control.h>
 
 #define valid_port(idx) ((idx) == 1 || (idx) == 2)
 
@@ -372,7 +370,7 @@ static int usb_hcd_s3c2410_probe (const struct hc_driver *driver,
 
        usb_clk = clk_get(&dev->dev, "usb-bus-host");
        if (IS_ERR(usb_clk)) {
-               dev_err(&dev->dev, "cannot get usb-host clock\n");
+               dev_err(&dev->dev, "cannot get usb-bus-host clock\n");
                retval = -ENOENT;
                goto err_clk;
        }
index 75548f7c716b1eab04dd1041665ec9c02421adf8..5ac489ee3dab80a766db23a0199186e9f3628585 100644 (file)
@@ -845,14 +845,14 @@ static inline void qh_update(struct oxu_hcd *oxu,
                is_out = !(qtd->hw_token & cpu_to_le32(1 << 8));
                epnum = (le32_to_cpup(&qh->hw_info1) >> 8) & 0x0f;
                if (unlikely(!usb_gettoggle(qh->dev, epnum, is_out))) {
-                       qh->hw_token &= ~__constant_cpu_to_le32(QTD_TOGGLE);
+                       qh->hw_token &= ~cpu_to_le32(QTD_TOGGLE);
                        usb_settoggle(qh->dev, epnum, is_out, 1);
                }
        }
 
        /* HC must see latest qtd and qh data before we clear ACTIVE+HALT */
        wmb();
-       qh->hw_token &= __constant_cpu_to_le32(QTD_TOGGLE | QTD_STS_PING);
+       qh->hw_token &= cpu_to_le32(QTD_TOGGLE | QTD_STS_PING);
 }
 
 /* If it weren't for a common silicon quirk (writing the dummy into the qh
@@ -937,7 +937,7 @@ __acquires(oxu->lock)
                struct ehci_qh  *qh = (struct ehci_qh *) urb->hcpriv;
 
                /* S-mask in a QH means it's an interrupt urb */
-               if ((qh->hw_info2 & __constant_cpu_to_le32(QH_SMASK)) != 0) {
+               if ((qh->hw_info2 & cpu_to_le32(QH_SMASK)) != 0) {
 
                        /* ... update hc-wide periodic stats (for usbfs) */
                        oxu_to_hcd(oxu)->self.bandwidth_int_reqs--;
@@ -981,7 +981,7 @@ static void unlink_async(struct oxu_hcd *oxu, struct ehci_qh *qh);
 static void intr_deschedule(struct oxu_hcd *oxu, struct ehci_qh *qh);
 static int qh_schedule(struct oxu_hcd *oxu, struct ehci_qh *qh);
 
-#define HALT_BIT __constant_cpu_to_le32(QTD_STS_HALT)
+#define HALT_BIT cpu_to_le32(QTD_STS_HALT)
 
 /* Process and free completed qtds for a qh, returning URBs to drivers.
  * Chases up to qh->hw_current.  Returns number of completions called,
@@ -1160,7 +1160,7 @@ halt:
                        /* should be rare for periodic transfers,
                         * except maybe high bandwidth ...
                         */
-                       if ((__constant_cpu_to_le32(QH_SMASK)
+                       if ((cpu_to_le32(QH_SMASK)
                                        & qh->hw_info2) != 0) {
                                intr_deschedule(oxu, qh);
                                (void) qh_schedule(oxu, qh);
@@ -1350,7 +1350,7 @@ static struct list_head *qh_urb_transaction(struct oxu_hcd *oxu,
        }
 
        /* by default, enable interrupt on urb completion */
-               qtd->hw_token |= __constant_cpu_to_le32(QTD_IOC);
+               qtd->hw_token |= cpu_to_le32(QTD_IOC);
        return head;
 
 cleanup:
@@ -1539,7 +1539,7 @@ static void qh_link_async(struct oxu_hcd *oxu, struct ehci_qh *qh)
        /* qtd completions reported later by interrupt */
 }
 
-#define        QH_ADDR_MASK    __constant_cpu_to_le32(0x7f)
+#define        QH_ADDR_MASK    cpu_to_le32(0x7f)
 
 /*
  * For control/bulk/interrupt, return QH with these TDs appended.
@@ -2012,7 +2012,7 @@ static void qh_unlink_periodic(struct oxu_hcd *oxu, struct ehci_qh *qh)
         *   and this qh is active in the current uframe
         *   (and overlay token SplitXstate is false?)
         * THEN
-        *   qh->hw_info1 |= __constant_cpu_to_le32(1 << 7 "ignore");
+        *   qh->hw_info1 |= cpu_to_le32(1 << 7 "ignore");
         */
 
        /* high bandwidth, or otherwise part of every microframe */
@@ -2057,7 +2057,7 @@ static void intr_deschedule(struct oxu_hcd *oxu, struct ehci_qh *qh)
         * active high speed queues may need bigger delays...
         */
        if (list_empty(&qh->qtd_list)
-               || (__constant_cpu_to_le32(QH_CMASK) & qh->hw_info2) != 0)
+               || (cpu_to_le32(QH_CMASK) & qh->hw_info2) != 0)
                wait = 2;
        else
                wait = 55;      /* worst case: 3 * 1024 */
@@ -2183,10 +2183,10 @@ static int qh_schedule(struct oxu_hcd *oxu, struct ehci_qh *qh)
                qh->start = frame;
 
                /* reset S-frame and (maybe) C-frame masks */
-               qh->hw_info2 &= __constant_cpu_to_le32(~(QH_CMASK | QH_SMASK));
+               qh->hw_info2 &= cpu_to_le32(~(QH_CMASK | QH_SMASK));
                qh->hw_info2 |= qh->period
                        ? cpu_to_le32(1 << uframe)
-                       : __constant_cpu_to_le32(QH_SMASK);
+                       : cpu_to_le32(QH_SMASK);
                qh->hw_info2 |= c_mask;
        } else
                oxu_dbg(oxu, "reused qh %p schedule\n", qh);
@@ -2684,7 +2684,7 @@ static int oxu_reset(struct usb_hcd *hcd)
        oxu->urb_len = 0;
 
        /* FIMXE */
-       hcd->self.controller->dma_mask = 0UL;
+       hcd->self.controller->dma_mask = NULL;
 
        if (oxu->is_otg) {
                oxu->caps = hcd->regs + OXU_OTG_CAP_OFFSET;
index 8910e271cc7dd482cc08bc70ec805979b2f5c901..1c216ad9aad28426913f68b4dc12dac6f6699953 100644 (file)
@@ -235,21 +235,21 @@ struct ehci_qtd {
 } __attribute__ ((aligned(32)));
 
 /* mask NakCnt+T in qh->hw_alt_next */
-#define QTD_MASK __constant_cpu_to_le32 (~0x1f)
+#define QTD_MASK cpu_to_le32 (~0x1f)
 
 #define IS_SHORT_READ(token) (QTD_LENGTH(token) != 0 && QTD_PID(token) == 1)
 
 /* Type tag from {qh, itd, sitd, fstn}->hw_next */
-#define Q_NEXT_TYPE(dma) ((dma) & __constant_cpu_to_le32 (3 << 1))
+#define Q_NEXT_TYPE(dma) ((dma) & cpu_to_le32 (3 << 1))
 
 /* values for that type tag */
-#define Q_TYPE_QH      __constant_cpu_to_le32 (1 << 1)
+#define Q_TYPE_QH      cpu_to_le32 (1 << 1)
 
 /* next async queue entry, or pointer to interrupt/periodic QH */
 #define        QH_NEXT(dma)    (cpu_to_le32(((u32)dma)&~0x01f)|Q_TYPE_QH)
 
 /* for periodic/async schedules and qtd lists, mark end of list */
-#define        EHCI_LIST_END   __constant_cpu_to_le32(1) /* "null pointer" to hw */
+#define        EHCI_LIST_END   cpu_to_le32(1) /* "null pointer" to hw */
 
 /*
  * Entries in periodic shadow table are pointers to one of four kinds
index 75b69847918e3a35c3a2832188ca0cb87dc6c9cb..033c2846ce5923e05f0805bff889ab45268ea056 100644 (file)
@@ -234,7 +234,7 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev)
         */
        hcc_params = readl(base + EHCI_HCC_PARAMS);
        offset = (hcc_params >> 8) & 0xff;
-       while (offset && count--) {
+       while (offset && --count) {
                u32             cap;
                int             msec;
 
index 319041205b57c878b38b7b60b9ad1a9f3bf47dab..f1626e58c141ff207fac18c57d3ce58212f86b72 100644 (file)
@@ -660,9 +660,9 @@ static u16 get_empty_pipenum(struct r8a66597 *r8a66597,
        u16 array[R8A66597_MAX_NUM_PIPE], i = 0, min;
 
        memset(array, 0, sizeof(array));
-       switch (ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
+       switch (usb_endpoint_type(ep)) {
        case USB_ENDPOINT_XFER_BULK:
-               if (ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK)
+               if (usb_endpoint_dir_in(ep))
                        array[i++] = 4;
                else {
                        array[i++] = 3;
@@ -670,7 +670,7 @@ static u16 get_empty_pipenum(struct r8a66597 *r8a66597,
                }
                break;
        case USB_ENDPOINT_XFER_INT:
-               if (ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) {
+               if (usb_endpoint_dir_in(ep)) {
                        array[i++] = 6;
                        array[i++] = 7;
                        array[i++] = 8;
@@ -678,7 +678,7 @@ static u16 get_empty_pipenum(struct r8a66597 *r8a66597,
                        array[i++] = 9;
                break;
        case USB_ENDPOINT_XFER_ISOC:
-               if (ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK)
+               if (usb_endpoint_dir_in(ep))
                        array[i++] = 2;
                else
                        array[i++] = 1;
@@ -928,10 +928,9 @@ static void init_pipe_info(struct r8a66597 *r8a66597, struct urb *urb,
 
        info.pipenum = get_empty_pipenum(r8a66597, ep);
        info.address = get_urb_to_r8a66597_addr(r8a66597, urb);
-       info.epnum = ep->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
+       info.epnum = usb_endpoint_num(ep);
        info.maxpacket = le16_to_cpu(ep->wMaxPacketSize);
-       info.type = get_r8a66597_type(ep->bmAttributes
-                                     & USB_ENDPOINT_XFERTYPE_MASK);
+       info.type = get_r8a66597_type(usb_endpoint_type(ep));
        info.bufnum = get_bufnum(info.pipenum);
        info.buf_bsize = get_buf_bsize(info.pipenum);
        if (info.type == R8A66597_BULK) {
@@ -941,7 +940,7 @@ static void init_pipe_info(struct r8a66597 *r8a66597, struct urb *urb,
                info.interval = get_interval(urb, ep->bInterval);
                info.timer_interval = get_timer_interval(urb, ep->bInterval);
        }
-       if (ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK)
+       if (usb_endpoint_dir_in(ep))
                info.dir_in = 1;
        else
                info.dir_in = 0;
@@ -1014,6 +1013,9 @@ static void r8a66597_check_syssts(struct r8a66597 *r8a66597, int port,
 
        r8a66597_write(r8a66597, ~DTCH, get_intsts_reg(port));
        r8a66597_bset(r8a66597, DTCHE, get_intenb_reg(port));
+
+       if (r8a66597->bus_suspended)
+               usb_hcd_resume_root_hub(r8a66597_to_hcd(r8a66597));
 }
 
 /* this function must be called with interrupt disabled */
@@ -1395,7 +1397,7 @@ static void packet_write(struct r8a66597 *r8a66597, u16 pipenum)
                           (int)urb->iso_frame_desc[td->iso_cnt].length);
        } else {
                buf = (u16 *)(urb->transfer_buffer + urb->actual_length);
-               size = min((int)bufsize,
+               size = min_t(u32, bufsize,
                           urb->transfer_buffer_length - urb->actual_length);
        }
 
@@ -1615,6 +1617,11 @@ static irqreturn_t r8a66597_irq(struct usb_hcd *hcd)
                        r8a66597_bclr(r8a66597, DTCHE, INTENB2);
                        r8a66597_usb_disconnect(r8a66597, 1);
                }
+               if (mask2 & BCHG) {
+                       r8a66597_write(r8a66597, ~BCHG, INTSTS2);
+                       r8a66597_bclr(r8a66597, BCHGE, INTENB2);
+                       usb_hcd_resume_root_hub(r8a66597_to_hcd(r8a66597));
+               }
        }
 
        if (mask1) {
@@ -1630,6 +1637,12 @@ static irqreturn_t r8a66597_irq(struct usb_hcd *hcd)
                        r8a66597_bclr(r8a66597, DTCHE, INTENB1);
                        r8a66597_usb_disconnect(r8a66597, 0);
                }
+               if (mask1 & BCHG) {
+                       r8a66597_write(r8a66597, ~BCHG, INTSTS1);
+                       r8a66597_bclr(r8a66597, BCHGE, INTENB1);
+                       usb_hcd_resume_root_hub(r8a66597_to_hcd(r8a66597));
+               }
+
                if (mask1 & SIGN) {
                        r8a66597_write(r8a66597, ~SIGN, INTSTS1);
                        status = get_urb_error(r8a66597, 0);
@@ -2141,7 +2154,7 @@ static int r8a66597_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
 
                switch (wValue) {
                case USB_PORT_FEAT_ENABLE:
-                       rh->port &= (1 << USB_PORT_FEAT_POWER);
+                       rh->port &= ~(1 << USB_PORT_FEAT_POWER);
                        break;
                case USB_PORT_FEAT_SUSPEND:
                        break;
@@ -2213,6 +2226,68 @@ error:
        return ret;
 }
 
+#if defined(CONFIG_PM)
+static int r8a66597_bus_suspend(struct usb_hcd *hcd)
+{
+       struct r8a66597 *r8a66597 = hcd_to_r8a66597(hcd);
+       int port;
+
+       dbg("%s", __func__);
+
+       for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++) {
+               struct r8a66597_root_hub *rh = &r8a66597->root_hub[port];
+               unsigned long dvstctr_reg = get_dvstctr_reg(port);
+
+               if (!(rh->port & (1 << USB_PORT_FEAT_ENABLE)))
+                       continue;
+
+               dbg("suspend port = %d", port);
+               r8a66597_bclr(r8a66597, UACT, dvstctr_reg);     /* suspend */
+               rh->port |= 1 << USB_PORT_FEAT_SUSPEND;
+
+               if (rh->dev->udev->do_remote_wakeup) {
+                       msleep(3);      /* waiting last SOF */
+                       r8a66597_bset(r8a66597, RWUPE, dvstctr_reg);
+                       r8a66597_write(r8a66597, ~BCHG, get_intsts_reg(port));
+                       r8a66597_bset(r8a66597, BCHGE, get_intenb_reg(port));
+               }
+       }
+
+       r8a66597->bus_suspended = 1;
+
+       return 0;
+}
+
+static int r8a66597_bus_resume(struct usb_hcd *hcd)
+{
+       struct r8a66597 *r8a66597 = hcd_to_r8a66597(hcd);
+       int port;
+
+       dbg("%s", __func__);
+
+       for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++) {
+               struct r8a66597_root_hub *rh = &r8a66597->root_hub[port];
+               unsigned long dvstctr_reg = get_dvstctr_reg(port);
+
+               if (!(rh->port & (1 << USB_PORT_FEAT_SUSPEND)))
+                       continue;
+
+               dbg("resume port = %d", port);
+               rh->port &= ~(1 << USB_PORT_FEAT_SUSPEND);
+               rh->port |= 1 << USB_PORT_FEAT_C_SUSPEND;
+               r8a66597_mdfy(r8a66597, RESUME, RESUME | UACT, dvstctr_reg);
+               msleep(50);
+               r8a66597_mdfy(r8a66597, UACT, RESUME | UACT, dvstctr_reg);
+       }
+
+       return 0;
+
+}
+#else
+#define        r8a66597_bus_suspend    NULL
+#define        r8a66597_bus_resume     NULL
+#endif
+
 static struct hc_driver r8a66597_hc_driver = {
        .description =          hcd_name,
        .hcd_priv_size =        sizeof(struct r8a66597),
@@ -2243,16 +2318,39 @@ static struct hc_driver r8a66597_hc_driver = {
         */
        .hub_status_data =      r8a66597_hub_status_data,
        .hub_control =          r8a66597_hub_control,
+       .bus_suspend =          r8a66597_bus_suspend,
+       .bus_resume =           r8a66597_bus_resume,
 };
 
 #if defined(CONFIG_PM)
 static int r8a66597_suspend(struct platform_device *pdev, pm_message_t state)
 {
+       struct r8a66597         *r8a66597 = dev_get_drvdata(&pdev->dev);
+       int port;
+
+       dbg("%s", __func__);
+
+       disable_controller(r8a66597);
+
+       for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++) {
+               struct r8a66597_root_hub *rh = &r8a66597->root_hub[port];
+
+               rh->port = 0x00000000;
+       }
+
        return 0;
 }
 
 static int r8a66597_resume(struct platform_device *pdev)
 {
+       struct r8a66597         *r8a66597 = dev_get_drvdata(&pdev->dev);
+       struct usb_hcd          *hcd = r8a66597_to_hcd(r8a66597);
+
+       dbg("%s", __func__);
+
+       enable_controller(r8a66597);
+       usb_root_hub_lost_power(hcd->self.root_hub);
+
        return 0;
 }
 #else  /* if defined(CONFIG_PM) */
index ecacde4d69b0801fcf67a0d9a7d316e015829b83..f49208f1bb74d80003c9a79b1e87090d298ac5f4 100644 (file)
@@ -504,6 +504,8 @@ struct r8a66597 {
 
        struct list_head child_device;
        unsigned long child_connect_map[4];
+
+       unsigned bus_suspended:1;
 };
 
 static inline struct r8a66597 *hcd_to_r8a66597(struct usb_hcd *hcd)
index e106e9d48d4ad282870acf04aac010ea95a40458..a949259f18b984794d9bc46200e1f0e3303e1f6e 100644 (file)
@@ -230,7 +230,7 @@ static void in_packet(
        writeb(usb_pipedevice(urb->pipe), data_reg);
 
        sl811_write(sl811, bank + SL11H_HOSTCTLREG, control);
-       ep->length = min((int)len,
+       ep->length = min_t(u32, len,
                        urb->transfer_buffer_length - urb->actual_length);
        PACKET("IN%s/%d qh%p len%d\n", ep->nak_count ? "/retry" : "",
                        !!usb_gettoggle(urb->dev, ep->epnum, 0), ep, len);
@@ -255,7 +255,7 @@ static void out_packet(
        buf = urb->transfer_buffer + urb->actual_length;
        prefetch(buf);
 
-       len = min((int)ep->maxpacket,
+       len = min_t(u32, ep->maxpacket,
                        urb->transfer_buffer_length - urb->actual_length);
 
        if (!(control & SL11H_HCTLMASK_ISOCH)
index 20cc58b9780713c573f874c85e01968e15a5f947..e52b954dda471d1a492e5be2a10ff2b5a19d8bdf 100644 (file)
@@ -118,7 +118,9 @@ static int uhci_show_urbp(struct urb_priv *urbp, char *buf, int len, int space)
        }
 
        out += sprintf(out, "%s%s", ptype, (urbp->fsbr ? " FSBR" : ""));
-       out += sprintf(out, " Actlen=%d", urbp->urb->actual_length);
+       out += sprintf(out, " Actlen=%d%s", urbp->urb->actual_length,
+                       (urbp->qh->type == USB_ENDPOINT_XFER_CONTROL ?
+                               "-8" : ""));
 
        if (urbp->urb->unlinked)
                out += sprintf(out, " Unlinked=%d", urbp->urb->unlinked);
index 7d01c5677f92ced1517c73dc562e853c2e6990fa..26bd1b2bcbfc81162bfb5c05662457ed92d57cf5 100644 (file)
 #define   USBLEGSUP_RWC                0x8f00  /* the R/WC bits */
 #define   USBLEGSUP_RO         0x5040  /* R/O and reserved bits */
 
-#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_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_NUMFRAMES         1024    /* in the frame list [array] */
 #define UHCI_MAX_SOF_NUMBER    2047    /* in an SOF packet */
index 5631d89c87309ce0155287534b77a234f71eba20..3e5807d14ffb5ed89d765b9b82087cb2e2d5fb30 100644 (file)
@@ -402,7 +402,7 @@ static void uhci_fixup_toggles(struct uhci_qh *qh, int skip_first)
                /* 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 ^= cpu_to_le32(
                                                        TD_TOKEN_TOGGLE);
                                toggle ^= 1;
                        }
@@ -883,7 +883,7 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb,
 
        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->status |= cpu_to_le32(TD_CTRL_ACTIVE);
        qh->dummy_td = td;
 
        /* Low-speed transfers get a different queue, and won't hog the bus.
@@ -899,8 +899,6 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb,
        }
        if (qh->state != QH_STATE_ACTIVE)
                qh->skel = skel;
-
-       urb->actual_length = -8;        /* Account for the SETUP packet */
        return 0;
 
 nomem:
@@ -1003,7 +1001,7 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb,
         * 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 |= __constant_cpu_to_le32(TD_CTRL_IOC);
+       td->status |= cpu_to_le32(TD_CTRL_IOC);
 
        /*
         * Build the new dummy TD and activate the old one
@@ -1015,7 +1013,7 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb,
 
        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->status |= cpu_to_le32(TD_CTRL_ACTIVE);
        qh->dummy_td = td;
 
        usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe),
@@ -1317,7 +1315,7 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb,
        }
 
        /* Set the interrupt-on-completion flag on the last packet. */
-       td->status |= __constant_cpu_to_le32(TD_CTRL_IOC);
+       td->status |= cpu_to_le32(TD_CTRL_IOC);
 
        /* Add the TDs to the frame list */
        frame = urb->start_frame;
@@ -1494,11 +1492,10 @@ __acquires(uhci->lock)
 
        if (qh->type == USB_ENDPOINT_XFER_CONTROL) {
 
-               /* urb->actual_length < 0 means the setup transaction didn't
-                * complete successfully.  Either it failed or the URB was
-                * unlinked first.  Regardless, don't confuse people with a
-                * negative length. */
-               urb->actual_length = max(urb->actual_length, 0);
+               /* Subtract off the length of the SETUP packet from
+                * urb->actual_length.
+                */
+               urb->actual_length -= min_t(u32, 8, urb->actual_length);
        }
 
        /* When giving back the first URB in an Isochronous queue,
index 972f20b3406cee41b9d86351fc976ec22533b38f..eca355dccf651215387cf76e7ef5951c4ed35f25 100644 (file)
@@ -188,7 +188,7 @@ static struct usb_endpoint_descriptor mdc800_ed [4] =
                .bDescriptorType =      0,
                .bEndpointAddress =     0x01,
                .bmAttributes =         0x02,
-               .wMaxPacketSize =       __constant_cpu_to_le16(8),
+               .wMaxPacketSize =       cpu_to_le16(8),
                .bInterval =            0,
                .bRefresh =             0,
                .bSynchAddress =        0,
@@ -198,7 +198,7 @@ static struct usb_endpoint_descriptor mdc800_ed [4] =
                .bDescriptorType =      0,
                .bEndpointAddress =     0x82,
                .bmAttributes =         0x03,
-               .wMaxPacketSize =       __constant_cpu_to_le16(8),
+               .wMaxPacketSize =       cpu_to_le16(8),
                .bInterval =            0,
                .bRefresh =             0,
                .bSynchAddress =        0,
@@ -208,7 +208,7 @@ static struct usb_endpoint_descriptor mdc800_ed [4] =
                .bDescriptorType =      0,
                .bEndpointAddress =     0x03,
                .bmAttributes =         0x02,
-               .wMaxPacketSize =       __constant_cpu_to_le16(64),
+               .wMaxPacketSize =       cpu_to_le16(64),
                .bInterval =            0,
                .bRefresh =             0,
                .bSynchAddress =        0,
@@ -218,7 +218,7 @@ static struct usb_endpoint_descriptor mdc800_ed [4] =
                .bDescriptorType =      0,
                .bEndpointAddress =     0x84,
                .bmAttributes =         0x02,
-               .wMaxPacketSize =       __constant_cpu_to_le16(64),
+               .wMaxPacketSize =       cpu_to_le16(64),
                .bInterval =            0,
                .bRefresh =             0,
                .bSynchAddress =        0,
index e463db5d818849860a23cb855e82a5cfd86624f4..a68d91a11bee32422dd1296ff539b7b036228b73 100644 (file)
@@ -135,45 +135,6 @@ config USB_CYTHERM
          To compile this driver as a module, choose M here: the
          module will be called cytherm.
 
-config USB_PHIDGET
-       tristate "USB Phidgets drivers"
-       depends on USB
-       help
-         Say Y here to enable the various drivers for devices from
-         Phidgets inc.
-
-config USB_PHIDGETKIT
-       tristate "USB PhidgetInterfaceKit support"
-       depends on USB_PHIDGET
-       help
-         Say Y here if you want to connect a PhidgetInterfaceKit USB device
-         from Phidgets Inc.
-
-         To compile this driver as a module, choose M here: the
-         module will be called phidgetkit.
-
-config USB_PHIDGETMOTORCONTROL
-       tristate "USB PhidgetMotorControl support"
-       depends on USB_PHIDGET
-       help
-         Say Y here if you want to connect a PhidgetMotorControl USB device
-         from Phidgets Inc.
-
-         To compile this driver as a module, choose M here: the
-         module will be called phidgetmotorcontrol.
-
-config USB_PHIDGETSERVO
-       tristate "USB PhidgetServo support"
-       depends on USB_PHIDGET
-       help
-         Say Y here if you want to connect an 1 or 4 Motor PhidgetServo 
-         servo controller version 2.0 or 3.0.
-
-         Phidgets Inc. has a web page at <http://www.phidgets.com/>.
-
-         To compile this driver as a module, choose M here: the
-         module will be called phidgetservo.
-
 config USB_IDMOUSE
        tristate "Siemens ID USB Mouse Fingerprint sensor support"
        depends on USB
index 1334f7bdd7bef16020f767a60133cef3b2654c4e..0826aab8303fc1e0e1a9bf33f46ef7b7204a6b4f 100644 (file)
@@ -18,10 +18,6 @@ obj-$(CONFIG_USB_LCD)                += usblcd.o
 obj-$(CONFIG_USB_LD)           += ldusb.o
 obj-$(CONFIG_USB_LED)          += usbled.o
 obj-$(CONFIG_USB_LEGOTOWER)    += legousbtower.o
-obj-$(CONFIG_USB_PHIDGET)      += phidget.o
-obj-$(CONFIG_USB_PHIDGETKIT)   += phidgetkit.o
-obj-$(CONFIG_USB_PHIDGETMOTORCONTROL)  += phidgetmotorcontrol.o
-obj-$(CONFIG_USB_PHIDGETSERVO) += phidgetservo.o
 obj-$(CONFIG_USB_RIO500)       += rio500.o
 obj-$(CONFIG_USB_TEST)         += usbtest.o
 obj-$(CONFIG_USB_TRANCEVIBRATOR)       += trancevibrator.o
index 79a7668ef2647d71813108d7fbddc408604c4577..9d0675ed0d4c89e0acbf488dfd6beb7df9e9131c 100644 (file)
@@ -1568,7 +1568,7 @@ static int ftdi_elan_edset_input(struct usb_ftdi *ftdi, u8 ed_number,
                         struct u132_target *target = &ftdi->target[ed];
                         struct u132_command *command = &ftdi->command[
                                 COMMAND_MASK & ftdi->command_next];
-                        int remaining_length = urb->transfer_buffer_length -
+                        u32 remaining_length = urb->transfer_buffer_length -
                                 urb->actual_length;
                         command->header = 0x82 | (ed << 5);
                         if (remaining_length == 0) {
@@ -1702,7 +1702,7 @@ static int ftdi_elan_edset_output(struct usb_ftdi *ftdi, u8 ed_number,
                                 | (address << 0);
                         command->width = usb_maxpacket(urb->dev, urb->pipe,
                                 usb_pipeout(urb->pipe));
-                        command->follows = min(1024,
+                        command->follows = min_t(u32, 1024,
                                 urb->transfer_buffer_length -
                                 urb->actual_length);
                         command->value = 0;
@@ -1766,7 +1766,7 @@ static int ftdi_elan_edset_single(struct usb_ftdi *ftdi, u8 ed_number,
                 mutex_lock(&ftdi->u132_lock);
                 command_size = ftdi->command_next - ftdi->command_head;
                 if (command_size < COMMAND_SIZE) {
-                        int remaining_length = urb->transfer_buffer_length -
+                        u32 remaining_length = urb->transfer_buffer_length -
                                 urb->actual_length;
                         struct u132_target *target = &ftdi->target[ed];
                         struct u132_command *command = &ftdi->command[
diff --git a/drivers/usb/misc/phidget.c b/drivers/usb/misc/phidget.c
deleted file mode 100644 (file)
index 735ed33..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * USB Phidgets class
- *
- * Copyright (C) 2006  Sean Young <sean@mess.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.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/err.h>
-#include <linux/device.h>
-
-struct class *phidget_class;
-
-static int __init init_phidget(void)
-{
-       phidget_class = class_create(THIS_MODULE, "phidget");
-
-       if (IS_ERR(phidget_class))
-               return PTR_ERR(phidget_class);
-
-       return 0;
-}
-
-static void __exit cleanup_phidget(void)
-{
-       class_destroy(phidget_class);
-}
-
-EXPORT_SYMBOL_GPL(phidget_class);
-
-module_init(init_phidget);
-module_exit(cleanup_phidget);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Sean Young <sean@mess.org>");
-MODULE_DESCRIPTION("Container module for phidget class");
-
diff --git a/drivers/usb/misc/phidget.h b/drivers/usb/misc/phidget.h
deleted file mode 100644 (file)
index c401190..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-/*
- * USB Phidgets class
- *
- * Copyright (C) 2006  Sean Young <sean@mess.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.
- */
-
-extern struct class *phidget_class;
diff --git a/drivers/usb/misc/phidgetkit.c b/drivers/usb/misc/phidgetkit.c
deleted file mode 100644 (file)
index cc8e0a9..0000000
+++ /dev/null
@@ -1,740 +0,0 @@
-/*
- * USB PhidgetInterfaceKit driver 1.0
- *
- * Copyright (C) 2004, 2006 Sean Young <sean@mess.org>
- * Copyright (C) 2005 Daniel Saakes <daniel@saakes.net>
- * Copyright (C) 2004 Greg Kroah-Hartman <greg@kroah.com>
- *
- * 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 is a driver for the USB PhidgetInterfaceKit.
- */
-
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/usb.h>
-
-#include "phidget.h"
-
-#define DRIVER_AUTHOR "Sean Young <sean@mess.org>"
-#define DRIVER_DESC "USB PhidgetInterfaceKit Driver"
-
-#define USB_VENDOR_ID_GLAB             0x06c2
-#define USB_DEVICE_ID_INTERFACEKIT004  0x0040
-#define USB_DEVICE_ID_INTERFACEKIT01616        0x0044
-#define USB_DEVICE_ID_INTERFACEKIT888  0x0045
-#define USB_DEVICE_ID_INTERFACEKIT047  0x0051
-#define USB_DEVICE_ID_INTERFACEKIT088  0x0053
-
-#define USB_VENDOR_ID_WISEGROUP                0x0925
-#define USB_DEVICE_ID_INTERFACEKIT884  0x8201
-
-#define MAX_INTERFACES                 16
-
-#define URB_INT_SIZE                   8
-
-struct driver_interfacekit {
-       int sensors;
-       int inputs;
-       int outputs;
-       int has_lcd;
-       int amnesiac;
-};
-
-#define ifkit(_sensors, _inputs, _outputs, _lcd, _amnesiac)            \
-{                                                                      \
-       .sensors        = _sensors,                                     \
-       .inputs         = _inputs,                                      \
-       .outputs        = _outputs,                                     \
-       .has_lcd        = _lcd,                                         \
-       .amnesiac       = _amnesiac                                     \
-};
-
-static const struct driver_interfacekit ph_004 = ifkit(0, 0, 4, 0, 0);
-static const struct driver_interfacekit ph_888n = ifkit(8, 8, 8, 0, 1);
-static const struct driver_interfacekit ph_888o = ifkit(8, 8, 8, 0, 0);
-static const struct driver_interfacekit ph_047 = ifkit(0, 4, 7, 1, 0);
-static const struct driver_interfacekit ph_884 = ifkit(8, 8, 4, 0, 0);
-static const struct driver_interfacekit ph_088 = ifkit(0, 8, 8, 1, 0);
-static const struct driver_interfacekit ph_01616 = ifkit(0, 16, 16, 0, 0);
-
-static unsigned long device_no;
-
-struct interfacekit {
-       struct usb_device *udev;
-       struct usb_interface *intf;
-       struct driver_interfacekit *ifkit;
-       struct device *dev;
-       unsigned long outputs;
-       int dev_no;
-       u8 inputs[MAX_INTERFACES];
-       u16 sensors[MAX_INTERFACES];
-       u8 lcd_files_on;
-
-       struct urb *irq;
-       unsigned char *data;
-       dma_addr_t data_dma;
-
-       struct delayed_work do_notify;
-       struct delayed_work do_resubmit;
-       unsigned long input_events;
-       unsigned long sensor_events;
-};
-
-static struct usb_device_id id_table[] = {
-       {USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_INTERFACEKIT004),
-               .driver_info = (kernel_ulong_t)&ph_004},
-       {USB_DEVICE_VER(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_INTERFACEKIT888, 0, 0x814),
-               .driver_info = (kernel_ulong_t)&ph_888o},
-       {USB_DEVICE_VER(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_INTERFACEKIT888, 0x0815, 0xffff),
-               .driver_info = (kernel_ulong_t)&ph_888n},
-       {USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_INTERFACEKIT047),
-               .driver_info = (kernel_ulong_t)&ph_047},
-       {USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_INTERFACEKIT088),
-               .driver_info = (kernel_ulong_t)&ph_088},
-       {USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_INTERFACEKIT01616),
-               .driver_info = (kernel_ulong_t)&ph_01616},
-       {USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_INTERFACEKIT884),
-               .driver_info = (kernel_ulong_t)&ph_884},
-       {}
-};
-MODULE_DEVICE_TABLE(usb, id_table);
-
-static int set_outputs(struct interfacekit *kit)
-{
-       u8 *buffer;
-       int retval;
-
-       buffer = kzalloc(4, GFP_KERNEL);
-       if (!buffer) {
-               dev_err(&kit->udev->dev, "%s - out of memory\n", __func__);
-               return -ENOMEM;
-       }
-       buffer[0] = (u8)kit->outputs;
-       buffer[1] = (u8)(kit->outputs >> 8);
-
-       dev_dbg(&kit->udev->dev, "sending data: 0x%04x\n", (u16)kit->outputs);
-
-       retval = usb_control_msg(kit->udev,
-                        usb_sndctrlpipe(kit->udev, 0),
-                        0x09, 0x21, 0x0200, 0x0000, buffer, 4, 2000);
-
-       if (retval != 4)
-               dev_err(&kit->udev->dev, "usb_control_msg returned %d\n", 
-                               retval);
-       kfree(buffer);
-
-       if (kit->ifkit->amnesiac)
-               schedule_delayed_work(&kit->do_resubmit, HZ / 2);
-
-       return retval < 0 ? retval : 0;
-}
-
-static int change_string(struct interfacekit *kit, const char *display, unsigned char row)
-{
-       unsigned char *buffer;
-       unsigned char *form_buffer;
-       int retval = -ENOMEM;
-       int i,j, len, buf_ptr;
-       
-       buffer = kmalloc(8, GFP_KERNEL);
-       form_buffer = kmalloc(30, GFP_KERNEL);
-       if ((!buffer) || (!form_buffer)) {
-               dev_err(&kit->udev->dev, "%s - out of memory\n", __func__);
-               goto exit;
-       }
-
-       len = strlen(display);
-       if (len > 20)
-               len = 20;
-
-       dev_dbg(&kit->udev->dev, "Setting LCD line %d to %s\n", row, display);
-
-       form_buffer[0] = row * 0x40 + 0x80;
-       form_buffer[1] = 0x02;
-       buf_ptr = 2;
-       for (i = 0; i<len; i++)
-               form_buffer[buf_ptr++] = display[i];
-
-       for (i = 0; i < (20 - len); i++)
-               form_buffer[buf_ptr++] = 0x20;
-       form_buffer[buf_ptr++] = 0x01;
-       form_buffer[buf_ptr++] = row * 0x40 + 0x80 + strlen(display);
-
-       for (i = 0; i < buf_ptr; i += 7) {
-               if ((buf_ptr - i) > 7)
-                       len = 7;
-               else
-                       len = (buf_ptr - i);
-               for (j = 0; j < len; j++)
-                       buffer[j] = form_buffer[i + j];
-               buffer[7] = len;
-
-               retval = usb_control_msg(kit->udev,
-                                usb_sndctrlpipe(kit->udev, 0),
-                                0x09, 0x21, 0x0200, 0x0000, buffer, 8, 2000);
-               if (retval < 0)
-                       goto exit;
-       }
-
-       retval = 0;
-exit:
-       kfree(buffer);
-       kfree(form_buffer);
-
-       return retval;
-}
-
-#define set_lcd_line(number)   \
-static ssize_t lcd_line_##number(struct device *dev,                   \
-                                       struct device_attribute *attr,  \
-                                       const char *buf, size_t count)  \
-{                                                                      \
-       struct interfacekit *kit = dev_get_drvdata(dev);                \
-       change_string(kit, buf, number - 1);                            \
-       return count;                                                   \
-}
-
-#define lcd_line_attr(number)                                          \
-       __ATTR(lcd_line_##number, S_IWUGO, NULL, lcd_line_##number)
-
-set_lcd_line(1);
-set_lcd_line(2);
-
-static ssize_t set_backlight(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-{
-       struct interfacekit *kit = dev_get_drvdata(dev);
-       int enabled;
-       unsigned char *buffer;
-       int retval = -ENOMEM;
-       
-       buffer = kzalloc(8, GFP_KERNEL);
-       if (!buffer) {
-               dev_err(&kit->udev->dev, "%s - out of memory\n", __func__);
-               goto exit;
-       }
-
-       if (sscanf(buf, "%d", &enabled) < 1) {
-               retval = -EINVAL;
-               goto exit;
-       }
-       if (enabled)
-               buffer[0] = 0x01;
-       buffer[7] = 0x11;
-
-       dev_dbg(&kit->udev->dev, "Setting backlight to %s\n", enabled ? "on" : "off");
-       
-       retval = usb_control_msg(kit->udev,
-                        usb_sndctrlpipe(kit->udev, 0),
-                        0x09, 0x21, 0x0200, 0x0000, buffer, 8, 2000);
-       if (retval < 0)
-               goto exit;
-
-       retval = count;
-exit:
-       kfree(buffer);
-       return retval;
-}
-
-static struct device_attribute dev_lcd_line_attrs[] = {
-       lcd_line_attr(1),
-       lcd_line_attr(2),
-       __ATTR(backlight, S_IWUGO, NULL, set_backlight)
-};
-
-static void remove_lcd_files(struct interfacekit *kit)
-{
-       int i;
-
-       if (kit->lcd_files_on) {
-               dev_dbg(&kit->udev->dev, "Removing lcd files\n");
-
-               for (i=0; i<ARRAY_SIZE(dev_lcd_line_attrs); i++)
-                       device_remove_file(kit->dev, &dev_lcd_line_attrs[i]);
-       }
-}
-
-static ssize_t enable_lcd_files(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-{
-       struct interfacekit *kit = dev_get_drvdata(dev);
-       int enable;
-       int i, rc;
-       
-       if (kit->ifkit->has_lcd == 0)
-               return -ENODEV;
-
-       if (sscanf(buf, "%d", &enable) < 1)
-               return -EINVAL;
-
-       if (enable) {
-               if (!kit->lcd_files_on) {
-                       dev_dbg(&kit->udev->dev, "Adding lcd files\n");
-                       for (i=0; i<ARRAY_SIZE(dev_lcd_line_attrs); i++) {
-                               rc = device_create_file(kit->dev,
-                                       &dev_lcd_line_attrs[i]);
-                               if (rc)
-                                       goto out;
-                       }
-                       kit->lcd_files_on = 1;
-               }
-       } else {
-               if (kit->lcd_files_on) {
-                       remove_lcd_files(kit);
-                       kit->lcd_files_on = 0;
-               }
-       }
-       
-       return count;
-out:
-       while (i-- > 0)
-               device_remove_file(kit->dev, &dev_lcd_line_attrs[i]);
-
-       return rc;
-}
-
-static DEVICE_ATTR(lcd, S_IWUGO, NULL, enable_lcd_files);
-
-static void interfacekit_irq(struct urb *urb)
-{
-       struct interfacekit *kit = urb->context;
-       unsigned char *buffer = kit->data;
-       int i, level, sensor;
-       int retval;
-       int status = urb->status;
-
-       switch (status) {
-       case 0:                 /* success */
-               break;
-       case -ECONNRESET:       /* unlink */
-       case -ENOENT:
-       case -ESHUTDOWN:
-               return;
-       /* -EPIPE:  should clear the halt */
-       default:                /* error */
-               goto resubmit;
-       }
-
-       /* digital inputs */
-       if (kit->ifkit->inputs == 16) {
-               for (i=0; i < 8; i++) {
-                       level = (buffer[0] >> i) & 1;
-                       if (kit->inputs[i] != level) {
-                               kit->inputs[i] = level;
-                               set_bit(i, &kit->input_events);
-                       }
-                       level = (buffer[1] >> i) & 1;
-                       if (kit->inputs[8 + i] != level) {
-                               kit->inputs[8 + i] = level;
-                               set_bit(8 + i, &kit->input_events);
-                       }
-               }
-       }
-       else if (kit->ifkit->inputs == 8) {
-               for (i=0; i < 8; i++) {
-                       level = (buffer[1] >> i) & 1;
-                       if (kit->inputs[i] != level) {
-                               kit->inputs[i] = level;
-                               set_bit(i, &kit->input_events);
-                       }
-               }
-       }
-
-       /* analog inputs */
-       if (kit->ifkit->sensors) {
-               sensor = (buffer[0] & 1) ? 4 : 0;
-
-               level = buffer[2] + (buffer[3] & 0x0f) * 256;
-               if (level != kit->sensors[sensor]) {
-                       kit->sensors[sensor] = level;
-                       set_bit(sensor, &kit->sensor_events);
-               }
-               sensor++;
-               level = buffer[4] + (buffer[3] & 0xf0) * 16;
-               if (level != kit->sensors[sensor]) {
-                       kit->sensors[sensor] = level;
-                       set_bit(sensor, &kit->sensor_events);
-               }
-               sensor++;
-               level = buffer[5] + (buffer[6] & 0x0f) * 256;
-               if (level != kit->sensors[sensor]) {
-                       kit->sensors[sensor] = level;
-                       set_bit(sensor, &kit->sensor_events);
-               }
-               sensor++;
-               level = buffer[7] + (buffer[6] & 0xf0) * 16;
-               if (level != kit->sensors[sensor]) {
-                       kit->sensors[sensor] = level;
-                       set_bit(sensor, &kit->sensor_events);
-               }
-       }
-
-       if (kit->input_events || kit->sensor_events)
-               schedule_delayed_work(&kit->do_notify, 0);
-
-resubmit:
-       retval = usb_submit_urb(urb, GFP_ATOMIC);
-       if (retval)
-               err("can't resubmit intr, %s-%s/interfacekit0, retval %d",
-                       kit->udev->bus->bus_name,
-                       kit->udev->devpath, retval);
-}
-
-static void do_notify(struct work_struct *work)
-{
-       struct interfacekit *kit =
-               container_of(work, struct interfacekit, do_notify.work);
-       int i;
-       char sysfs_file[8];
-
-       for (i=0; i<kit->ifkit->inputs; i++) {
-               if (test_and_clear_bit(i, &kit->input_events)) {
-                       sprintf(sysfs_file, "input%d", i + 1);
-                       sysfs_notify(&kit->dev->kobj, NULL, sysfs_file);
-               }
-       }
-
-       for (i=0; i<kit->ifkit->sensors; i++) {
-               if (test_and_clear_bit(i, &kit->sensor_events)) {
-                       sprintf(sysfs_file, "sensor%d", i + 1);
-                       sysfs_notify(&kit->dev->kobj, NULL, sysfs_file);
-               }
-       }
-}
-
-static void do_resubmit(struct work_struct *work)
-{
-       struct interfacekit *kit =
-               container_of(work, struct interfacekit, do_resubmit.work);
-       set_outputs(kit);
-}
-
-#define show_set_output(value)         \
-static ssize_t set_output##value(struct device *dev,                   \
-                                       struct device_attribute *attr,  \
-                                       const char *buf, size_t count)  \
-{                                                                      \
-       struct interfacekit *kit = dev_get_drvdata(dev);                \
-       int enable;                                                     \
-       int retval;                                                     \
-                                                                       \
-       if (sscanf(buf, "%d", &enable) < 1)                             \
-               return -EINVAL;                                         \
-                                                                       \
-       if (enable)                                                     \
-               set_bit(value - 1, &kit->outputs);                      \
-       else                                                            \
-               clear_bit(value - 1, &kit->outputs);                    \
-                                                                       \
-       retval = set_outputs(kit);                                      \
-                                                                       \
-       return retval ? retval : count;                                 \
-}                                                                      \
-                                                                       \
-static ssize_t show_output##value(struct device *dev,                  \
-                                       struct device_attribute *attr,  \
-                                       char *buf)                      \
-{                                                                      \
-       struct interfacekit *kit = dev_get_drvdata(dev);                \
-                                                                       \
-       return sprintf(buf, "%d\n", !!test_bit(value - 1, &kit->outputs));\
-}
-
-#define output_attr(value)                                             \
-       __ATTR(output##value, S_IWUGO | S_IRUGO,                        \
-               show_output##value, set_output##value)
-
-show_set_output(1);
-show_set_output(2);
-show_set_output(3);
-show_set_output(4);
-show_set_output(5);
-show_set_output(6);
-show_set_output(7);
-show_set_output(8);
-show_set_output(9);
-show_set_output(10);
-show_set_output(11);
-show_set_output(12);
-show_set_output(13);
-show_set_output(14);
-show_set_output(15);
-show_set_output(16);
-
-static struct device_attribute dev_output_attrs[] = {
-       output_attr(1), output_attr(2), output_attr(3), output_attr(4),
-       output_attr(5), output_attr(6), output_attr(7), output_attr(8),
-       output_attr(9), output_attr(10), output_attr(11), output_attr(12),
-       output_attr(13), output_attr(14), output_attr(15), output_attr(16)
-};
-
-#define show_input(value)      \
-static ssize_t show_input##value(struct device *dev,                   \
-                       struct device_attribute *attr, char *buf)       \
-{                                                                      \
-       struct interfacekit *kit = dev_get_drvdata(dev);                \
-                                                                       \
-       return sprintf(buf, "%d\n", (int)kit->inputs[value - 1]);       \
-}
-
-#define input_attr(value)                                              \
-       __ATTR(input##value, S_IRUGO, show_input##value, NULL)
-
-show_input(1);
-show_input(2);
-show_input(3);
-show_input(4);
-show_input(5);
-show_input(6);
-show_input(7);
-show_input(8);
-show_input(9);
-show_input(10);
-show_input(11);
-show_input(12);
-show_input(13);
-show_input(14);
-show_input(15);
-show_input(16);
-
-static struct device_attribute dev_input_attrs[] = {
-       input_attr(1), input_attr(2), input_attr(3), input_attr(4),
-       input_attr(5), input_attr(6), input_attr(7), input_attr(8),
-       input_attr(9), input_attr(10), input_attr(11), input_attr(12),
-       input_attr(13), input_attr(14), input_attr(15), input_attr(16)
-};
-
-#define show_sensor(value)     \
-static ssize_t show_sensor##value(struct device *dev,                  \
-                                       struct device_attribute *attr,  \
-                                       char *buf)                      \
-{                                                                      \
-       struct interfacekit *kit = dev_get_drvdata(dev);                \
-                                                                       \
-       return sprintf(buf, "%d\n", (int)kit->sensors[value - 1]);      \
-}
-
-#define sensor_attr(value)                                             \
-       __ATTR(sensor##value, S_IRUGO, show_sensor##value, NULL)
-
-show_sensor(1);
-show_sensor(2);
-show_sensor(3);
-show_sensor(4);
-show_sensor(5);
-show_sensor(6);
-show_sensor(7);
-show_sensor(8);
-
-static struct device_attribute dev_sensor_attrs[] = {
-       sensor_attr(1), sensor_attr(2), sensor_attr(3), sensor_attr(4),
-       sensor_attr(5), sensor_attr(6), sensor_attr(7), sensor_attr(8)
-};
-
-static int interfacekit_probe(struct usb_interface *intf, const struct usb_device_id *id)
-{
-       struct usb_device *dev = interface_to_usbdev(intf);
-       struct usb_host_interface *interface;
-       struct usb_endpoint_descriptor *endpoint;
-       struct interfacekit *kit;
-       struct driver_interfacekit *ifkit;
-       int pipe, maxp, rc = -ENOMEM;
-       int bit, value, i;
-
-       ifkit = (struct driver_interfacekit *)id->driver_info;
-       if (!ifkit)
-               return -ENODEV;
-
-       interface = intf->cur_altsetting;
-       if (interface->desc.bNumEndpoints != 1)
-               return -ENODEV;
-
-       endpoint = &interface->endpoint[0].desc;
-       if (!usb_endpoint_dir_in(endpoint))
-               return -ENODEV;
-       /*
-        * bmAttributes
-        */
-       pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
-       maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));
-       
-       kit = kzalloc(sizeof(*kit), GFP_KERNEL);
-       if (!kit)
-               goto out;
-
-       kit->dev_no = -1;
-       kit->ifkit = ifkit;
-       kit->data = usb_buffer_alloc(dev, URB_INT_SIZE, GFP_ATOMIC, &kit->data_dma);
-       if (!kit->data)
-               goto out;
-
-       kit->irq = usb_alloc_urb(0, GFP_KERNEL);
-       if (!kit->irq)
-               goto out;
-
-       kit->udev = usb_get_dev(dev);
-       kit->intf = intf;
-       INIT_DELAYED_WORK(&kit->do_notify, do_notify);
-       INIT_DELAYED_WORK(&kit->do_resubmit, do_resubmit);
-       usb_fill_int_urb(kit->irq, kit->udev, pipe, kit->data,
-                       maxp > URB_INT_SIZE ? URB_INT_SIZE : maxp,
-                       interfacekit_irq, kit, endpoint->bInterval);
-       kit->irq->transfer_dma = kit->data_dma;
-       kit->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
-
-       usb_set_intfdata(intf, kit);
-
-        do {
-                bit = find_first_zero_bit(&device_no, sizeof(device_no));
-                value = test_and_set_bit(bit, &device_no);
-        } while(value);
-        kit->dev_no = bit;
-
-       kit->dev = device_create(phidget_class, &kit->udev->dev, MKDEV(0, 0),
-                                kit, "interfacekit%d", kit->dev_no);
-        if (IS_ERR(kit->dev)) {
-                rc = PTR_ERR(kit->dev);
-                kit->dev = NULL;
-                goto out;
-        }
-
-       if (usb_submit_urb(kit->irq, GFP_KERNEL)) {
-               rc = -EIO;
-               goto out;
-       }
-
-       for (i=0; i<ifkit->outputs; i++ ) {
-               rc = device_create_file(kit->dev, &dev_output_attrs[i]);
-               if (rc)
-                       goto out2;
-       }
-
-       for (i=0; i<ifkit->inputs; i++ ) {
-               rc = device_create_file(kit->dev, &dev_input_attrs[i]);
-               if (rc)
-                       goto out3;
-       }
-
-       for (i=0; i<ifkit->sensors; i++ ) {
-               rc = device_create_file(kit->dev, &dev_sensor_attrs[i]);
-               if (rc)
-                       goto out4;
-       }
-
-       if (ifkit->has_lcd) {
-               rc = device_create_file(kit->dev, &dev_attr_lcd);
-               if (rc)
-                       goto out4;
-
-       }
-
-       dev_info(&intf->dev, "USB PhidgetInterfaceKit %d/%d/%d attached\n",
-                       ifkit->sensors, ifkit->inputs, ifkit->outputs);
-
-       return 0;
-
-out4:
-       while (i-- > 0)
-               device_remove_file(kit->dev, &dev_sensor_attrs[i]);
-
-       i = ifkit->inputs;
-out3:
-       while (i-- > 0)
-               device_remove_file(kit->dev, &dev_input_attrs[i]);
-
-       i = ifkit->outputs;
-out2:
-       while (i-- > 0)
-               device_remove_file(kit->dev, &dev_output_attrs[i]);
-out:
-       if (kit) {
-               usb_free_urb(kit->irq);
-               if (kit->data)
-                       usb_buffer_free(dev, URB_INT_SIZE, kit->data, kit->data_dma);
-               if (kit->dev)
-                       device_unregister(kit->dev);
-               if (kit->dev_no >= 0)
-                       clear_bit(kit->dev_no, &device_no);
-
-               kfree(kit);
-       }
-
-       return rc;
-}
-
-static void interfacekit_disconnect(struct usb_interface *interface)
-{
-       struct interfacekit *kit;
-       int i;
-
-       kit = usb_get_intfdata(interface);
-       usb_set_intfdata(interface, NULL);
-       if (!kit)
-               return;
-
-       usb_kill_urb(kit->irq);
-       usb_free_urb(kit->irq);
-       usb_buffer_free(kit->udev, URB_INT_SIZE, kit->data, kit->data_dma);
-
-       cancel_delayed_work(&kit->do_notify);
-       cancel_delayed_work(&kit->do_resubmit);
-
-       for (i=0; i<kit->ifkit->outputs; i++)
-               device_remove_file(kit->dev, &dev_output_attrs[i]);
-
-       for (i=0; i<kit->ifkit->inputs; i++)
-               device_remove_file(kit->dev, &dev_input_attrs[i]);
-
-       for (i=0; i<kit->ifkit->sensors; i++)
-               device_remove_file(kit->dev, &dev_sensor_attrs[i]);
-
-       if (kit->ifkit->has_lcd) {
-               device_remove_file(kit->dev, &dev_attr_lcd);
-               remove_lcd_files(kit);
-       }
-
-       device_unregister(kit->dev);
-
-       dev_info(&interface->dev, "USB PhidgetInterfaceKit %d/%d/%d detached\n",
-               kit->ifkit->sensors, kit->ifkit->inputs, kit->ifkit->outputs);
-
-       usb_put_dev(kit->udev);
-       clear_bit(kit->dev_no, &device_no);
-
-       kfree(kit);
-}
-
-static struct usb_driver interfacekit_driver = {
-       .name = "phidgetkit",
-       .probe = interfacekit_probe,
-       .disconnect = interfacekit_disconnect,
-       .id_table = id_table
-};
-
-static int __init interfacekit_init(void)
-{
-       int retval = 0;
-
-       retval = usb_register(&interfacekit_driver);
-       if (retval)
-               err("usb_register failed. Error number %d", retval);
-
-       return retval;
-}
-
-static void __exit interfacekit_exit(void)
-{
-       usb_deregister(&interfacekit_driver);
-}
-
-module_init(interfacekit_init);
-module_exit(interfacekit_exit);
-
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE("GPL");
diff --git a/drivers/usb/misc/phidgetmotorcontrol.c b/drivers/usb/misc/phidgetmotorcontrol.c
deleted file mode 100644 (file)
index 38088b4..0000000
+++ /dev/null
@@ -1,465 +0,0 @@
-/*
- * USB Phidget MotorControl driver
- *
- * Copyright (C) 2006  Sean Young <sean@mess.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.
- */
-
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/usb.h>
-
-#include "phidget.h"
-
-#define DRIVER_AUTHOR "Sean Young <sean@mess.org>"
-#define DRIVER_DESC "USB PhidgetMotorControl Driver"
-
-#define USB_VENDOR_ID_GLAB             0x06c2
-#define USB_DEVICE_ID_MOTORCONTROL     0x0058
-
-#define URB_INT_SIZE                   8
-
-static unsigned long device_no;
-
-struct motorcontrol {
-       struct usb_device *udev;
-       struct usb_interface *intf;
-       struct device *dev;
-       int dev_no;
-       u8 inputs[4];
-       s8 desired_speed[2];
-       s8 speed[2];
-       s16 _current[2];
-       s8 acceleration[2];
-       struct urb *irq;
-       unsigned char *data;
-       dma_addr_t data_dma;
-
-       struct delayed_work do_notify;
-       unsigned long input_events;
-       unsigned long speed_events;
-       unsigned long exceed_events;
-};
-
-static struct usb_device_id id_table[] = {
-       { USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_MOTORCONTROL) },
-       {}
-};
-MODULE_DEVICE_TABLE(usb, id_table);
-
-static int set_motor(struct motorcontrol *mc, int motor)
-{
-       u8 *buffer;
-       int speed, speed2, acceleration;
-       int retval;
-
-       buffer = kzalloc(8, GFP_KERNEL);
-       if (!buffer) {
-               dev_err(&mc->intf->dev, "%s - out of memory\n", __func__);
-               return -ENOMEM;
-       }
-
-       acceleration = mc->acceleration[motor] * 10;
-       /* -127 <= speed <= 127 */
-       speed = (mc->desired_speed[motor] * 127) / 100;
-       /* -0x7300 <= speed2 <= 0x7300 */
-       speed2 = (mc->desired_speed[motor] * 230 * 128) / 100;
-
-       buffer[0] = motor;
-       buffer[1] = speed;
-       buffer[2] = acceleration >> 8;
-       buffer[3] = acceleration;
-       buffer[4] = speed2 >> 8;
-       buffer[5] = speed2;
-
-       retval = usb_control_msg(mc->udev,
-                        usb_sndctrlpipe(mc->udev, 0),
-                        0x09, 0x21, 0x0200, 0x0000, buffer, 8, 2000);
-
-       if (retval != 8)
-               dev_err(&mc->intf->dev, "usb_control_msg returned %d\n",
-                               retval);
-       kfree(buffer);
-
-       return retval < 0 ? retval : 0;
-}
-
-static void motorcontrol_irq(struct urb *urb)
-{
-       struct motorcontrol *mc = urb->context;
-       unsigned char *buffer = mc->data;
-       int i, level;
-       int retval;
-       int status = urb->status;;
-
-       switch (status) {
-       case 0:                 /* success */
-               break;
-       case -ECONNRESET:       /* unlink */
-       case -ENOENT:
-       case -ESHUTDOWN:
-               return;
-       /* -EPIPE:  should clear the halt */
-       default:                /* error */
-               goto resubmit;
-       }
-
-       /* digital inputs */
-       for (i=0; i<4; i++) {
-               level = (buffer[0] >> i) & 1;
-               if (mc->inputs[i] != level) {
-                       mc->inputs[i] = level;
-                       set_bit(i, &mc->input_events);
-               }
-       }
-
-       /* motor speed */
-       if (buffer[2] == 0) {
-               for (i=0; i<2; i++) {
-               level = ((s8)buffer[4+i]) * 100 / 127;
-                       if (mc->speed[i] != level) {
-                               mc->speed[i] = level;
-                               set_bit(i, &mc->speed_events);
-                       }
-               }
-       } else {
-               int index = buffer[3] & 1;
-
-               level = ((s8)buffer[4] << 8) | buffer[5];
-               level = level * 100 / 29440;
-               if (mc->speed[index] != level) {
-                       mc->speed[index] = level;
-                       set_bit(index, &mc->speed_events);
-               }
-
-               level = ((s8)buffer[6] << 8) | buffer[7];
-               mc->_current[index] = level * 100 / 1572;
-       }
-
-       if (buffer[1] & 1)
-               set_bit(0, &mc->exceed_events);
-
-       if (buffer[1] & 2)
-               set_bit(1, &mc->exceed_events);
-
-       if (mc->input_events || mc->exceed_events || mc->speed_events)
-               schedule_delayed_work(&mc->do_notify, 0);
-
-resubmit:
-       retval = usb_submit_urb(urb, GFP_ATOMIC);
-       if (retval)
-               dev_err(&mc->intf->dev,
-                       "can't resubmit intr, %s-%s/motorcontrol0, retval %d\n",
-                       mc->udev->bus->bus_name,
-                       mc->udev->devpath, retval);
-}
-
-static void do_notify(struct work_struct *work)
-{
-       struct motorcontrol *mc =
-               container_of(work, struct motorcontrol, do_notify.work);
-       int i;
-       char sysfs_file[8];
-
-       for (i=0; i<4; i++) {
-               if (test_and_clear_bit(i, &mc->input_events)) {
-                       sprintf(sysfs_file, "input%d", i);
-                       sysfs_notify(&mc->dev->kobj, NULL, sysfs_file);
-               }
-       }
-
-       for (i=0; i<2; i++) {
-               if (test_and_clear_bit(i, &mc->speed_events)) {
-                       sprintf(sysfs_file, "speed%d", i);
-                       sysfs_notify(&mc->dev->kobj, NULL, sysfs_file);
-               }
-       }
-
-       for (i=0; i<2; i++) {
-               if (test_and_clear_bit(i, &mc->exceed_events))
-                       dev_warn(&mc->intf->dev,
-                               "motor #%d exceeds 1.5 Amp current limit\n", i);
-       }
-}
-
-#define show_set_speed(value)          \
-static ssize_t set_speed##value(struct device *dev,                    \
-                                       struct device_attribute *attr,  \
-                                       const char *buf, size_t count)  \
-{                                                                      \
-       struct motorcontrol *mc = dev_get_drvdata(dev);                 \
-       int speed;                                                      \
-       int retval;                                                     \
-                                                                       \
-       if (sscanf(buf, "%d", &speed) < 1)                              \
-               return -EINVAL;                                         \
-                                                                       \
-       if (speed < -100 || speed > 100)                                \
-               return -EINVAL;                                         \
-                                                                       \
-       mc->desired_speed[value] = speed;                               \
-                                                                       \
-       retval = set_motor(mc, value);                                  \
-                                                                       \
-       return retval ? retval : count;                                 \
-}                                                                      \
-                                                                       \
-static ssize_t show_speed##value(struct device *dev,                   \
-                                       struct device_attribute *attr,  \
-                                       char *buf)                      \
-{                                                                      \
-       struct motorcontrol *mc = dev_get_drvdata(dev);                 \
-                                                                       \
-       return sprintf(buf, "%d\n", mc->speed[value]);                  \
-}
-
-#define speed_attr(value)                                              \
-       __ATTR(speed##value, S_IWUGO | S_IRUGO,                         \
-               show_speed##value, set_speed##value)
-
-show_set_speed(0);
-show_set_speed(1);
-
-#define show_set_acceleration(value)           \
-static ssize_t set_acceleration##value(struct device *dev,             \
-                                       struct device_attribute *attr,  \
-                                       const char *buf, size_t count)  \
-{                                                                      \
-       struct motorcontrol *mc = dev_get_drvdata(dev);                 \
-       int acceleration;                                               \
-       int retval;                                                     \
-                                                                       \
-       if (sscanf(buf, "%d", &acceleration) < 1)                       \
-               return -EINVAL;                                         \
-                                                                       \
-       if (acceleration < 0 || acceleration > 100)                     \
-               return -EINVAL;                                         \
-                                                                       \
-       mc->acceleration[value] = acceleration;                         \
-                                                                       \
-       retval = set_motor(mc, value);                                  \
-                                                                       \
-       return retval ? retval : count;                                 \
-}                                                                      \
-                                                                       \
-static ssize_t show_acceleration##value(struct device *dev,            \
-                                       struct device_attribute *attr,  \
-                                                       char *buf)      \
-{                                                                      \
-       struct motorcontrol *mc = dev_get_drvdata(dev);                 \
-                                                                       \
-       return sprintf(buf, "%d\n", mc->acceleration[value]);           \
-}
-
-#define acceleration_attr(value)       \
-       __ATTR(acceleration##value, S_IWUGO | S_IRUGO,                  \
-               show_acceleration##value, set_acceleration##value)
-
-show_set_acceleration(0);
-show_set_acceleration(1);
-
-#define show_current(value)    \
-static ssize_t show_current##value(struct device *dev,                 \
-                                       struct device_attribute *attr,  \
-                                       char *buf)                      \
-{                                                                      \
-       struct motorcontrol *mc = dev_get_drvdata(dev);                 \
-                                                                       \
-       return sprintf(buf, "%dmA\n", (int)mc->_current[value]);        \
-}
-
-#define current_attr(value)    \
-       __ATTR(current##value, S_IRUGO, show_current##value, NULL)
-
-show_current(0);
-show_current(1);
-
-#define show_input(value)      \
-static ssize_t show_input##value(struct device *dev,                   \
-                                       struct device_attribute *attr,  \
-                                       char *buf)                      \
-{                                                                      \
-       struct motorcontrol *mc = dev_get_drvdata(dev);                 \
-                                                                       \
-       return sprintf(buf, "%d\n", (int)mc->inputs[value]);            \
-}
-
-#define input_attr(value)      \
-       __ATTR(input##value, S_IRUGO, show_input##value, NULL)
-
-show_input(0);
-show_input(1);
-show_input(2);
-show_input(3);
-
-static struct device_attribute dev_attrs[] = {
-       input_attr(0),
-       input_attr(1),
-       input_attr(2),
-       input_attr(3),
-       speed_attr(0),
-       speed_attr(1),
-       acceleration_attr(0),
-       acceleration_attr(1),
-       current_attr(0),
-       current_attr(1)
-};
-
-static int motorcontrol_probe(struct usb_interface *intf, const struct usb_device_id *id)
-{
-       struct usb_device *dev = interface_to_usbdev(intf);
-       struct usb_host_interface *interface;
-       struct usb_endpoint_descriptor *endpoint;
-       struct motorcontrol *mc;
-       int pipe, maxp, rc = -ENOMEM;
-       int bit, value, i;
-
-       interface = intf->cur_altsetting;
-       if (interface->desc.bNumEndpoints != 1)
-               return -ENODEV;
-
-       endpoint = &interface->endpoint[0].desc;
-       if (!usb_endpoint_dir_in(endpoint))
-               return -ENODEV;
-
-       /*
-        * bmAttributes
-        */
-       pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
-       maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));
-
-       mc = kzalloc(sizeof(*mc), GFP_KERNEL);
-       if (!mc)
-               goto out;
-
-       mc->dev_no = -1;
-       mc->data = usb_buffer_alloc(dev, URB_INT_SIZE, GFP_ATOMIC, &mc->data_dma);
-       if (!mc->data)
-               goto out;
-
-       mc->irq = usb_alloc_urb(0, GFP_KERNEL);
-       if (!mc->irq)
-               goto out;
-
-       mc->udev = usb_get_dev(dev);
-       mc->intf = intf;
-       mc->acceleration[0] = mc->acceleration[1] = 10;
-       INIT_DELAYED_WORK(&mc->do_notify, do_notify);
-       usb_fill_int_urb(mc->irq, mc->udev, pipe, mc->data,
-                       maxp > URB_INT_SIZE ? URB_INT_SIZE : maxp,
-                       motorcontrol_irq, mc, endpoint->bInterval);
-       mc->irq->transfer_dma = mc->data_dma;
-       mc->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
-
-       usb_set_intfdata(intf, mc);
-
-       do {
-               bit = find_first_zero_bit(&device_no, sizeof(device_no));
-               value = test_and_set_bit(bit, &device_no);
-       } while(value);
-       mc->dev_no = bit;
-
-       mc->dev = device_create(phidget_class, &mc->udev->dev, MKDEV(0, 0), mc,
-                               "motorcontrol%d", mc->dev_no);
-       if (IS_ERR(mc->dev)) {
-               rc = PTR_ERR(mc->dev);
-               mc->dev = NULL;
-               goto out;
-       }
-
-       if (usb_submit_urb(mc->irq, GFP_KERNEL)) {
-               rc = -EIO;
-               goto out;
-       }
-
-       for (i=0; i<ARRAY_SIZE(dev_attrs); i++) {
-               rc = device_create_file(mc->dev, &dev_attrs[i]);
-               if (rc)
-                       goto out2;
-       }
-
-       dev_info(&intf->dev, "USB PhidgetMotorControl attached\n");
-
-       return 0;
-out2:
-       while (i-- > 0)
-               device_remove_file(mc->dev, &dev_attrs[i]);
-out:
-       if (mc) {
-               usb_free_urb(mc->irq);
-               if (mc->data)
-                       usb_buffer_free(dev, URB_INT_SIZE, mc->data, mc->data_dma);
-               if (mc->dev)
-                       device_unregister(mc->dev);
-               if (mc->dev_no >= 0)
-                       clear_bit(mc->dev_no, &device_no);
-
-               kfree(mc);
-       }
-
-       return rc;
-}
-
-static void motorcontrol_disconnect(struct usb_interface *interface)
-{
-       struct motorcontrol *mc;
-       int i;
-
-       mc = usb_get_intfdata(interface);
-       usb_set_intfdata(interface, NULL);
-       if (!mc)
-               return;
-
-       usb_kill_urb(mc->irq);
-       usb_free_urb(mc->irq);
-       usb_buffer_free(mc->udev, URB_INT_SIZE, mc->data, mc->data_dma);
-
-       cancel_delayed_work(&mc->do_notify);
-
-       for (i=0; i<ARRAY_SIZE(dev_attrs); i++)
-               device_remove_file(mc->dev, &dev_attrs[i]);
-
-       device_unregister(mc->dev);
-
-       usb_put_dev(mc->udev);
-       clear_bit(mc->dev_no, &device_no);
-       kfree(mc);
-
-       dev_info(&interface->dev, "USB PhidgetMotorControl detached\n");
-}
-
-static struct usb_driver motorcontrol_driver = {
-       .name = "phidgetmotorcontrol",
-       .probe = motorcontrol_probe,
-       .disconnect = motorcontrol_disconnect,
-       .id_table = id_table
-};
-
-static int __init motorcontrol_init(void)
-{
-       int retval = 0;
-
-       retval = usb_register(&motorcontrol_driver);
-       if (retval)
-               err("usb_register failed. Error number %d", retval);
-
-       return retval;
-}
-
-static void __exit motorcontrol_exit(void)
-{
-       usb_deregister(&motorcontrol_driver);
-}
-
-module_init(motorcontrol_init);
-module_exit(motorcontrol_exit);
-
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE("GPL");
diff --git a/drivers/usb/misc/phidgetservo.c b/drivers/usb/misc/phidgetservo.c
deleted file mode 100644 (file)
index bef6fe1..0000000
+++ /dev/null
@@ -1,375 +0,0 @@
-/*
- * USB PhidgetServo driver 1.0
- *
- * Copyright (C) 2004, 2006 Sean Young <sean@mess.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 is a driver for the USB PhidgetServo version 2.0 and 3.0 servo 
- * controllers available at: http://www.phidgets.com/ 
- *
- * Note that the driver takes input as: degrees.minutes
- *
- * CAUTION: Generally you should use 0 < degrees < 180 as anything else
- * is probably beyond the range of your servo and may damage it.
- */
-
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/usb.h>
-
-#include "phidget.h"
-
-#define DRIVER_AUTHOR "Sean Young <sean@mess.org>"
-#define DRIVER_DESC "USB PhidgetServo Driver"
-
-#define VENDOR_ID_GLAB                         0x06c2
-#define DEVICE_ID_GLAB_PHIDGETSERVO_QUAD       0x0038
-#define DEVICE_ID_GLAB_PHIDGETSERVO_UNI                0x0039
-
-#define VENDOR_ID_WISEGROUP                    0x0925
-#define VENDOR_ID_WISEGROUP_PHIDGETSERVO_QUAD  0x8101
-#define VENDOR_ID_WISEGROUP_PHIDGETSERVO_UNI   0x8104
-
-#define SERVO_VERSION_30                       0x01
-#define SERVO_COUNT_QUAD                       0x02
-
-static struct usb_device_id id_table[] = {
-       {
-               USB_DEVICE(VENDOR_ID_GLAB, DEVICE_ID_GLAB_PHIDGETSERVO_QUAD), 
-               .driver_info = SERVO_VERSION_30 | SERVO_COUNT_QUAD 
-       },
-       {
-               USB_DEVICE(VENDOR_ID_GLAB, DEVICE_ID_GLAB_PHIDGETSERVO_UNI),
-               .driver_info = SERVO_VERSION_30 
-       },
-       {
-               USB_DEVICE(VENDOR_ID_WISEGROUP, 
-                               VENDOR_ID_WISEGROUP_PHIDGETSERVO_QUAD),
-               .driver_info = SERVO_COUNT_QUAD 
-       },
-       {
-               USB_DEVICE(VENDOR_ID_WISEGROUP, 
-                               VENDOR_ID_WISEGROUP_PHIDGETSERVO_UNI),
-               .driver_info = 0
-       },
-       {}
-};
-
-MODULE_DEVICE_TABLE(usb, id_table);
-
-static int unsigned long device_no;
-
-struct phidget_servo {
-       struct usb_device *udev;
-       struct device *dev;
-       int dev_no;
-       ulong type;
-       int pulse[4];
-       int degrees[4];
-       int minutes[4];
-};
-
-static int
-change_position_v30(struct phidget_servo *servo, int servo_no, int degrees, 
-                                                               int minutes)
-{
-       int retval;
-       unsigned char *buffer;
-
-       if (degrees < -23 || degrees > 362)
-               return -EINVAL;
-
-       buffer = kmalloc(6, GFP_KERNEL);
-       if (!buffer) {
-               dev_err(&servo->udev->dev, "%s - out of memory\n",
-                       __func__);
-               return -ENOMEM;
-       }
-
-       /*
-        * pulse = 0 - 4095
-        * angle = 0 - 180 degrees
-        *
-        * pulse = angle * 10.6 + 243.8 
-        */
-       servo->pulse[servo_no] = ((degrees*60 + minutes)*106 + 2438*60)/600;    
-       servo->degrees[servo_no]= degrees;
-       servo->minutes[servo_no]= minutes;      
-
-       /* 
-        * The PhidgetServo v3.0 is controlled by sending 6 bytes,
-        * 4 * 12 bits for each servo.
-        *
-        * low = lower 8 bits pulse
-        * high = higher 4 bits pulse
-        *
-        * offset     bits
-        * +---+-----------------+
-        * | 0 |      low 0      |
-        * +---+--------+--------+
-        * | 1 | high 1 | high 0 |
-        * +---+--------+--------+
-        * | 2 |      low 1      |
-        * +---+-----------------+
-        * | 3 |      low 2      |
-        * +---+--------+--------+
-        * | 4 | high 3 | high 2 |
-        * +---+--------+--------+
-        * | 5 |      low 3      |
-        * +---+-----------------+
-        */
-
-       buffer[0] = servo->pulse[0] & 0xff;
-       buffer[1] = (servo->pulse[0] >> 8 & 0x0f)
-           | (servo->pulse[1] >> 4 & 0xf0);
-       buffer[2] = servo->pulse[1] & 0xff;
-       buffer[3] = servo->pulse[2] & 0xff;
-       buffer[4] = (servo->pulse[2] >> 8 & 0x0f)
-           | (servo->pulse[3] >> 4 & 0xf0);
-       buffer[5] = servo->pulse[3] & 0xff;
-
-       dev_dbg(&servo->udev->dev,
-               "data: %02x %02x %02x %02x %02x %02x\n",
-               buffer[0], buffer[1], buffer[2],
-               buffer[3], buffer[4], buffer[5]);
-
-       retval = usb_control_msg(servo->udev,
-                                usb_sndctrlpipe(servo->udev, 0),
-                                0x09, 0x21, 0x0200, 0x0000, buffer, 6, 2000);
-
-       kfree(buffer);
-
-       return retval;
-}
-
-static int
-change_position_v20(struct phidget_servo *servo, int servo_no, int degrees,
-                                                               int minutes)
-{
-       int retval;
-       unsigned char *buffer;
-
-       if (degrees < -23 || degrees > 278)
-               return -EINVAL;
-
-       buffer = kmalloc(2, GFP_KERNEL);
-       if (!buffer) {
-               dev_err(&servo->udev->dev, "%s - out of memory\n",
-                       __func__);
-               return -ENOMEM;
-       }
-
-       /*
-        * angle = 0 - 180 degrees
-        * pulse = angle + 23
-        */
-       servo->pulse[servo_no]= degrees + 23;
-       servo->degrees[servo_no]= degrees;
-       servo->minutes[servo_no]= 0;
-
-       /*
-        * The PhidgetServo v2.0 is controlled by sending two bytes. The
-        * first byte is the servo number xor'ed with 2:
-        *
-        * servo 0 = 2
-        * servo 1 = 3
-        * servo 2 = 0
-        * servo 3 = 1
-        *
-        * The second byte is the position.
-        */
-
-       buffer[0] = servo_no ^ 2;
-       buffer[1] = servo->pulse[servo_no];
-
-       dev_dbg(&servo->udev->dev, "data: %02x %02x\n", buffer[0], buffer[1]);
-
-       retval = usb_control_msg(servo->udev,
-                                usb_sndctrlpipe(servo->udev, 0),
-                                0x09, 0x21, 0x0200, 0x0000, buffer, 2, 2000);
-
-       kfree(buffer);
-
-       return retval;
-}
-
-#define show_set(value)        \
-static ssize_t set_servo##value (struct device *dev,                   \
-                                       struct device_attribute *attr,  \
-                                       const char *buf, size_t count)  \
-{                                                                      \
-       int degrees, minutes, retval;                                   \
-       struct phidget_servo *servo = dev_get_drvdata(dev);             \
-                                                                       \
-       minutes = 0;                                                    \
-       /* must at least convert degrees */                             \
-       if (sscanf(buf, "%d.%d", &degrees, &minutes) < 1) {             \
-               return -EINVAL;                                         \
-       }                                                               \
-                                                                       \
-       if (minutes < 0 || minutes > 59)                                \
-               return -EINVAL;                                         \
-                                                                       \
-       if (servo->type & SERVO_VERSION_30)                             \
-               retval = change_position_v30(servo, value, degrees,     \
-                                                       minutes);       \
-       else                                                            \
-               retval = change_position_v20(servo, value, degrees,     \
-                                                       minutes);       \
-                                                                       \
-       return retval < 0 ? retval : count;                             \
-}                                                                      \
-                                                                       \
-static ssize_t show_servo##value (struct device *dev,                  \
-                                       struct device_attribute *attr,  \
-                                       char *buf)                      \
-{                                                                      \
-       struct phidget_servo *servo = dev_get_drvdata(dev);             \
-                                                                       \
-       return sprintf(buf, "%d.%02d\n", servo->degrees[value],         \
-                               servo->minutes[value]);                 \
-}
-
-#define servo_attr(value)                                              \
-       __ATTR(servo##value, S_IWUGO | S_IRUGO,                         \
-               show_servo##value, set_servo##value)
-show_set(0);
-show_set(1);
-show_set(2);
-show_set(3);
-
-static struct device_attribute dev_attrs[] = {
-       servo_attr(0), servo_attr(1), servo_attr(2), servo_attr(3)
-};
-
-static int
-servo_probe(struct usb_interface *interface, const struct usb_device_id *id)
-{
-       struct usb_device *udev = interface_to_usbdev(interface);
-       struct phidget_servo *dev;
-       int bit, value, rc;
-       int servo_count, i;
-
-       dev = kzalloc(sizeof (struct phidget_servo), GFP_KERNEL);
-       if (dev == NULL) {
-               dev_err(&interface->dev, "%s - out of memory\n", __func__);
-               rc = -ENOMEM;
-               goto out;
-       }
-
-       dev->udev = usb_get_dev(udev);
-       dev->type = id->driver_info;
-       dev->dev_no = -1;
-       usb_set_intfdata(interface, dev);
-
-        do {
-                bit = find_first_zero_bit(&device_no, sizeof(device_no));
-                value = test_and_set_bit(bit, &device_no);
-        } while (value);
-       dev->dev_no = bit;
-
-       dev->dev = device_create(phidget_class, &dev->udev->dev, MKDEV(0, 0),
-                                dev, "servo%d", dev->dev_no);
-       if (IS_ERR(dev->dev)) {
-               rc = PTR_ERR(dev->dev);
-               dev->dev = NULL;
-               goto out;
-       }
-
-       servo_count = dev->type & SERVO_COUNT_QUAD ? 4 : 1;
-
-       for (i=0; i<servo_count; i++) {
-               rc = device_create_file(dev->dev, &dev_attrs[i]);
-               if (rc)
-                       goto out2;
-       }
-
-       dev_info(&interface->dev, "USB %d-Motor PhidgetServo v%d.0 attached\n",
-               servo_count, dev->type & SERVO_VERSION_30 ? 3 : 2);
-
-       if (!(dev->type & SERVO_VERSION_30))
-               dev_info(&interface->dev,
-                        "WARNING: v2.0 not tested! Please report if it works.\n");
-
-       return 0;
-out2:
-       while (i-- > 0)
-               device_remove_file(dev->dev, &dev_attrs[i]);
-out:
-       if (dev) {
-               if (dev->dev)
-                       device_unregister(dev->dev);
-               if (dev->dev_no >= 0)
-                       clear_bit(dev->dev_no, &device_no);
-
-               kfree(dev);
-       }
-
-       return rc;
-}
-
-static void
-servo_disconnect(struct usb_interface *interface)
-{
-       struct phidget_servo *dev;
-       int servo_count, i;
-
-       dev = usb_get_intfdata(interface);
-       usb_set_intfdata(interface, NULL);
-
-       if (!dev)
-               return;
-
-       servo_count = dev->type & SERVO_COUNT_QUAD ? 4 : 1;
-
-       for (i=0; i<servo_count; i++)
-               device_remove_file(dev->dev, &dev_attrs[i]);
-
-       device_unregister(dev->dev);
-       usb_put_dev(dev->udev);
-
-       dev_info(&interface->dev, "USB %d-Motor PhidgetServo v%d.0 detached\n",
-               servo_count, dev->type & SERVO_VERSION_30 ? 3 : 2);
-
-       clear_bit(dev->dev_no, &device_no);
-       kfree(dev);
-}
-
-static struct usb_driver servo_driver = {
-       .name = "phidgetservo",
-       .probe = servo_probe,
-       .disconnect = servo_disconnect,
-       .id_table = id_table
-};
-
-static int __init
-phidget_servo_init(void)
-{
-       int retval;
-
-       retval = usb_register(&servo_driver);
-       if (retval)
-               err("usb_register failed. Error number %d", retval);
-
-       return retval;
-}
-
-static void __exit
-phidget_servo_exit(void)
-{
-       usb_deregister(&servo_driver);
-}
-
-module_init(phidget_servo_init);
-module_exit(phidget_servo_exit);
-
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE("GPL");
index 4cf27c72423e13e2187a37c973e755f2c21b9948..f8d9045d668a15659fadf2af3fecf374623402f5 100644 (file)
 #define MON_IOCX_GET   _IOW(MON_IOC_MAGIC, 6, struct mon_bin_get)
 #define MON_IOCX_MFETCH _IOWR(MON_IOC_MAGIC, 7, struct mon_bin_mfetch)
 #define MON_IOCH_MFLUSH _IO(MON_IOC_MAGIC, 8)
+/* #9 was MON_IOCT_SETAPI */
+#define MON_IOCX_GETX   _IOW(MON_IOC_MAGIC, 10, struct mon_bin_get)
 
 #ifdef CONFIG_COMPAT
 #define MON_IOCX_GET32 _IOW(MON_IOC_MAGIC, 6, struct mon_bin_get32)
 #define MON_IOCX_MFETCH32 _IOWR(MON_IOC_MAGIC, 7, struct mon_bin_mfetch32)
+#define MON_IOCX_GETX32   _IOW(MON_IOC_MAGIC, 10, struct mon_bin_get32)
 #endif
 
 /*
@@ -92,7 +95,29 @@ struct mon_bin_hdr {
        int status;
        unsigned int len_urb;   /* Length of data (submitted or actual) */
        unsigned int len_cap;   /* Delivered length */
-       unsigned char setup[SETUP_LEN]; /* Only for Control S-type */
+       union {
+               unsigned char setup[SETUP_LEN]; /* Only for Control S-type */
+               struct iso_rec {
+                       int error_count;
+                       int numdesc;
+               } iso;
+       } s;
+       int interval;
+       int start_frame;
+       unsigned int xfer_flags;
+       unsigned int ndesc;     /* Actual number of ISO descriptors */
+};
+
+/*
+ * ISO vector, packed into the head of data stream.
+ * This has to take 16 bytes to make sure that the end of buffer
+ * wrap is not happening in the middle of a descriptor.
+ */
+struct mon_bin_isodesc {
+       int          iso_status;
+       unsigned int iso_off;
+       unsigned int iso_len;
+       u32 _pad;
 };
 
 /* per file statistic */
@@ -102,7 +127,7 @@ struct mon_bin_stats {
 };
 
 struct mon_bin_get {
-       struct mon_bin_hdr __user *hdr; /* Only 48 bytes, not 64. */
+       struct mon_bin_hdr __user *hdr; /* Can be 48 bytes or 64. */
        void __user *data;
        size_t alloc;           /* Length of data (can be zero) */
 };
@@ -131,6 +156,11 @@ struct mon_bin_mfetch32 {
 #define PKT_ALIGN   64
 #define PKT_SIZE    64
 
+#define PKT_SZ_API0 48 /* API 0 (2.6.20) size */
+#define PKT_SZ_API1 64 /* API 1 size: extra fields */
+
+#define ISODESC_MAX   128      /* Same number as usbfs allows, 2048 bytes. */
+
 /* max number of USB bus supported */
 #define MON_BIN_MAX_MINOR 128
 
@@ -360,12 +390,8 @@ static inline char mon_bin_get_setup(unsigned char *setupb,
     const struct urb *urb, char ev_type)
 {
 
-       if (!usb_endpoint_xfer_control(&urb->ep->desc) || ev_type != 'S')
-               return '-';
-
        if (urb->setup_packet == NULL)
                return 'Z';
-
        memcpy(setupb, urb->setup_packet, SETUP_LEN);
        return 0;
 }
@@ -387,6 +413,26 @@ static char mon_bin_get_data(const struct mon_reader_bin *rp,
        return 0;
 }
 
+static void mon_bin_get_isodesc(const struct mon_reader_bin *rp,
+    unsigned int offset, struct urb *urb, char ev_type, unsigned int ndesc)
+{
+       struct mon_bin_isodesc *dp;
+       struct usb_iso_packet_descriptor *fp;
+
+       fp = urb->iso_frame_desc;
+       while (ndesc-- != 0) {
+               dp = (struct mon_bin_isodesc *)
+                   (rp->b_vec[offset / CHUNK_SIZE].ptr + offset % CHUNK_SIZE);
+               dp->iso_status = fp->status;
+               dp->iso_off = fp->offset;
+               dp->iso_len = (ev_type == 'S') ? fp->length : fp->actual_length;
+               dp->_pad = 0;
+               if ((offset += sizeof(struct mon_bin_isodesc)) >= rp->b_size)
+                       offset = 0;
+               fp++;
+       }
+}
+
 static void mon_bin_event(struct mon_reader_bin *rp, struct urb *urb,
     char ev_type, int status)
 {
@@ -396,6 +442,7 @@ static void mon_bin_event(struct mon_reader_bin *rp, struct urb *urb,
        unsigned int urb_length;
        unsigned int offset;
        unsigned int length;
+       unsigned int ndesc, lendesc;
        unsigned char dir;
        struct mon_bin_hdr *ep;
        char data_tag = 0;
@@ -407,6 +454,19 @@ static void mon_bin_event(struct mon_reader_bin *rp, struct urb *urb,
        /*
         * Find the maximum allowable length, then allocate space.
         */
+       if (usb_endpoint_xfer_isoc(epd)) {
+               if (urb->number_of_packets < 0) {
+                       ndesc = 0;
+               } else if (urb->number_of_packets >= ISODESC_MAX) {
+                       ndesc = ISODESC_MAX;
+               } else {
+                       ndesc = urb->number_of_packets;
+               }
+       } else {
+               ndesc = 0;
+       }
+       lendesc = ndesc*sizeof(struct mon_bin_isodesc);
+
        urb_length = (ev_type == 'S') ?
            urb->transfer_buffer_length : urb->actual_length;
        length = urb_length;
@@ -429,10 +489,12 @@ static void mon_bin_event(struct mon_reader_bin *rp, struct urb *urb,
                dir = 0;
        }
 
-       if (rp->mmap_active)
-               offset = mon_buff_area_alloc_contiguous(rp, length + PKT_SIZE);
-       else
-               offset = mon_buff_area_alloc(rp, length + PKT_SIZE);
+       if (rp->mmap_active) {
+               offset = mon_buff_area_alloc_contiguous(rp,
+                                                length + PKT_SIZE + lendesc);
+       } else {
+               offset = mon_buff_area_alloc(rp, length + PKT_SIZE + lendesc);
+       }
        if (offset == ~0) {
                rp->cnt_lost++;
                spin_unlock_irqrestore(&rp->b_lock, flags);
@@ -456,9 +518,31 @@ static void mon_bin_event(struct mon_reader_bin *rp, struct urb *urb,
        ep->ts_usec = ts.tv_usec;
        ep->status = status;
        ep->len_urb = urb_length;
-       ep->len_cap = length;
+       ep->len_cap = length + lendesc;
+       ep->xfer_flags = urb->transfer_flags;
+
+       if (usb_endpoint_xfer_int(epd)) {
+               ep->interval = urb->interval;
+       } else if (usb_endpoint_xfer_isoc(epd)) {
+               ep->interval = urb->interval;
+               ep->start_frame = urb->start_frame;
+               ep->s.iso.error_count = urb->error_count;
+               ep->s.iso.numdesc = urb->number_of_packets;
+       }
+
+       if (usb_endpoint_xfer_control(epd) && ev_type == 'S') {
+               ep->flag_setup = mon_bin_get_setup(ep->s.setup, urb, ev_type);
+       } else {
+               ep->flag_setup = '-';
+       }
+
+       if (ndesc != 0) {
+               ep->ndesc = ndesc;
+               mon_bin_get_isodesc(rp, offset, urb, ev_type, ndesc);
+               if ((offset += lendesc) >= rp->b_size)
+                       offset -= rp->b_size;
+       }
 
-       ep->flag_setup = mon_bin_get_setup(ep->setup, urb, ev_type);
        if (length != 0) {
                ep->flag_data = mon_bin_get_data(rp, offset, urb, length);
                if (ep->flag_data != 0) {       /* Yes, it's 0x00, not '0' */
@@ -592,7 +676,8 @@ err_alloc:
  * Returns zero or error.
  */
 static int mon_bin_get_event(struct file *file, struct mon_reader_bin *rp,
-    struct mon_bin_hdr __user *hdr, void __user *data, unsigned int nbytes)
+    struct mon_bin_hdr __user *hdr, unsigned int hdrbytes,
+    void __user *data, unsigned int nbytes)
 {
        unsigned long flags;
        struct mon_bin_hdr *ep;
@@ -609,7 +694,7 @@ static int mon_bin_get_event(struct file *file, struct mon_reader_bin *rp,
 
        ep = MON_OFF2HDR(rp, rp->b_out);
 
-       if (copy_to_user(hdr, ep, sizeof(struct mon_bin_hdr))) {
+       if (copy_to_user(hdr, ep, hdrbytes)) {
                mutex_unlock(&rp->fetch_lock);
                return -EFAULT;
        }
@@ -657,6 +742,7 @@ static ssize_t mon_bin_read(struct file *file, char __user *buf,
     size_t nbytes, loff_t *ppos)
 {
        struct mon_reader_bin *rp = file->private_data;
+       unsigned int hdrbytes = PKT_SZ_API0;
        unsigned long flags;
        struct mon_bin_hdr *ep;
        unsigned int offset;
@@ -674,8 +760,8 @@ static ssize_t mon_bin_read(struct file *file, char __user *buf,
 
        ep = MON_OFF2HDR(rp, rp->b_out);
 
-       if (rp->b_read < sizeof(struct mon_bin_hdr)) {
-               step_len = min(nbytes, sizeof(struct mon_bin_hdr) - rp->b_read);
+       if (rp->b_read < hdrbytes) {
+               step_len = min(nbytes, (size_t)(hdrbytes - rp->b_read));
                ptr = ((char *)ep) + rp->b_read;
                if (step_len && copy_to_user(buf, ptr, step_len)) {
                        mutex_unlock(&rp->fetch_lock);
@@ -687,13 +773,13 @@ static ssize_t mon_bin_read(struct file *file, char __user *buf,
                done += step_len;
        }
 
-       if (rp->b_read >= sizeof(struct mon_bin_hdr)) {
+       if (rp->b_read >= hdrbytes) {
                step_len = ep->len_cap;
-               step_len -= rp->b_read - sizeof(struct mon_bin_hdr);
+               step_len -= rp->b_read - hdrbytes;
                if (step_len > nbytes)
                        step_len = nbytes;
                offset = rp->b_out + PKT_SIZE;
-               offset += rp->b_read - sizeof(struct mon_bin_hdr);
+               offset += rp->b_read - hdrbytes;
                if (offset >= rp->b_size)
                        offset -= rp->b_size;
                if (copy_from_buf(rp, offset, buf, step_len)) {
@@ -709,7 +795,7 @@ static ssize_t mon_bin_read(struct file *file, char __user *buf,
        /*
         * Check if whole packet was read, and if so, jump to the next one.
         */
-       if (rp->b_read >= sizeof(struct mon_bin_hdr) + ep->len_cap) {
+       if (rp->b_read >= hdrbytes + ep->len_cap) {
                spin_lock_irqsave(&rp->b_lock, flags);
                mon_buff_area_free(rp, PKT_SIZE + ep->len_cap);
                spin_unlock_irqrestore(&rp->b_lock, flags);
@@ -908,6 +994,7 @@ static int mon_bin_ioctl(struct inode *inode, struct file *file,
                break;
 
        case MON_IOCX_GET:
+       case MON_IOCX_GETX:
                {
                struct mon_bin_get getb;
 
@@ -917,8 +1004,9 @@ static int mon_bin_ioctl(struct inode *inode, struct file *file,
 
                if (getb.alloc > 0x10000000)    /* Want to cast to u32 */
                        return -EINVAL;
-               ret = mon_bin_get_event(file, rp,
-                         getb.hdr, getb.data, (unsigned int)getb.alloc);
+               ret = mon_bin_get_event(file, rp, getb.hdr,
+                   (cmd == MON_IOCX_GET)? PKT_SZ_API0: PKT_SZ_API1,
+                   getb.data, (unsigned int)getb.alloc);
                }
                break;
 
@@ -984,16 +1072,18 @@ static long mon_bin_compat_ioctl(struct file *file,
 
        switch (cmd) {
 
-       case MON_IOCX_GET32: {
+       case MON_IOCX_GET32:
+       case MON_IOCX_GETX32:
+               {
                struct mon_bin_get32 getb;
 
                if (copy_from_user(&getb, (void __user *)arg,
                                            sizeof(struct mon_bin_get32)))
                        return -EFAULT;
 
-               ret = mon_bin_get_event(file, rp,
-                   compat_ptr(getb.hdr32), compat_ptr(getb.data32),
-                   getb.alloc32);
+               ret = mon_bin_get_event(file, rp, compat_ptr(getb.hdr32),
+                   (cmd == MON_IOCX_GET32)? PKT_SZ_API0: PKT_SZ_API1,
+                   compat_ptr(getb.data32), getb.alloc32);
                if (ret < 0)
                        return ret;
                }
index 9985db08e7dbc19b1954d353c6440c506f464fec..b66e8544d8b90761a80a11a5a2c524284dd0711b 100644 (file)
@@ -20,8 +20,8 @@ config USB_MUSB_HDRC
          it's being used with, including the USB peripheral role,
          or the USB host role, or both.
 
-         Texas Instruments parts using this IP include DaVinci 644x,
-         OMAP 243x, OMAP 343x, and TUSB 6010.
+         Texas Instruments familiies using this IP include DaVinci
+         (35x, 644x ...), OMAP 243x, OMAP 3, and TUSB 6010.
 
          Analog Devices parts using this IP include Blackfin BF54x,
          BF525 and BF527.
@@ -40,7 +40,7 @@ config USB_MUSB_SOC
        default y if (BF54x && !BF544)
        default y if (BF52x && !BF522 && !BF523)
 
-comment "DaVinci 644x USB support"
+comment "DaVinci 35x and 644x USB support"
        depends on USB_MUSB_HDRC && ARCH_DAVINCI
 
 comment "OMAP 243x high speed USB support"
index 2dc7606f319c1e0e857e6c70a0178e0f477a5d6c..10d11ab113ab3c38b50b87172ed2a910c746e242 100644 (file)
@@ -48,6 +48,9 @@
 #include "cppi_dma.h"
 
 
+#define USB_PHY_CTRL   IO_ADDRESS(USBPHY_CTL_PADDR)
+#define DM355_DEEPSLEEP        IO_ADDRESS(DM355_DEEPSLEEP_PADDR)
+
 /* REVISIT (PM) we should be able to keep the PHY in low power mode most
  * of the time (24 MHZ oscillator and PLL off, etc) by setting POWER.D0
  * and, when in host mode, autosuspending idle root ports... PHYPLLON
 
 static inline void phy_on(void)
 {
-       /* start the on-chip PHY and its PLL */
-       __raw_writel(USBPHY_SESNDEN | USBPHY_VBDTCTEN | USBPHY_PHYPLLON,
-                       (void __force __iomem *) IO_ADDRESS(USBPHY_CTL_PADDR));
-       while ((__raw_readl((void __force __iomem *)
-                               IO_ADDRESS(USBPHY_CTL_PADDR))
-                       & USBPHY_PHYCLKGD) == 0)
+       u32     phy_ctrl = __raw_readl(USB_PHY_CTRL);
+
+       /* power everything up; start the on-chip PHY and its PLL */
+       phy_ctrl &= ~(USBPHY_OSCPDWN | USBPHY_OTGPDWN | USBPHY_PHYPDWN);
+       phy_ctrl |= USBPHY_SESNDEN | USBPHY_VBDTCTEN | USBPHY_PHYPLLON;
+       __raw_writel(phy_ctrl, USB_PHY_CTRL);
+
+       /* wait for PLL to lock before proceeding */
+       while ((__raw_readl(USB_PHY_CTRL) & USBPHY_PHYCLKGD) == 0)
                cpu_relax();
 }
 
 static inline void phy_off(void)
 {
-       /* powerdown the on-chip PHY and its oscillator */
-       __raw_writel(USBPHY_OSCPDWN | USBPHY_PHYPDWN, (void __force __iomem *)
-                       IO_ADDRESS(USBPHY_CTL_PADDR));
+       u32     phy_ctrl = __raw_readl(USB_PHY_CTRL);
+
+       /* powerdown the on-chip PHY, its PLL, and the OTG block */
+       phy_ctrl &= ~(USBPHY_SESNDEN | USBPHY_VBDTCTEN | USBPHY_PHYPLLON);
+       phy_ctrl |= USBPHY_OSCPDWN | USBPHY_OTGPDWN | USBPHY_PHYPDWN;
+       __raw_writel(phy_ctrl, USB_PHY_CTRL);
 }
 
 static int dma_off = 1;
@@ -126,10 +135,6 @@ void musb_platform_disable(struct musb *musb)
 }
 
 
-/* REVISIT it's not clear whether DaVinci can support full OTG.  */
-
-static int vbus_state = -1;
-
 #ifdef CONFIG_USB_MUSB_HDRC_HCD
 #define        portstate(stmt)         stmt
 #else
@@ -137,10 +142,19 @@ static int vbus_state = -1;
 #endif
 
 
-/* VBUS SWITCHING IS BOARD-SPECIFIC */
+/*
+ * VBUS SWITCHING IS BOARD-SPECIFIC ... at least for the DM6446 EVM,
+ * which doesn't wire DRVVBUS to the FET that switches it.  Unclear
+ * if that's a problem with the DM6446 chip or just with that board.
+ *
+ * In either case, the DM355 EVM automates DRVVBUS the normal way,
+ * when J10 is out, and TI documents it as handling OTG.
+ */
 
 #ifdef CONFIG_MACH_DAVINCI_EVM
 
+static int vbus_state = -1;
+
 /* I2C operations are always synchronous, and require a task context.
  * With unloaded systems, using the shared workqueue seems to suffice
  * to satisfy the 100msec A_WAIT_VRISE timeout...
@@ -150,12 +164,12 @@ static void evm_deferred_drvvbus(struct work_struct *ignored)
        gpio_set_value_cansleep(GPIO_nVBUS_DRV, vbus_state);
        vbus_state = !vbus_state;
 }
-static DECLARE_WORK(evm_vbus_work, evm_deferred_drvvbus);
 
 #endif /* EVM */
 
 static void davinci_source_power(struct musb *musb, int is_on, int immediate)
 {
+#ifdef CONFIG_MACH_DAVINCI_EVM
        if (is_on)
                is_on = 1;
 
@@ -163,16 +177,17 @@ static void davinci_source_power(struct musb *musb, int is_on, int immediate)
                return;
        vbus_state = !is_on;            /* 0/1 vs "-1 == unknown/init" */
 
-#ifdef CONFIG_MACH_DAVINCI_EVM
        if (machine_is_davinci_evm()) {
+               static DECLARE_WORK(evm_vbus_work, evm_deferred_drvvbus);
+
                if (immediate)
                        gpio_set_value_cansleep(GPIO_nVBUS_DRV, vbus_state);
                else
                        schedule_work(&evm_vbus_work);
        }
-#endif
        if (immediate)
                vbus_state = is_on;
+#endif
 }
 
 static void davinci_set_vbus(struct musb *musb, int is_on)
@@ -391,6 +406,17 @@ int __init musb_platform_init(struct musb *musb)
        musb->board_set_vbus = davinci_set_vbus;
        davinci_source_power(musb, 0, 1);
 
+       /* dm355 EVM swaps D+/D- for signal integrity, and
+        * is clocked from the main 24 MHz crystal.
+        */
+       if (machine_is_davinci_dm355_evm()) {
+               u32     phy_ctrl = __raw_readl(USB_PHY_CTRL);
+
+               phy_ctrl &= ~(3 << 9);
+               phy_ctrl |= USBPHY_DATAPOL;
+               __raw_writel(phy_ctrl, USB_PHY_CTRL);
+       }
+
        /* reset the controller */
        musb_writel(tibase, DAVINCI_USB_CTRL_REG, 0x1);
 
@@ -401,8 +427,7 @@ int __init musb_platform_init(struct musb *musb)
 
        /* NOTE:  irqs are in mixed mode, not bypass to pure-musb */
        pr_debug("DaVinci OTG revision %08x phy %03x control %02x\n",
-               revision, __raw_readl((void __force __iomem *)
-                               IO_ADDRESS(USBPHY_CTL_PADDR)),
+               revision, __raw_readl(USB_PHY_CTRL),
                musb_readb(tibase, DAVINCI_USB_CTRL_REG));
 
        musb->isr = davinci_interrupt;
index 7fb6238e270f41c1aecdb525fc8f4fd75e0cfd85..046c84433cadc92e6f8f7d8788520d73f91e4380 100644 (file)
  */
 
 /* Integrated highspeed/otg PHY */
-#define        USBPHY_CTL_PADDR        (DAVINCI_SYSTEM_MODULE_BASE + 0x34)
-#define        USBPHY_PHYCLKGD         (1 << 8)
-#define        USBPHY_SESNDEN          (1 << 7)        /* v(sess_end) comparator */
-#define        USBPHY_VBDTCTEN         (1 << 6)        /* v(bus) comparator */
-#define        USBPHY_PHYPLLON         (1 << 4)        /* override pll suspend */
-#define        USBPHY_CLKO1SEL         (1 << 3)
-#define        USBPHY_OSCPDWN          (1 << 2)
-#define        USBPHY_PHYPDWN          (1 << 0)
+#define USBPHY_CTL_PADDR       (DAVINCI_SYSTEM_MODULE_BASE + 0x34)
+#define USBPHY_DATAPOL         BIT(11) /* (dm355) switch D+/D- */
+#define USBPHY_PHYCLKGD                BIT(8)
+#define USBPHY_SESNDEN         BIT(7)  /* v(sess_end) comparator */
+#define USBPHY_VBDTCTEN                BIT(6)  /* v(bus) comparator */
+#define USBPHY_VBUSSENS                BIT(5)  /* (dm355,ro) is vbus > 0.5V */
+#define USBPHY_PHYPLLON                BIT(4)  /* override pll suspend */
+#define USBPHY_CLKO1SEL                BIT(3)
+#define USBPHY_OSCPDWN         BIT(2)
+#define USBPHY_OTGPDWN         BIT(1)
+#define USBPHY_PHYPDWN         BIT(0)
+
+#define DM355_DEEPSLEEP_PADDR  (DAVINCI_SYSTEM_MODULE_BASE + 0x48)
+#define DRVVBUS_FORCE          BIT(2)
+#define DRVVBUS_OVERRIDE       BIT(1)
 
 /* For now include usb OTG module registers here */
 #define DAVINCI_USB_VERSION_REG                0x00
index af77e46590065fd5b8890bd819ac20d0cc912b82..338cd1611ab3a24981676194811bebb0ef836120 100644 (file)
@@ -769,7 +769,7 @@ static irqreturn_t musb_stage2_irq(struct musb *musb, u8 int_usb,
                case OTG_STATE_A_SUSPEND:
                        usb_hcd_resume_root_hub(musb_to_hcd(musb));
                        musb_root_disconnect(musb);
-                       if (musb->a_wait_bcon != 0)
+                       if (musb->a_wait_bcon != 0 && is_otg_enabled(musb))
                                musb_platform_try_idle(musb, jiffies
                                        + msecs_to_jiffies(musb->a_wait_bcon));
                        break;
index 630946a2d9fce2db69bd9a7cd2ab68d513ade60f..efb39b5e55b5e62493dc64ea8d05ab15d10074b8 100644 (file)
@@ -331,7 +331,6 @@ struct musb {
        struct list_head        control;        /* of musb_qh */
        struct list_head        in_bulk;        /* of musb_qh */
        struct list_head        out_bulk;       /* of musb_qh */
-       struct musb_qh          *periodic[32];  /* tree of interrupt+iso */
 #endif
 
        /* called with IRQs blocked; ON/nonzero implies starting a session,
@@ -479,10 +478,11 @@ static inline void musb_configure_ep0(struct musb *musb)
 static inline int musb_read_fifosize(struct musb *musb,
                struct musb_hw_ep *hw_ep, u8 epnum)
 {
+       void *mbase = musb->mregs;
        u8 reg = 0;
 
        /* read from core using indexed model */
-       reg = musb_readb(hw_ep->regs, 0x10 + MUSB_FIFOSIZE);
+       reg = musb_readb(mbase, MUSB_EP_OFFSET(epnum, MUSB_FIFOSIZE));
        /* 0's returned when no more endpoints */
        if (!reg)
                return -ENODEV;
@@ -509,6 +509,7 @@ static inline void musb_configure_ep0(struct musb *musb)
 {
        musb->endpoints[0].max_packet_sz_tx = MUSB_EP0_FIFOSIZE;
        musb->endpoints[0].max_packet_sz_rx = MUSB_EP0_FIFOSIZE;
+       musb->endpoints[0].is_shared_fifo = true;
 }
 #endif /* CONFIG_BLACKFIN */
 
index 6dbbd0786a6a0955877dca888f107b641d50eec0..499c431a6d62421efdd03b599ed5756e51c70af0 100644 (file)
  *
  * - DMA (Mentor/OMAP) ...has at least toggle update problems
  *
- * - Still no traffic scheduling code to make NAKing for bulk or control
- *   transfers unable to starve other requests; or to make efficient use
- *   of hardware with periodic transfers.  (Note that network drivers
- *   commonly post bulk reads that stay pending for a long time; these
- *   would make very visible trouble.)
+ * - [23-feb-2009] minimal traffic scheduling to avoid bulk RX packet
+ *   starvation ... nothing yet for TX, interrupt, or bulk.
  *
  * - Not tested with HNP, but some SRP paths seem to behave.
  *
  *
  * CONTROL transfers all go through ep0.  BULK ones go through dedicated IN
  * and OUT endpoints ... hardware is dedicated for those "async" queue(s).
- *
  * (Yes, bulk _could_ use more of the endpoints than that, and would even
- * benefit from it ... one remote device may easily be NAKing while others
- * need to perform transfers in that same direction.  The same thing could
- * be done in software though, assuming dma cooperates.)
+ * benefit from it.)
  *
  * INTERUPPT and ISOCHRONOUS transfers are scheduled to the other endpoints.
  * So far that scheduling is both dumb and optimistic:  the endpoint will be
@@ -201,8 +195,9 @@ musb_start_urb(struct musb *musb, int is_in, struct musb_qh *qh)
                len = urb->iso_frame_desc[0].length;
                break;
        default:                /* bulk, interrupt */
-               buf = urb->transfer_buffer;
-               len = urb->transfer_buffer_length;
+               /* actual_length may be nonzero on retry paths */
+               buf = urb->transfer_buffer + urb->actual_length;
+               len = urb->transfer_buffer_length - urb->actual_length;
        }
 
        DBG(4, "qh %p urb %p dev%d ep%d%s%s, hw_ep %d, %p/%d\n",
@@ -395,7 +390,6 @@ musb_giveback(struct musb_qh *qh, struct urb *urb, int status)
                         * de-allocated if it's tracked and allocated;
                         * and where we'd update the schedule tree...
                         */
-                       musb->periodic[ep->epnum] = NULL;
                        kfree(qh);
                        qh = NULL;
                        break;
@@ -1045,7 +1039,8 @@ irqreturn_t musb_h_ep0_irq(struct musb *musb)
 
                /* NOTE:  this code path would be a good place to PAUSE a
                 * control transfer, if another one is queued, so that
-                * ep0 is more likely to stay busy.
+                * ep0 is more likely to stay busy.  That's already done
+                * for bulk RX transfers.
                 *
                 * if (qh->ring.next != &musb->control), then
                 * we have a candidate... NAKing is *NOT* an error
@@ -1197,6 +1192,7 @@ void musb_host_tx(struct musb *musb, u8 epnum)
                /* NOTE:  this code path would be a good place to PAUSE a
                 * transfer, if there's some other (nonperiodic) tx urb
                 * that could use this fifo.  (dma complicates it...)
+                * That's already done for bulk RX transfers.
                 *
                 * if (bulk && qh->ring.next != &musb->out_bulk), then
                 * we have a candidate... NAKing is *NOT* an error
@@ -1358,6 +1354,50 @@ finish:
 
 #endif
 
+/* Schedule next QH from musb->in_bulk and move the current qh to
+ * the end; avoids starvation for other endpoints.
+ */
+static void musb_bulk_rx_nak_timeout(struct musb *musb, struct musb_hw_ep *ep)
+{
+       struct dma_channel      *dma;
+       struct urb              *urb;
+       void __iomem            *mbase = musb->mregs;
+       void __iomem            *epio = ep->regs;
+       struct musb_qh          *cur_qh, *next_qh;
+       u16                     rx_csr;
+
+       musb_ep_select(mbase, ep->epnum);
+       dma = is_dma_capable() ? ep->rx_channel : NULL;
+
+       /* clear nak timeout bit */
+       rx_csr = musb_readw(epio, MUSB_RXCSR);
+       rx_csr |= MUSB_RXCSR_H_WZC_BITS;
+       rx_csr &= ~MUSB_RXCSR_DATAERROR;
+       musb_writew(epio, MUSB_RXCSR, rx_csr);
+
+       cur_qh = first_qh(&musb->in_bulk);
+       if (cur_qh) {
+               urb = next_urb(cur_qh);
+               if (dma_channel_status(dma) == MUSB_DMA_STATUS_BUSY) {
+                       dma->status = MUSB_DMA_STATUS_CORE_ABORT;
+                       musb->dma_controller->channel_abort(dma);
+                       urb->actual_length += dma->actual_len;
+                       dma->actual_len = 0L;
+               }
+               musb_save_toggle(ep, 1, urb);
+
+               /* move cur_qh to end of queue */
+               list_move_tail(&cur_qh->ring, &musb->in_bulk);
+
+               /* get the next qh from musb->in_bulk */
+               next_qh = first_qh(&musb->in_bulk);
+
+               /* set rx_reinit and schedule the next qh */
+               ep->rx_reinit = 1;
+               musb_start_urb(musb, 1, next_qh);
+       }
+}
+
 /*
  * Service an RX interrupt for the given IN endpoint; docs cover bulk, iso,
  * and high-bandwidth IN transfer cases.
@@ -1421,18 +1461,26 @@ void musb_host_rx(struct musb *musb, u8 epnum)
        } else if (rx_csr & MUSB_RXCSR_DATAERROR) {
 
                if (USB_ENDPOINT_XFER_ISOC != qh->type) {
-                       /* NOTE this code path would be a good place to PAUSE a
-                        * transfer, if there's some other (nonperiodic) rx urb
-                        * that could use this fifo.  (dma complicates it...)
+                       DBG(6, "RX end %d NAK timeout\n", epnum);
+
+                       /* NOTE: NAKing is *NOT* an error, so we want to
+                        * continue.  Except ... if there's a request for
+                        * another QH, use that instead of starving it.
                         *
-                        * if (bulk && qh->ring.next != &musb->in_bulk), then
-                        * we have a candidate... NAKing is *NOT* an error
+                        * Devices like Ethernet and serial adapters keep
+                        * reads posted at all times, which will starve
+                        * other devices without this logic.
                         */
-                       DBG(6, "RX end %d NAK timeout\n", epnum);
+                       if (usb_pipebulk(urb->pipe)
+                                       && qh->mux == 1
+                                       && !list_is_singular(&musb->in_bulk)) {
+                               musb_bulk_rx_nak_timeout(musb, hw_ep);
+                               return;
+                       }
                        musb_ep_select(mbase, epnum);
-                       musb_writew(epio, MUSB_RXCSR,
-                                       MUSB_RXCSR_H_WZC_BITS
-                                       | MUSB_RXCSR_H_REQPKT);
+                       rx_csr |= MUSB_RXCSR_H_WZC_BITS;
+                       rx_csr &= ~MUSB_RXCSR_DATAERROR;
+                       musb_writew(epio, MUSB_RXCSR, rx_csr);
 
                        goto finish;
                } else {
@@ -1711,31 +1759,27 @@ static int musb_schedule(
 
        /* else, periodic transfers get muxed to other endpoints */
 
-       /* FIXME this doesn't consider direction, so it can only
-        * work for one half of the endpoint hardware, and assumes
-        * the previous cases handled all non-shared endpoints...
-        */
-
-       /* we know this qh hasn't been scheduled, so all we need to do
+       /*
+        * We know this qh hasn't been scheduled, so all we need to do
         * is choose which hardware endpoint to put it on ...
         *
         * REVISIT what we really want here is a regular schedule tree
-        * like e.g. OHCI uses, but for now musb->periodic is just an
-        * array of the _single_ logical endpoint associated with a
-        * given physical one (identity mapping logical->physical).
-        *
-        * that simplistic approach makes TT scheduling a lot simpler;
-        * there is none, and thus none of its complexity...
+        * like e.g. OHCI uses.
         */
        best_diff = 4096;
        best_end = -1;
 
-       for (epnum = 1; epnum < musb->nr_endpoints; epnum++) {
+       for (epnum = 1, hw_ep = musb->endpoints + 1;
+                       epnum < musb->nr_endpoints;
+                       epnum++, hw_ep++) {
                int     diff;
 
-               if (musb->periodic[epnum])
+               if (is_in || hw_ep->is_shared_fifo) {
+                       if (hw_ep->in_qh  != NULL)
+                               continue;
+               } else  if (hw_ep->out_qh != NULL)
                        continue;
-               hw_ep = &musb->endpoints[epnum];
+
                if (hw_ep == musb->bulk_ep)
                        continue;
 
@@ -1756,6 +1800,17 @@ static int musb_schedule(
                        head = &musb->in_bulk;
                else
                        head = &musb->out_bulk;
+
+               /* Enable bulk RX NAK timeout scheme when bulk requests are
+                * multiplexed.  This scheme doen't work in high speed to full
+                * speed scenario as NAK interrupts are not coming from a
+                * full speed device connected to a high speed device.
+                * NAK timeout interval is 8 (128 uframe or 16ms) for HS and
+                * 4 (8 frame or 8ms) for FS device.
+                */
+               if (is_in && qh->dev)
+                       qh->intv_reg =
+                               (USB_SPEED_HIGH == qh->dev->speed) ? 8 : 4;
                goto success;
        } else if (best_end < 0) {
                return -ENOSPC;
@@ -1764,7 +1819,6 @@ static int musb_schedule(
        idle = 1;
        qh->mux = 0;
        hw_ep = musb->endpoints + best_end;
-       musb->periodic[best_end] = qh;
        DBG(4, "qh %p periodic slot %d\n", qh, best_end);
 success:
        if (head) {
@@ -1888,13 +1942,11 @@ static int musb_urb_enqueue(
                 *
                 * The downside of disabling this is that transfer scheduling
                 * gets VERY unfair for nonperiodic transfers; a misbehaving
-                * peripheral could make that hurt.  Or for reads, one that's
-                * perfectly normal:  network and other drivers keep reads
-                * posted at all times, having one pending for a week should
-                * be perfectly safe.
+                * peripheral could make that hurt.  That's perfectly normal
+                * for reads from network or serial adapters ... so we have
+                * partial NAKlimit support for bulk RX.
                 *
-                * The upside of disabling it is avoidng transfer scheduling
-                * code to put this aside for while.
+                * The upside of disabling it is simpler transfer scheduling.
                 */
                interval = 0;
        }
index e0e9ce58417502a501480ef70e5170f442331fbc..bf677acc83db03e781bb786642b1e5121ee1f627 100644 (file)
@@ -285,7 +285,7 @@ int musb_hub_control(
                desc->bDescLength = 9;
                desc->bDescriptorType = 0x29;
                desc->bNbrPorts = 1;
-               desc->wHubCharacteristics = __constant_cpu_to_le16(
+               desc->wHubCharacteristics = cpu_to_le16(
                                  0x0001        /* per-port power switching */
                                | 0x0010        /* no overcurrent reporting */
                                );
index ee55b449ffde53dd01316ce4c796add6f8e7b348..aa884d072f0b4c7202e5b421e52b0ca37a5163de 100644 (file)
@@ -43,7 +43,7 @@ config ISP1301_OMAP
 
 config TWL4030_USB
        tristate "TWL4030 USB Transceiver Driver"
-       depends on TWL4030_CORE
+       depends on TWL4030_CORE && REGULATOR_TWL4030
        select USB_OTG_UTILS
        help
          Enable this to support the USB OTG transceiver on TWL4030
@@ -51,4 +51,12 @@ config TWL4030_USB
          This transceiver supports high and full speed devices plus,
          in host mode, low speed.
 
+config NOP_USB_XCEIV
+       tristate "NOP USB Transceiver Driver"
+       select USB_OTG_UTILS
+       help
+        this driver is to be used by all the usb transceiver which are either
+        built-in with usb ip or which are autonomous and doesn't require any
+        phy programming such as ISP1x04 etc.
+
 endif # USB || OTG
index d73c7cf5e2f789674492cf5c4bdf609fa1c58b06..208167856529f26225807cd7edea4fb29a3640e9 100644 (file)
@@ -9,6 +9,7 @@ obj-$(CONFIG_USB_OTG_UTILS)     += otg.o
 obj-$(CONFIG_USB_GPIO_VBUS)    += gpio_vbus.o
 obj-$(CONFIG_ISP1301_OMAP)     += isp1301_omap.o
 obj-$(CONFIG_TWL4030_USB)      += twl4030-usb.o
+obj-$(CONFIG_NOP_USB_XCEIV)    += nop-usb-xceiv.o
 
 ccflags-$(CONFIG_USB_DEBUG)    += -DDEBUG
 ccflags-$(CONFIG_USB_GADGET_DEBUG) += -DDEBUG
index 63a6036f04befd51f84b5e1e8802274524208da3..1c26c94513e9e5bd14299d1ae046125a6d1cce07 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/gpio.h>
 #include <linux/interrupt.h>
 #include <linux/usb.h>
+#include <linux/workqueue.h>
 
 #include <linux/regulator/consumer.h>
 
@@ -34,6 +35,7 @@ struct gpio_vbus_data {
        struct regulator       *vbus_draw;
        int                     vbus_draw_enabled;
        unsigned                mA;
+       struct work_struct      work;
 };
 
 
@@ -76,24 +78,26 @@ static void set_vbus_draw(struct gpio_vbus_data *gpio_vbus, unsigned mA)
        gpio_vbus->mA = mA;
 }
 
-/* VBUS change IRQ handler */
-static irqreturn_t gpio_vbus_irq(int irq, void *data)
+static int is_vbus_powered(struct gpio_vbus_mach_info *pdata)
 {
-       struct platform_device *pdev = data;
-       struct gpio_vbus_mach_info *pdata = pdev->dev.platform_data;
-       struct gpio_vbus_data *gpio_vbus = platform_get_drvdata(pdev);
-       int gpio, vbus;
+       int vbus;
 
        vbus = gpio_get_value(pdata->gpio_vbus);
        if (pdata->gpio_vbus_inverted)
                vbus = !vbus;
 
-       dev_dbg(&pdev->dev, "VBUS %s (gadget: %s)\n",
-               vbus ? "supplied" : "inactive",
-               gpio_vbus->otg.gadget ? gpio_vbus->otg.gadget->name : "none");
+       return vbus;
+}
+
+static void gpio_vbus_work(struct work_struct *work)
+{
+       struct gpio_vbus_data *gpio_vbus =
+               container_of(work, struct gpio_vbus_data, work);
+       struct gpio_vbus_mach_info *pdata = gpio_vbus->dev->platform_data;
+       int gpio;
 
        if (!gpio_vbus->otg.gadget)
-               return IRQ_HANDLED;
+               return;
 
        /* Peripheral controllers which manage the pullup themselves won't have
         * gpio_pullup configured here.  If it's configured here, we'll do what
@@ -101,7 +105,7 @@ static irqreturn_t gpio_vbus_irq(int irq, void *data)
         * that may complicate usb_gadget_{,dis}connect() support.
         */
        gpio = pdata->gpio_pullup;
-       if (vbus) {
+       if (is_vbus_powered(pdata)) {
                gpio_vbus->otg.state = OTG_STATE_B_PERIPHERAL;
                usb_gadget_vbus_connect(gpio_vbus->otg.gadget);
 
@@ -121,6 +125,21 @@ static irqreturn_t gpio_vbus_irq(int irq, void *data)
                usb_gadget_vbus_disconnect(gpio_vbus->otg.gadget);
                gpio_vbus->otg.state = OTG_STATE_B_IDLE;
        }
+}
+
+/* VBUS change IRQ handler */
+static irqreturn_t gpio_vbus_irq(int irq, void *data)
+{
+       struct platform_device *pdev = data;
+       struct gpio_vbus_mach_info *pdata = pdev->dev.platform_data;
+       struct gpio_vbus_data *gpio_vbus = platform_get_drvdata(pdev);
+
+       dev_dbg(&pdev->dev, "VBUS %s (gadget: %s)\n",
+               is_vbus_powered(pdata) ? "supplied" : "inactive",
+               gpio_vbus->otg.gadget ? gpio_vbus->otg.gadget->name : "none");
+
+       if (gpio_vbus->otg.gadget)
+               schedule_work(&gpio_vbus->work);
 
        return IRQ_HANDLED;
 }
@@ -257,6 +276,7 @@ static int __init gpio_vbus_probe(struct platform_device *pdev)
                        irq, err);
                goto err_irq;
        }
+       INIT_WORK(&gpio_vbus->work, gpio_vbus_work);
 
        /* only active when a gadget is registered */
        err = otg_set_transceiver(&gpio_vbus->otg);
diff --git a/drivers/usb/otg/nop-usb-xceiv.c b/drivers/usb/otg/nop-usb-xceiv.c
new file mode 100644 (file)
index 0000000..4b933f6
--- /dev/null
@@ -0,0 +1,180 @@
+/*
+ * drivers/usb/otg/nop-usb-xceiv.c
+ *
+ * NOP USB transceiver for all USB transceiver which are either built-in
+ * into USB IP or which are mostly autonomous.
+ *
+ * Copyright (C) 2009 Texas Instruments Inc
+ * Author: Ajay Kumar Gupta <ajay.gupta@ti.com>
+ *
+ * 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.
+ *
+ * Current status:
+ *     this is to add "nop" transceiver for all those phy which is
+ *     autonomous such as isp1504 etc.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/usb/otg.h>
+
+struct nop_usb_xceiv {
+       struct otg_transceiver  otg;
+       struct device           *dev;
+};
+
+static u64 nop_xceiv_dmamask = DMA_32BIT_MASK;
+
+static struct platform_device nop_xceiv_device = {
+       .name           = "nop_usb_xceiv",
+       .id             = -1,
+       .dev = {
+               .dma_mask               = &nop_xceiv_dmamask,
+               .coherent_dma_mask      = DMA_32BIT_MASK,
+               .platform_data          = NULL,
+       },
+};
+
+void usb_nop_xceiv_register(void)
+{
+       if (platform_device_register(&nop_xceiv_device) < 0) {
+               printk(KERN_ERR "Unable to register usb nop transceiver\n");
+               return;
+       }
+}
+
+void usb_nop_xceiv_unregister(void)
+{
+       platform_device_unregister(&nop_xceiv_device);
+}
+
+static inline struct nop_usb_xceiv *xceiv_to_nop(struct otg_transceiver *x)
+{
+       return container_of(x, struct nop_usb_xceiv, otg);
+}
+
+static int nop_set_suspend(struct otg_transceiver *x, int suspend)
+{
+       return 0;
+}
+
+static int nop_set_peripheral(struct otg_transceiver *x,
+               struct usb_gadget *gadget)
+{
+       struct nop_usb_xceiv *nop;
+
+       if (!x)
+               return -ENODEV;
+
+       nop = xceiv_to_nop(x);
+
+       if (!gadget) {
+               nop->otg.gadget = NULL;
+               return -ENODEV;
+       }
+
+       nop->otg.gadget = gadget;
+       nop->otg.state = OTG_STATE_B_IDLE;
+       return 0;
+}
+
+static int nop_set_host(struct otg_transceiver *x, struct usb_bus *host)
+{
+       struct nop_usb_xceiv *nop;
+
+       if (!x)
+               return -ENODEV;
+
+       nop = xceiv_to_nop(x);
+
+       if (!host) {
+               nop->otg.host = NULL;
+               return -ENODEV;
+       }
+
+       nop->otg.host = host;
+       return 0;
+}
+
+static int __devinit nop_usb_xceiv_probe(struct platform_device *pdev)
+{
+       struct nop_usb_xceiv    *nop;
+       int err;
+
+       nop = kzalloc(sizeof *nop, GFP_KERNEL);
+       if (!nop)
+               return -ENOMEM;
+
+       nop->dev                = &pdev->dev;
+       nop->otg.dev            = nop->dev;
+       nop->otg.label          = "nop-xceiv";
+       nop->otg.state          = OTG_STATE_UNDEFINED;
+       nop->otg.set_host       = nop_set_host;
+       nop->otg.set_peripheral = nop_set_peripheral;
+       nop->otg.set_suspend    = nop_set_suspend;
+
+       err = otg_set_transceiver(&nop->otg);
+       if (err) {
+               dev_err(&pdev->dev, "can't register transceiver, err: %d\n",
+                       err);
+               goto exit;
+       }
+
+       platform_set_drvdata(pdev, nop);
+
+       return 0;
+exit:
+       kfree(nop);
+       return err;
+}
+
+static int __devexit nop_usb_xceiv_remove(struct platform_device *pdev)
+{
+       struct nop_usb_xceiv *nop = platform_get_drvdata(pdev);
+
+       otg_set_transceiver(NULL);
+
+       platform_set_drvdata(pdev, NULL);
+       kfree(nop);
+
+       return 0;
+}
+
+static struct platform_driver nop_usb_xceiv_driver = {
+       .probe          = nop_usb_xceiv_probe,
+       .remove         = __devexit_p(nop_usb_xceiv_remove),
+       .driver         = {
+               .name   = "nop_usb_xceiv",
+               .owner  = THIS_MODULE,
+       },
+};
+
+static int __init nop_usb_xceiv_init(void)
+{
+       return platform_driver_register(&nop_usb_xceiv_driver);
+}
+subsys_initcall(nop_usb_xceiv_init);
+
+static void __exit nop_usb_xceiv_exit(void)
+{
+       platform_driver_unregister(&nop_usb_xceiv_driver);
+}
+module_exit(nop_usb_xceiv_exit);
+
+MODULE_ALIAS("platform:nop_usb_xceiv");
+MODULE_AUTHOR("Texas Instruments Inc");
+MODULE_DESCRIPTION("NOP USB Transceiver driver");
+MODULE_LICENSE("GPL");
index 416e4410be0205258a7142d5f1d33009ebe4d963..d9478d0e1c8bd6bb6d45c778d220a6ee96c8139a 100644 (file)
@@ -34,6 +34,8 @@
 #include <linux/delay.h>
 #include <linux/usb/otg.h>
 #include <linux/i2c/twl4030.h>
+#include <linux/regulator/consumer.h>
+#include <linux/err.h>
 
 
 /* Register defines */
@@ -246,6 +248,11 @@ struct twl4030_usb {
        struct otg_transceiver  otg;
        struct device           *dev;
 
+       /* TWL4030 internal USB regulator supplies */
+       struct regulator        *usb1v5;
+       struct regulator        *usb1v8;
+       struct regulator        *usb3v1;
+
        /* for vbus reporting with irqs disabled */
        spinlock_t              lock;
 
@@ -434,6 +441,18 @@ static void twl4030_phy_power(struct twl4030_usb *twl, int on)
 
        pwr = twl4030_usb_read(twl, PHY_PWR_CTRL);
        if (on) {
+               regulator_enable(twl->usb3v1);
+               regulator_enable(twl->usb1v8);
+               /*
+                * Disabling usb3v1 regulator (= writing 0 to VUSB3V1_DEV_GRP
+                * in twl4030) resets the VUSB_DEDICATED2 register. This reset
+                * enables VUSB3V1_SLEEP bit that remaps usb3v1 ACTIVE state to
+                * SLEEP. We work around this by clearing the bit after usv3v1
+                * is re-activated. This ensures that VUSB3V1 is really active.
+                */
+               twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0,
+                                                       VUSB_DEDICATED2);
+               regulator_enable(twl->usb1v5);
                pwr &= ~PHY_PWR_PHYPWD;
                WARN_ON(twl4030_usb_write_verify(twl, PHY_PWR_CTRL, pwr) < 0);
                twl4030_usb_write(twl, PHY_CLK_CTRL,
@@ -443,6 +462,9 @@ static void twl4030_phy_power(struct twl4030_usb *twl, int on)
        } else  {
                pwr |= PHY_PWR_PHYPWD;
                WARN_ON(twl4030_usb_write_verify(twl, PHY_PWR_CTRL, pwr) < 0);
+               regulator_disable(twl->usb1v5);
+               regulator_disable(twl->usb1v8);
+               regulator_disable(twl->usb3v1);
        }
 }
 
@@ -468,7 +490,7 @@ static void twl4030_phy_resume(struct twl4030_usb *twl)
        twl->asleep = 0;
 }
 
-static void twl4030_usb_ldo_init(struct twl4030_usb *twl)
+static int twl4030_usb_ldo_init(struct twl4030_usb *twl)
 {
        /* Enable writing to power configuration registers */
        twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, 0xC0, PROTECT_KEY);
@@ -480,20 +502,45 @@ static void twl4030_usb_ldo_init(struct twl4030_usb *twl)
        /* input to VUSB3V1 LDO is from VBAT, not VBUS */
        twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0x14, VUSB_DEDICATED1);
 
-       /* turn on 3.1V regulator */
-       twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0x20, VUSB3V1_DEV_GRP);
+       /* Initialize 3.1V regulator */
+       twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB3V1_DEV_GRP);
+
+       twl->usb3v1 = regulator_get(twl->dev, "usb3v1");
+       if (IS_ERR(twl->usb3v1))
+               return -ENODEV;
+
        twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB3V1_TYPE);
 
-       /* turn on 1.5V regulator */
-       twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0x20, VUSB1V5_DEV_GRP);
+       /* Initialize 1.5V regulator */
+       twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB1V5_DEV_GRP);
+
+       twl->usb1v5 = regulator_get(twl->dev, "usb1v5");
+       if (IS_ERR(twl->usb1v5))
+               goto fail1;
+
        twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB1V5_TYPE);
 
-       /* turn on 1.8V regulator */
-       twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0x20, VUSB1V8_DEV_GRP);
+       /* Initialize 1.8V regulator */
+       twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB1V8_DEV_GRP);
+
+       twl->usb1v8 = regulator_get(twl->dev, "usb1v8");
+       if (IS_ERR(twl->usb1v8))
+               goto fail2;
+
        twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB1V8_TYPE);
 
        /* disable access to power configuration registers */
        twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, 0, PROTECT_KEY);
+
+       return 0;
+
+fail2:
+       regulator_put(twl->usb1v5);
+       twl->usb1v5 = NULL;
+fail1:
+       regulator_put(twl->usb3v1);
+       twl->usb3v1 = NULL;
+       return -ENODEV;
 }
 
 static ssize_t twl4030_usb_vbus_show(struct device *dev,
@@ -598,7 +645,7 @@ static int __init twl4030_usb_probe(struct platform_device *pdev)
 {
        struct twl4030_usb_data *pdata = pdev->dev.platform_data;
        struct twl4030_usb      *twl;
-       int                     status;
+       int                     status, err;
 
        if (!pdata) {
                dev_dbg(&pdev->dev, "platform_data not available\n");
@@ -622,7 +669,12 @@ static int __init twl4030_usb_probe(struct platform_device *pdev)
        /* init spinlock for workqueue */
        spin_lock_init(&twl->lock);
 
-       twl4030_usb_ldo_init(twl);
+       err = twl4030_usb_ldo_init(twl);
+       if (err) {
+               dev_err(&pdev->dev, "ldo init failed\n");
+               kfree(twl);
+               return err;
+       }
        otg_set_transceiver(&twl->otg);
 
        platform_set_drvdata(pdev, twl);
@@ -688,6 +740,9 @@ static int __exit twl4030_usb_remove(struct platform_device *pdev)
        twl4030_usb_clear_bits(twl, POWER_CTRL, POWER_CTRL_OTG_ENAB);
 
        twl4030_phy_power(twl, 0);
+       regulator_put(twl->usb1v5);
+       regulator_put(twl->usb1v8);
+       regulator_put(twl->usb3v1);
 
        kfree(twl);
 
index b361f05cafacaeb2a1af3c38d2652c52a09682e2..a65f9196b0a06e93df07bcb5ef0a9313c8f47f88 100644 (file)
@@ -116,14 +116,14 @@ config USB_SERIAL_DIGI_ACCELEPORT
          To compile this driver as a module, choose M here: the
          module will be called digi_acceleport.
 
-config USB_SERIAL_CP2101
-       tristate "USB CP2101 UART Bridge Controller"
+config USB_SERIAL_CP210X
+       tristate "USB CP210x family of UART Bridge Controllers"
        help
-         Say Y here if you want to use a CP2101/CP2102 based USB to RS232
-         converter.
+         Say Y here if you want to use a CP2101/CP2102/CP2103 based USB
+         to RS232 converters.
 
          To compile this driver as a module, choose M here: the
-         module will be called cp2101.
+         module will be called cp210x.
 
 config USB_SERIAL_CYPRESS_M8
        tristate "USB Cypress M8 USB Serial Driver"
@@ -472,6 +472,15 @@ config USB_SERIAL_OTI6858
          To compile this driver as a module, choose M here: the
          module will be called oti6858.
 
+config USB_SERIAL_QUALCOMM
+       tristate "USB Qualcomm Serial modem"
+       help
+         Say Y here if you have a Qualcomm USB modem device.  These are
+         usually wireless cellular modems.
+
+         To compile this driver as a module, choose M here: the
+         module will be called qcserial.
+
 config USB_SERIAL_SPCP8X5
        tristate "USB SPCP8x5 USB To Serial Driver"
        help
@@ -515,6 +524,15 @@ config USB_SERIAL_SIERRAWIRELESS
          To compile this driver as a module, choose M here: the
          module will be called sierra.
 
+config USB_SERIAL_SYMBOL
+       tristate "USB Symbol Barcode driver (serial mode)"
+       help
+         Say Y here if you want to use a Symbol USB Barcode device
+         in serial emulation mode.
+
+         To compile this driver as a module, choose M here: the
+         module will be called symbolserial.
+
 config USB_SERIAL_TI
        tristate "USB TI 3410/5052 Serial Driver"
        help
index b75be91eb8f12f31615f54da4fcb2ab60b12e38d..66619beb6cc0578b591c2e961e1e71f5306ca09a 100644 (file)
@@ -15,7 +15,7 @@ obj-$(CONFIG_USB_SERIAL_AIRCABLE)             += aircable.o
 obj-$(CONFIG_USB_SERIAL_ARK3116)               += ark3116.o
 obj-$(CONFIG_USB_SERIAL_BELKIN)                        += belkin_sa.o
 obj-$(CONFIG_USB_SERIAL_CH341)                 += ch341.o
-obj-$(CONFIG_USB_SERIAL_CP2101)                        += cp2101.o
+obj-$(CONFIG_USB_SERIAL_CP210X)                        += cp210x.o
 obj-$(CONFIG_USB_SERIAL_CYBERJACK)             += cyberjack.o
 obj-$(CONFIG_USB_SERIAL_CYPRESS_M8)            += cypress_m8.o
 obj-$(CONFIG_USB_SERIAL_DEBUG)                 += usb_debug.o
@@ -45,10 +45,12 @@ obj-$(CONFIG_USB_SERIAL_OPTICON)            += opticon.o
 obj-$(CONFIG_USB_SERIAL_OPTION)                        += option.o
 obj-$(CONFIG_USB_SERIAL_OTI6858)               += oti6858.o
 obj-$(CONFIG_USB_SERIAL_PL2303)                        += pl2303.o
+obj-$(CONFIG_USB_SERIAL_QUALCOMM)              += qcserial.o
 obj-$(CONFIG_USB_SERIAL_SAFE)                  += safe_serial.o
 obj-$(CONFIG_USB_SERIAL_SIEMENS_MPI)           += siemens_mpi.o
 obj-$(CONFIG_USB_SERIAL_SIERRAWIRELESS)                += sierra.o
 obj-$(CONFIG_USB_SERIAL_SPCP8X5)               += spcp8x5.o
+obj-$(CONFIG_USB_SERIAL_SYMBOL)                        += symbolserial.o
 obj-$(CONFIG_USB_SERIAL_TI)                    += ti_usb_3410_5052.o
 obj-$(CONFIG_USB_SERIAL_VISOR)                 += visor.o
 obj-$(CONFIG_USB_SERIAL_WHITEHEAT)             += whiteheat.o
index f61e3ca64305abb3d7bbefda787c073bb30c77ee..ab4cc277aa659be685a154c6a5024cf02f14eba9 100644 (file)
@@ -1,5 +1,7 @@
 /*
  * Copyright 2007, Frank A Kingswood <frank@kingswood-consulting.co.uk>
+ * Copyright 2007, Werner Cornelius <werner@cornelius-consult.de>
+ * Copyright 2009, Boris Hajduk <boris@hajduk.org>
  *
  * ch341.c implements a serial port driver for the Winchiphead CH341.
  *
 #include <linux/usb/serial.h>
 #include <linux/serial.h>
 
-#define DEFAULT_BAUD_RATE 2400
+#define DEFAULT_BAUD_RATE 9600
 #define DEFAULT_TIMEOUT   1000
 
+/* flags for IO-Bits */
+#define CH341_BIT_RTS (1 << 6)
+#define CH341_BIT_DTR (1 << 5)
+
+/******************************/
+/* interrupt pipe definitions */
+/******************************/
+/* always 4 interrupt bytes */
+/* first irq byte normally 0x08 */
+/* second irq byte base 0x7d + below */
+/* third irq byte base 0x94 + below */
+/* fourth irq byte normally 0xee */
+
+/* second interrupt byte */
+#define CH341_MULT_STAT 0x04 /* multiple status since last interrupt event */
+
+/* status returned in third interrupt answer byte, inverted in data
+   from irq */
+#define CH341_BIT_CTS 0x01
+#define CH341_BIT_DSR 0x02
+#define CH341_BIT_RI  0x04
+#define CH341_BIT_DCD 0x08
+#define CH341_BITS_MODEM_STAT 0x0f /* all bits */
+
+/*******************************/
+/* baudrate calculation factor */
+/*******************************/
+#define CH341_BAUDBASE_FACTOR 1532620800
+#define CH341_BAUDBASE_DIVMAX 3
+
 static int debug;
 
 static struct usb_device_id id_table [] = {
@@ -34,9 +66,12 @@ static struct usb_device_id id_table [] = {
 MODULE_DEVICE_TABLE(usb, id_table);
 
 struct ch341_private {
-       unsigned baud_rate;
-       u8 dtr;
-       u8 rts;
+       spinlock_t lock; /* access lock */
+       wait_queue_head_t delta_msr_wait; /* wait queue for modem status */
+       unsigned baud_rate; /* set baud rate */
+       u8 line_control; /* set line control value RTS/DTR */
+       u8 line_status; /* active status of modem control inputs */
+       u8 multi_status_change; /* status changed multiple since last call */
 };
 
 static int ch341_control_out(struct usb_device *dev, u8 request,
@@ -72,37 +107,28 @@ static int ch341_set_baudrate(struct usb_device *dev,
 {
        short a, b;
        int r;
+       unsigned long factor;
+       short divisor;
 
        dbg("ch341_set_baudrate(%d)", priv->baud_rate);
-       switch (priv->baud_rate) {
-       case 2400:
-               a = 0xd901;
-               b = 0x0038;
-               break;
-       case 4800:
-               a = 0x6402;
-               b = 0x001f;
-               break;
-       case 9600:
-               a = 0xb202;
-               b = 0x0013;
-               break;
-       case 19200:
-               a = 0xd902;
-               b = 0x000d;
-               break;
-       case 38400:
-               a = 0x6403;
-               b = 0x000a;
-               break;
-       case 115200:
-               a = 0xcc03;
-               b = 0x0008;
-               break;
-       default:
+
+       if (!priv->baud_rate)
                return -EINVAL;
+       factor = (CH341_BAUDBASE_FACTOR / priv->baud_rate);
+       divisor = CH341_BAUDBASE_DIVMAX;
+
+       while ((factor > 0xfff0) && divisor) {
+               factor >>= 3;
+               divisor--;
        }
 
+       if (factor > 0xfff0)
+               return -EINVAL;
+
+       factor = 0x10000 - factor;
+       a = (factor & 0xff00) | divisor;
+       b = factor & 0xff;
+
        r = ch341_control_out(dev, 0x9a, 0x1312, a);
        if (!r)
                r = ch341_control_out(dev, 0x9a, 0x0f2c, b);
@@ -110,19 +136,18 @@ static int ch341_set_baudrate(struct usb_device *dev,
        return r;
 }
 
-static int ch341_set_handshake(struct usb_device *dev,
-                              struct ch341_private *priv)
+static int ch341_set_handshake(struct usb_device *dev, u8 control)
 {
-       dbg("ch341_set_handshake(%d,%d)", priv->dtr, priv->rts);
-       return ch341_control_out(dev, 0xa4,
-               ~((priv->dtr?1<<5:0)|(priv->rts?1<<6:0)), 0);
+       dbg("ch341_set_handshake(0x%02x)", control);
+       return ch341_control_out(dev, 0xa4, ~control, 0);
 }
 
-static int ch341_get_status(struct usb_device *dev)
+static int ch341_get_status(struct usb_device *dev, struct ch341_private *priv)
 {
        char *buffer;
        int r;
        const unsigned size = 8;
+       unsigned long flags;
 
        dbg("ch341_get_status()");
 
@@ -134,10 +159,15 @@ static int ch341_get_status(struct usb_device *dev)
        if (r < 0)
                goto out;
 
-       /* Not having the datasheet for the CH341, we ignore the bytes returned
-        * from the device. Return error if the device did not respond in time.
-        */
-       r = 0;
+       /* setup the private status if available */
+       if (r == 2) {
+               r = 0;
+               spin_lock_irqsave(&priv->lock, flags);
+               priv->line_status = (~(*buffer)) & CH341_BITS_MODEM_STAT;
+               priv->multi_status_change = 0;
+               spin_unlock_irqrestore(&priv->lock, flags);
+       } else
+               r = -EPROTO;
 
 out:   kfree(buffer);
        return r;
@@ -180,7 +210,7 @@ static int ch341_configure(struct usb_device *dev, struct ch341_private *priv)
                goto out;
 
        /* expect 0xff 0xee */
-       r = ch341_get_status(dev);
+       r = ch341_get_status(dev, priv);
        if (r < 0)
                goto out;
 
@@ -192,12 +222,12 @@ static int ch341_configure(struct usb_device *dev, struct ch341_private *priv)
        if (r < 0)
                goto out;
 
-       r = ch341_set_handshake(dev, priv);
+       r = ch341_set_handshake(dev, priv->line_control);
        if (r < 0)
                goto out;
 
        /* expect 0x9f 0xee */
-       r = ch341_get_status(dev);
+       r = ch341_get_status(dev, priv);
 
 out:   kfree(buffer);
        return r;
@@ -216,9 +246,10 @@ static int ch341_attach(struct usb_serial *serial)
        if (!priv)
                return -ENOMEM;
 
+       spin_lock_init(&priv->lock);
+       init_waitqueue_head(&priv->delta_msr_wait);
        priv->baud_rate = DEFAULT_BAUD_RATE;
-       priv->dtr = 1;
-       priv->rts = 1;
+       priv->line_control = CH341_BIT_RTS | CH341_BIT_DTR;
 
        r = ch341_configure(serial->dev, priv);
        if (r < 0)
@@ -231,6 +262,35 @@ error:     kfree(priv);
        return r;
 }
 
+static void ch341_close(struct tty_struct *tty, struct usb_serial_port *port,
+                               struct file *filp)
+{
+       struct ch341_private *priv = usb_get_serial_port_data(port);
+       unsigned long flags;
+       unsigned int c_cflag;
+
+       dbg("%s - port %d", __func__, port->number);
+
+       /* shutdown our urbs */
+       dbg("%s - shutting down urbs", __func__);
+       usb_kill_urb(port->write_urb);
+       usb_kill_urb(port->read_urb);
+       usb_kill_urb(port->interrupt_in_urb);
+
+       if (tty) {
+               c_cflag = tty->termios->c_cflag;
+               if (c_cflag & HUPCL) {
+                       /* drop DTR and RTS */
+                       spin_lock_irqsave(&priv->lock, flags);
+                       priv->line_control = 0;
+                       spin_unlock_irqrestore(&priv->lock, flags);
+                       ch341_set_handshake(port->serial->dev, 0);
+               }
+       }
+       wake_up_interruptible(&priv->delta_msr_wait);
+}
+
+
 /* open this device, set default parameters */
 static int ch341_open(struct tty_struct *tty, struct usb_serial_port *port,
                                struct file *filp)
@@ -242,14 +302,13 @@ static int ch341_open(struct tty_struct *tty, struct usb_serial_port *port,
        dbg("ch341_open()");
 
        priv->baud_rate = DEFAULT_BAUD_RATE;
-       priv->dtr = 1;
-       priv->rts = 1;
+       priv->line_control = CH341_BIT_RTS | CH341_BIT_DTR;
 
        r = ch341_configure(serial->dev, priv);
        if (r)
                goto out;
 
-       r = ch341_set_handshake(serial->dev, priv);
+       r = ch341_set_handshake(serial->dev, priv->line_control);
        if (r)
                goto out;
 
@@ -257,6 +316,16 @@ static int ch341_open(struct tty_struct *tty, struct usb_serial_port *port,
        if (r)
                goto out;
 
+       dbg("%s - submitting interrupt urb", __func__);
+       port->interrupt_in_urb->dev = serial->dev;
+       r = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
+       if (r) {
+               dev_err(&port->dev, "%s - failed submitting interrupt urb,"
+                       " error %d\n", __func__, r);
+               ch341_close(tty, port, NULL);
+               return -EPROTO;
+       }
+
        r = usb_serial_generic_open(tty, port, filp);
 
 out:   return r;
@@ -270,46 +339,224 @@ static void ch341_set_termios(struct tty_struct *tty,
 {
        struct ch341_private *priv = usb_get_serial_port_data(port);
        unsigned baud_rate;
+       unsigned long flags;
 
        dbg("ch341_set_termios()");
 
+       if (!tty || !tty->termios)
+               return;
+
        baud_rate = tty_get_baud_rate(tty);
 
-       switch (baud_rate) {
-       case 2400:
-       case 4800:
-       case 9600:
-       case 19200:
-       case 38400:
-       case 115200:
-               priv->baud_rate = baud_rate;
-               break;
-       default:
-               dbg("Rate %d not supported, using %d",
-                       baud_rate, DEFAULT_BAUD_RATE);
-               priv->baud_rate = DEFAULT_BAUD_RATE;
+       priv->baud_rate = baud_rate;
+
+       if (baud_rate) {
+               spin_lock_irqsave(&priv->lock, flags);
+               priv->line_control |= (CH341_BIT_DTR | CH341_BIT_RTS);
+               spin_unlock_irqrestore(&priv->lock, flags);
+               ch341_set_baudrate(port->serial->dev, priv);
+       } else {
+               spin_lock_irqsave(&priv->lock, flags);
+               priv->line_control &= ~(CH341_BIT_DTR | CH341_BIT_RTS);
+               spin_unlock_irqrestore(&priv->lock, flags);
        }
 
-       ch341_set_baudrate(port->serial->dev, priv);
+       ch341_set_handshake(port->serial->dev, priv->line_control);
 
        /* Unimplemented:
         * (cflag & CSIZE) : data bits [5, 8]
         * (cflag & PARENB) : parity {NONE, EVEN, ODD}
         * (cflag & CSTOPB) : stop bits [1, 2]
         */
+}
+
+static int ch341_tiocmset(struct tty_struct *tty, struct file *file,
+                         unsigned int set, unsigned int clear)
+{
+       struct usb_serial_port *port = tty->driver_data;
+       struct ch341_private *priv = usb_get_serial_port_data(port);
+       unsigned long flags;
+       u8 control;
+
+       spin_lock_irqsave(&priv->lock, flags);
+       if (set & TIOCM_RTS)
+               priv->line_control |= CH341_BIT_RTS;
+       if (set & TIOCM_DTR)
+               priv->line_control |= CH341_BIT_DTR;
+       if (clear & TIOCM_RTS)
+               priv->line_control &= ~CH341_BIT_RTS;
+       if (clear & TIOCM_DTR)
+               priv->line_control &= ~CH341_BIT_DTR;
+       control = priv->line_control;
+       spin_unlock_irqrestore(&priv->lock, flags);
+
+       return ch341_set_handshake(port->serial->dev, control);
+}
+
+static void ch341_read_int_callback(struct urb *urb)
+{
+       struct usb_serial_port *port = (struct usb_serial_port *) urb->context;
+       unsigned char *data = urb->transfer_buffer;
+       unsigned int actual_length = urb->actual_length;
+       int status;
+
+       dbg("%s (%d)", __func__, port->number);
+
+       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", __func__,
+                   urb->status);
+               return;
+       default:
+               dbg("%s - nonzero urb status received: %d", __func__,
+                   urb->status);
+               goto exit;
+       }
 
-        /* Copy back the old hardware settings */
-        tty_termios_copy_hw(tty->termios, old_termios);
-        /* And re-encode with the new baud */
-        tty_encode_baud_rate(tty, baud_rate, baud_rate);
+       usb_serial_debug_data(debug, &port->dev, __func__,
+                             urb->actual_length, urb->transfer_buffer);
+
+       if (actual_length >= 4) {
+               struct ch341_private *priv = usb_get_serial_port_data(port);
+               unsigned long flags;
+
+               spin_lock_irqsave(&priv->lock, flags);
+               priv->line_status = (~(data[2])) & CH341_BITS_MODEM_STAT;
+               if ((data[1] & CH341_MULT_STAT))
+                       priv->multi_status_change = 1;
+               spin_unlock_irqrestore(&priv->lock, flags);
+               wake_up_interruptible(&priv->delta_msr_wait);
+       }
+
+exit:
+       status = usb_submit_urb(urb, GFP_ATOMIC);
+       if (status)
+               dev_err(&urb->dev->dev,
+                       "%s - usb_submit_urb failed with result %d\n",
+                       __func__, status);
+}
+
+static int wait_modem_info(struct usb_serial_port *port, unsigned int arg)
+{
+       struct ch341_private *priv = usb_get_serial_port_data(port);
+       unsigned long flags;
+       u8 prevstatus;
+       u8 status;
+       u8 changed;
+       u8 multi_change = 0;
+
+       spin_lock_irqsave(&priv->lock, flags);
+       prevstatus = priv->line_status;
+       priv->multi_status_change = 0;
+       spin_unlock_irqrestore(&priv->lock, flags);
+
+       while (!multi_change) {
+               interruptible_sleep_on(&priv->delta_msr_wait);
+               /* see if a signal did it */
+               if (signal_pending(current))
+                       return -ERESTARTSYS;
+
+               spin_lock_irqsave(&priv->lock, flags);
+               status = priv->line_status;
+               multi_change = priv->multi_status_change;
+               spin_unlock_irqrestore(&priv->lock, flags);
+
+               changed = prevstatus ^ status;
+
+               if (((arg & TIOCM_RNG) && (changed & CH341_BIT_RI)) ||
+                   ((arg & TIOCM_DSR) && (changed & CH341_BIT_DSR)) ||
+                   ((arg & TIOCM_CD)  && (changed & CH341_BIT_DCD)) ||
+                   ((arg & TIOCM_CTS) && (changed & CH341_BIT_CTS))) {
+                       return 0;
+               }
+               prevstatus = status;
+       }
+
+       return 0;
+}
+
+/*static int ch341_ioctl(struct usb_serial_port *port, struct file *file,*/
+static int ch341_ioctl(struct tty_struct *tty, struct file *file,
+                       unsigned int cmd, unsigned long arg)
+{
+       struct usb_serial_port *port = tty->driver_data;
+       dbg("%s (%d) cmd = 0x%04x", __func__, port->number, cmd);
+
+       switch (cmd) {
+       case TIOCMIWAIT:
+               dbg("%s (%d) TIOCMIWAIT", __func__,  port->number);
+               return wait_modem_info(port, arg);
+
+       default:
+               dbg("%s not supported = 0x%04x", __func__, cmd);
+               break;
+       }
+
+       return -ENOIOCTLCMD;
+}
+
+static int ch341_tiocmget(struct tty_struct *tty, struct file *file)
+{
+       struct usb_serial_port *port = tty->driver_data;
+       struct ch341_private *priv = usb_get_serial_port_data(port);
+       unsigned long flags;
+       u8 mcr;
+       u8 status;
+       unsigned int result;
+
+       dbg("%s (%d)", __func__, port->number);
+
+       spin_lock_irqsave(&priv->lock, flags);
+       mcr = priv->line_control;
+       status = priv->line_status;
+       spin_unlock_irqrestore(&priv->lock, flags);
+
+       result = ((mcr & CH341_BIT_DTR)         ? TIOCM_DTR : 0)
+                 | ((mcr & CH341_BIT_RTS)      ? TIOCM_RTS : 0)
+                 | ((status & CH341_BIT_CTS)   ? TIOCM_CTS : 0)
+                 | ((status & CH341_BIT_DSR)   ? TIOCM_DSR : 0)
+                 | ((status & CH341_BIT_RI)    ? TIOCM_RI  : 0)
+                 | ((status & CH341_BIT_DCD)   ? TIOCM_CD  : 0);
+
+       dbg("%s - result = %x", __func__, result);
+
+       return result;
+}
+
+
+static int ch341_reset_resume(struct usb_interface *intf)
+{
+       struct usb_device *dev = interface_to_usbdev(intf);
+       struct usb_serial *serial = NULL;
+       struct ch341_private *priv;
+
+       serial = usb_get_intfdata(intf);
+       priv = usb_get_serial_port_data(serial->port[0]);
+
+       /*reconfigure ch341 serial port after bus-reset*/
+       ch341_configure(dev, priv);
+
+       usb_serial_resume(intf);
+
+       return 0;
 }
 
 static struct usb_driver ch341_driver = {
        .name           = "ch341",
        .probe          = usb_serial_probe,
        .disconnect     = usb_serial_disconnect,
+       .suspend        = usb_serial_suspend,
+       .resume         = usb_serial_resume,
+       .reset_resume   = ch341_reset_resume,
        .id_table       = id_table,
        .no_dynamic_id  = 1,
+       .supports_autosuspend = 1,
 };
 
 static struct usb_serial_driver ch341_device = {
@@ -317,12 +564,17 @@ static struct usb_serial_driver ch341_device = {
                .owner  = THIS_MODULE,
                .name   = "ch341-uart",
        },
-       .id_table         = id_table,
-       .usb_driver       = &ch341_driver,
-       .num_ports        = 1,
-       .open             = ch341_open,
-       .set_termios      = ch341_set_termios,
-       .attach           = ch341_attach,
+       .id_table          = id_table,
+       .usb_driver        = &ch341_driver,
+       .num_ports         = 1,
+       .open              = ch341_open,
+       .close             = ch341_close,
+       .ioctl             = ch341_ioctl,
+       .set_termios       = ch341_set_termios,
+       .tiocmget          = ch341_tiocmget,
+       .tiocmset          = ch341_tiocmset,
+       .read_int_callback = ch341_read_int_callback,
+       .attach            = ch341_attach,
 };
 
 static int __init ch341_init(void)
similarity index 85%
rename from drivers/usb/serial/cp2101.c
rename to drivers/usb/serial/cp210x.c
index 9b4082b58c5ba3d3cfa7316f9c83dfbebb156acf..e8d5133ce9c84f911d210a374f5af40821c7f6b4 100644 (file)
  * thanks to Karl Hiramoto karl@hiramoto.org. RTSCTS hardware flow
  * control thanks to Munir Nassar nassarmu@real-time.com
  *
- * Outstanding Issues:
- *  Buffers are not flushed when the port is opened.
- *  Multiple calls to write() may fail with "Resource temporarily unavailable"
- *
  */
 
 #include <linux/kernel.h>
@@ -31,7 +27,7 @@
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v0.07"
+#define DRIVER_VERSION "v0.08"
 #define DRIVER_DESC "Silicon Labs CP2101/CP2102 RS232 serial adaptor driver"
 
 /*
@@ -42,17 +38,21 @@ static int cp2101_open(struct tty_struct *, struct usb_serial_port *,
 static void cp2101_cleanup(struct usb_serial_port *);
 static void cp2101_close(struct tty_struct *, struct usb_serial_port *,
                                                        struct file*);
-static void cp2101_get_termios(struct tty_struct *);
+static void cp2101_get_termios(struct tty_struct *,
+       struct usb_serial_port *port);
+static void cp2101_get_termios_port(struct usb_serial_port *port,
+       unsigned int *cflagp, unsigned int *baudp);
 static void cp2101_set_termios(struct tty_struct *, struct usb_serial_port *,
                                                        struct ktermios*);
 static int cp2101_tiocmget(struct tty_struct *, struct file *);
 static int cp2101_tiocmset(struct tty_struct *, struct file *,
                unsigned int, unsigned int);
+static int cp2101_tiocmset_port(struct usb_serial_port *port, struct file *,
+               unsigned int, unsigned int);
 static void cp2101_break_ctl(struct tty_struct *, int);
 static int cp2101_startup(struct usb_serial *);
 static void cp2101_shutdown(struct usb_serial *);
 
-
 static int debug;
 
 static struct usb_device_id id_table [] = {
@@ -91,6 +91,7 @@ static struct usb_device_id id_table [] = {
        { USB_DEVICE(0x10c4, 0x8293) }, /* Telegesys ETRX2USB */
        { USB_DEVICE(0x10C4, 0x8341) }, /* Siemens MC35PU GPRS Modem */
        { USB_DEVICE(0x10C4, 0x83A8) }, /* Amber Wireless AMB2560 */
+       { USB_DEVICE(0x10C4, 0x846E) }, /* BEI USB Sensor Interface (VCP) */
        { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */
        { USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */
        { USB_DEVICE(0x10C4, 0xF001) }, /* Elan Digital Systems USBscope50 */
@@ -225,7 +226,7 @@ static int cp2101_get_config(struct usb_serial_port *port, u8 request,
        kfree(buf);
 
        if (result != size) {
-               dev_err(&port->dev, "%s - Unable to send config request, "
+               dbg("%s - Unable to send config request, "
                                "request=0x%x size=%d result=%d\n",
                                __func__, request, size, result);
                return -EPROTO;
@@ -276,7 +277,7 @@ static int cp2101_set_config(struct usb_serial_port *port, u8 request,
        kfree(buf);
 
        if ((size > 2 && result != size) || result < 0) {
-               dev_err(&port->dev, "%s - Unable to send request, "
+               dbg("%s - Unable to send request, "
                                "request=0x%x size=%d result=%d\n",
                                __func__, request, size, result);
                return -EPROTO;
@@ -301,6 +302,47 @@ static inline int cp2101_set_config_single(struct usb_serial_port *port,
        return cp2101_set_config(port, request, &data, 2);
 }
 
+/*
+ * cp2101_quantise_baudrate
+ * Quantises the baud rate as per AN205 Table 1
+ */
+static unsigned int cp2101_quantise_baudrate(unsigned int baud) {
+       if      (baud <= 56)       baud = 0;
+       else if (baud <= 300)      baud = 300;
+       else if (baud <= 600)      baud = 600;
+       else if (baud <= 1200)     baud = 1200;
+       else if (baud <= 1800)     baud = 1800;
+       else if (baud <= 2400)     baud = 2400;
+       else if (baud <= 4000)     baud = 4000;
+       else if (baud <= 4803)     baud = 4800;
+       else if (baud <= 7207)     baud = 7200;
+       else if (baud <= 9612)     baud = 9600;
+       else if (baud <= 14428)    baud = 14400;
+       else if (baud <= 16062)    baud = 16000;
+       else if (baud <= 19250)    baud = 19200;
+       else if (baud <= 28912)    baud = 28800;
+       else if (baud <= 38601)    baud = 38400;
+       else if (baud <= 51558)    baud = 51200;
+       else if (baud <= 56280)    baud = 56000;
+       else if (baud <= 58053)    baud = 57600;
+       else if (baud <= 64111)    baud = 64000;
+       else if (baud <= 77608)    baud = 76800;
+       else if (baud <= 117028)   baud = 115200;
+       else if (baud <= 129347)   baud = 128000;
+       else if (baud <= 156868)   baud = 153600;
+       else if (baud <= 237832)   baud = 230400;
+       else if (baud <= 254234)   baud = 250000;
+       else if (baud <= 273066)   baud = 256000;
+       else if (baud <= 491520)   baud = 460800;
+       else if (baud <= 567138)   baud = 500000;
+       else if (baud <= 670254)   baud = 576000;
+       else if (baud <= 1053257)  baud = 921600;
+       else if (baud <= 1474560)  baud = 1228800;
+       else if (baud <= 2457600)  baud = 1843200;
+       else                       baud = 3686400;
+       return baud;
+}
+
 static int cp2101_open(struct tty_struct *tty, struct usb_serial_port *port,
                                struct file *filp)
 {
@@ -331,10 +373,12 @@ static int cp2101_open(struct tty_struct *tty, struct usb_serial_port *port,
        }
 
        /* Configure the termios structure */
-       cp2101_get_termios(tty);
+       cp2101_get_termios(tty, port);
 
        /* Set the DTR and RTS pins low */
-       cp2101_tiocmset(tty, NULL, TIOCM_DTR | TIOCM_RTS, 0);
+       cp2101_tiocmset_port(tty ? (struct usb_serial_port *) tty->driver_data
+                       : port,
+               NULL, TIOCM_DTR | TIOCM_RTS, 0);
 
        return 0;
 }
@@ -376,9 +420,31 @@ static void cp2101_close(struct tty_struct *tty, struct usb_serial_port *port,
  * from the device, corrects any unsupported values, and configures the
  * termios structure to reflect the state of the device
  */
-static void cp2101_get_termios (struct tty_struct *tty)
+static void cp2101_get_termios(struct tty_struct *tty,
+       struct usb_serial_port *port)
+{
+       unsigned int baud;
+
+       if (tty) {
+               cp2101_get_termios_port(tty->driver_data,
+                       &tty->termios->c_cflag, &baud);
+               tty_encode_baud_rate(tty, baud, baud);
+       }
+
+       else {
+               unsigned int cflag;
+               cflag = 0;
+               cp2101_get_termios_port(port, &cflag, &baud);
+       }
+}
+
+/*
+ * cp2101_get_termios_port
+ * This is the heart of cp2101_get_termios which always uses a &usb_serial_port.
+ */
+static void cp2101_get_termios_port(struct usb_serial_port *port,
+       unsigned int *cflagp, unsigned int *baudp)
 {
-       struct usb_serial_port *port = tty->driver_data;
        unsigned int cflag, modem_ctl[4];
        unsigned int baud;
        unsigned int bits;
@@ -388,12 +454,12 @@ static void cp2101_get_termios (struct tty_struct *tty)
        cp2101_get_config(port, CP2101_BAUDRATE, &baud, 2);
        /* Convert to baudrate */
        if (baud)
-               baud = BAUD_RATE_GEN_FREQ / baud;
+               baud = cp2101_quantise_baudrate((BAUD_RATE_GEN_FREQ + baud/2)/ baud);
 
        dbg("%s - baud rate = %d", __func__, baud);
+       *baudp = baud;
 
-       tty_encode_baud_rate(tty, baud, baud);
-       cflag = tty->termios->c_cflag;
+       cflag = *cflagp;
 
        cp2101_get_config(port, CP2101_BITS, &bits, 2);
        cflag &= ~CSIZE;
@@ -499,7 +565,7 @@ static void cp2101_get_termios (struct tty_struct *tty)
                cflag &= ~CRTSCTS;
        }
 
-       tty->termios->c_cflag = cflag;
+       *cflagp = cflag;
 }
 
 static void cp2101_set_termios(struct tty_struct *tty,
@@ -517,46 +583,16 @@ static void cp2101_set_termios(struct tty_struct *tty,
        tty->termios->c_cflag &= ~CMSPAR;
        cflag = tty->termios->c_cflag;
        old_cflag = old_termios->c_cflag;
-       baud = tty_get_baud_rate(tty);
+       baud = cp2101_quantise_baudrate(tty_get_baud_rate(tty));
 
        /* If the baud rate is to be updated*/
-       if (baud != tty_termios_baud_rate(old_termios)) {
-               switch (baud) {
-               case 0:
-               case 600:
-               case 1200:
-               case 1800:
-               case 2400:
-               case 4800:
-               case 7200:
-               case 9600:
-               case 14400:
-               case 19200:
-               case 28800:
-               case 38400:
-               case 55854:
-               case 57600:
-               case 115200:
-               case 127117:
-               case 230400:
-               case 460800:
-               case 921600:
-               case 3686400:
-                       break;
-               default:
-                       baud = 9600;
-                       break;
-               }
-
-               if (baud) {
-                       dbg("%s - Setting baud rate to %d baud", __func__,
-                                       baud);
-                       if (cp2101_set_config_single(port, CP2101_BAUDRATE,
-                                               (BAUD_RATE_GEN_FREQ / baud))) {
-                               dev_err(&port->dev, "Baud rate requested not "
-                                               "supported by device\n");
-                               baud = tty_termios_baud_rate(old_termios);
-                       }
+       if (baud != tty_termios_baud_rate(old_termios) && baud != 0) {
+               dbg("%s - Setting baud rate to %d baud", __func__,
+                               baud);
+               if (cp2101_set_config_single(port, CP2101_BAUDRATE,
+                                       ((BAUD_RATE_GEN_FREQ + baud/2) / baud))) {
+                       dbg("Baud rate requested not supported by device\n");
+                       baud = tty_termios_baud_rate(old_termios);
                }
        }
        /* Report back the resulting baud rate */
@@ -588,14 +624,14 @@ static void cp2101_set_termios(struct tty_struct *tty,
                        dbg("%s - data bits = 9", __func__);
                        break;*/
                default:
-                       dev_err(&port->dev, "cp2101 driver does not "
+                       dbg("cp2101 driver does not "
                                        "support the number of bits requested,"
                                        " using 8 bit mode\n");
                                bits |= BITS_DATA_8;
                                break;
                }
                if (cp2101_set_config(port, CP2101_BITS, &bits, 2))
-                       dev_err(&port->dev, "Number of data bits requested "
+                       dbg("Number of data bits requested "
                                        "not supported by device\n");
        }
 
@@ -612,7 +648,7 @@ static void cp2101_set_termios(struct tty_struct *tty,
                        }
                }
                if (cp2101_set_config(port, CP2101_BITS, &bits, 2))
-                       dev_err(&port->dev, "Parity mode not supported "
+                       dbg("Parity mode not supported "
                                        "by device\n");
        }
 
@@ -627,7 +663,7 @@ static void cp2101_set_termios(struct tty_struct *tty,
                        dbg("%s - stop bits = 1", __func__);
                }
                if (cp2101_set_config(port, CP2101_BITS, &bits, 2))
-                       dev_err(&port->dev, "Number of stop bits requested "
+                       dbg("Number of stop bits requested "
                                        "not supported by device\n");
        }
 
@@ -661,6 +697,12 @@ static int cp2101_tiocmset (struct tty_struct *tty, struct file *file,
                unsigned int set, unsigned int clear)
 {
        struct usb_serial_port *port = tty->driver_data;
+       return cp2101_tiocmset_port(port, file, set, clear);
+}
+
+static int cp2101_tiocmset_port(struct usb_serial_port *port, struct file *file,
+               unsigned int set, unsigned int clear)
+{
        unsigned int control = 0;
 
        dbg("%s - port %d", __func__, port->number);
@@ -685,7 +727,6 @@ static int cp2101_tiocmset (struct tty_struct *tty, struct file *file,
        dbg("%s - control = 0x%.4x", __func__, control);
 
        return cp2101_set_config(port, CP2101_CONTROL, &control, 2);
-
 }
 
 static int cp2101_tiocmget (struct tty_struct *tty, struct file *file)
index ae84c326a54039cf7ef077823d94550860df74b5..dcc87aaa86282b186bdc1cdd024eb97a9cb9e27b 100644 (file)
@@ -1938,18 +1938,16 @@ static void ftdi_process_read(struct work_struct *work)
                /* Compare new line status to the old one, signal if different/
                   N.B. packet may be processed more than once, but differences
                   are only processed once.  */
-               if (priv != NULL) {
-                       char new_status = data[packet_offset + 0] &
-                                                       FTDI_STATUS_B0_MASK;
-                       if (new_status != priv->prev_status) {
-                               priv->diff_status |=
-                                       new_status ^ priv->prev_status;
-                               wake_up_interruptible(&priv->delta_msr_wait);
-                               priv->prev_status = new_status;
-                       }
+               char new_status = data[packet_offset + 0] &
+                                               FTDI_STATUS_B0_MASK;
+               if (new_status != priv->prev_status) {
+                       priv->diff_status |=
+                               new_status ^ priv->prev_status;
+                       wake_up_interruptible(&priv->delta_msr_wait);
+                       priv->prev_status = new_status;
                }
 
-               length = min(PKTSZ, urb->actual_length-packet_offset)-2;
+               length = min_t(u32, PKTSZ, urb->actual_length-packet_offset)-2;
                if (length < 0) {
                        dev_err(&port->dev, "%s - bad packet length: %d\n",
                                __func__, length+2);
@@ -2294,11 +2292,8 @@ static int ftdi_tiocmget(struct tty_struct *tty, struct file *file)
                           FTDI_SIO_GET_MODEM_STATUS_REQUEST_TYPE,
                           0, 0,
                           buf, 1, WDR_TIMEOUT);
-               if (ret < 0) {
-                       dbg("%s Could not get modem status of device - err: %d", __func__,
-                           ret);
+               if (ret < 0)
                        return ret;
-               }
                break;
        case FT8U232AM:
        case FT232BM:
@@ -2313,15 +2308,11 @@ static int ftdi_tiocmget(struct tty_struct *tty, struct file *file)
                                   FTDI_SIO_GET_MODEM_STATUS_REQUEST_TYPE,
                                   0, priv->interface,
                                   buf, 2, WDR_TIMEOUT);
-               if (ret < 0) {
-                       dbg("%s Could not get modem status of device - err: %d", __func__,
-                           ret);
+               if (ret < 0)
                        return ret;
-               }
                break;
        default:
                return -EFAULT;
-               break;
        }
 
        return  (buf[0] & FTDI_SIO_DSR_MASK ? TIOCM_DSR : 0) |
index 814909f1ee630b34092e7e22fa6f764e0a1d9e3a..9d57cace37317a76af1394a86becd676afb97cb6 100644 (file)
@@ -177,14 +177,6 @@ int usb_serial_generic_resume(struct usb_serial *serial)
        struct usb_serial_port *port;
        int i, c = 0, r;
 
-#ifdef CONFIG_PM
-       /*
-        * If this is an autoresume, don't submit URBs.
-        * They will be submitted in the open function instead.
-        */
-       if (serial->dev->auto_pm)
-               return 0;
-#endif
        for (i = 0; i < serial->num_ports; i++) {
                port = serial->port[i];
                if (port->port.count && port->read_urb) {
@@ -196,6 +188,7 @@ int usb_serial_generic_resume(struct usb_serial *serial)
 
        return c ? -EIO : 0;
 }
+EXPORT_SYMBOL_GPL(usb_serial_generic_resume);
 
 void usb_serial_generic_close(struct tty_struct *tty,
                        struct usb_serial_port *port, struct file *filp)
index 132be74d2b890dbe7c868b4cbc33f10cc8311516..ef92095b0732b23ca9e22d79e98acba41f74c9bc 100644 (file)
@@ -78,6 +78,7 @@ static int  ipaq_open(struct tty_struct *tty,
                        struct usb_serial_port *port, struct file *filp);
 static void ipaq_close(struct tty_struct *tty,
                        struct usb_serial_port *port, struct file *filp);
+static int  ipaq_calc_num_ports(struct usb_serial *serial);
 static int  ipaq_startup(struct usb_serial *serial);
 static void ipaq_shutdown(struct usb_serial *serial);
 static int ipaq_write(struct tty_struct *tty, struct usb_serial_port *port,
@@ -572,15 +573,10 @@ static struct usb_serial_driver ipaq_device = {
        .description =          "PocketPC PDA",
        .usb_driver =           &ipaq_driver,
        .id_table =             ipaq_id_table,
-       /*
-        * some devices have an extra endpoint, which
-        * must be ignored as it would make the core
-        * create a second port which oopses when used
-        */
-       .num_ports =            1,
        .open =                 ipaq_open,
        .close =                ipaq_close,
        .attach =               ipaq_startup,
+       .calc_num_ports =       ipaq_calc_num_ports,
        .shutdown =             ipaq_shutdown,
        .write =                ipaq_write,
        .write_room =           ipaq_write_room,
@@ -956,14 +952,49 @@ static void ipaq_destroy_lists(struct usb_serial_port *port)
 }
 
 
+static int ipaq_calc_num_ports(struct usb_serial *serial)
+{
+       /*
+        * some devices have 3 endpoints, the 3rd of which
+        * must be ignored as it would make the core
+        * create a second port which oopses when used
+        */
+       int ipaq_num_ports = 1;
+
+       dbg("%s - numberofendpoints: %d", __FUNCTION__,
+               (int)serial->interface->cur_altsetting->desc.bNumEndpoints);
+
+       /*
+        * a few devices have 4 endpoints, seemingly Yakuma devices,
+        * and we need the second pair, so let them have 2 ports
+        *
+        * TODO: can we drop port 1 ?
+        */
+       if (serial->interface->cur_altsetting->desc.bNumEndpoints > 3) {
+               ipaq_num_ports = 2;
+       }
+
+       return ipaq_num_ports;
+}
+
+
 static int ipaq_startup(struct usb_serial *serial)
 {
        dbg("%s", __func__);
        if (serial->dev->actconfig->desc.bConfigurationValue != 1) {
+               /*
+                * FIXME: HP iPaq rx3715, possibly others, have 1 config that
+                * is labeled as 2
+                */
+
                dev_err(&serial->dev->dev, "active config #%d != 1 ??\n",
                        serial->dev->actconfig->desc.bConfigurationValue);
                return -ENODEV;
        }
+
+       dbg("%s - iPAQ module configured for %d ports",
+               __FUNCTION__, serial->num_ports);
+
        return usb_reset_configuration(serial->dev);
 }
 
index 9878c0fb3859f201345a2171459d31a55baf8831..00daa8f7759a99946fc3a902dc1e46c9a2bf55af 100644 (file)
@@ -1507,7 +1507,7 @@ static struct urb *keyspan_setup_urb(struct usb_serial *serial, int endpoint,
        } else {
                dev_warn(&serial->interface->dev,
                         "unsupported endpoint type %x\n",
-                        ep_desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK);
+                        usb_endpoint_type(ep_desc));
                usb_free_urb(urb);
                return NULL;
        }
index cea326f1f105535886de22ab8353c850929fe43b..839583dc8b6ac33ee0ee9b7ac7465156134caff6 100644 (file)
@@ -1,8 +1,8 @@
 /*
  * Opticon USB barcode to serial driver
  *
- * Copyright (C) 2008 Greg Kroah-Hartman <gregkh@suse.de>
- * Copyright (C) 2008 Novell Inc.
+ * Copyright (C) 2008 - 2009 Greg Kroah-Hartman <gregkh@suse.de>
+ * Copyright (C) 2008 - 2009 Novell Inc.
  *
  *     This program is free software; you can redistribute it and/or
  *     modify it under the terms of the GNU General Public License version
@@ -14,6 +14,7 @@
 #include <linux/tty.h>
 #include <linux/tty_driver.h>
 #include <linux/tty_flip.h>
+#include <linux/serial.h>
 #include <linux/module.h>
 #include <linux/usb.h>
 #include <linux/usb/serial.h>
@@ -40,8 +41,12 @@ struct opticon_private {
        bool throttled;
        bool actually_throttled;
        bool rts;
+       int outstanding_urbs;
 };
 
+/* max number of write urbs in flight */
+#define URB_UPPER_LIMIT        4
+
 static void opticon_bulk_callback(struct urb *urb)
 {
        struct opticon_private *priv = urb->context;
@@ -106,7 +111,6 @@ static void opticon_bulk_callback(struct urb *urb)
                                        priv->rts = false;
                                else
                                        priv->rts = true;
-                               /* FIXME change the RTS level */
                        } else {
                        dev_dbg(&priv->udev->dev,
                                "Unknown data packet received from the device:"
@@ -188,6 +192,120 @@ static void opticon_close(struct tty_struct *tty, struct usb_serial_port *port,
        usb_kill_urb(priv->bulk_read_urb);
 }
 
+static void opticon_write_bulk_callback(struct urb *urb)
+{
+       struct opticon_private *priv = urb->context;
+       int status = urb->status;
+       unsigned long flags;
+
+       /* free up the transfer buffer, as usb_free_urb() does not do this */
+       kfree(urb->transfer_buffer);
+
+       if (status)
+               dbg("%s - nonzero write bulk status received: %d",
+                   __func__, status);
+
+       spin_lock_irqsave(&priv->lock, flags);
+       --priv->outstanding_urbs;
+       spin_unlock_irqrestore(&priv->lock, flags);
+
+       usb_serial_port_softint(priv->port);
+}
+
+static int opticon_write(struct tty_struct *tty, struct usb_serial_port *port,
+                        const unsigned char *buf, int count)
+{
+       struct opticon_private *priv = usb_get_serial_data(port->serial);
+       struct usb_serial *serial = port->serial;
+       struct urb *urb;
+       unsigned char *buffer;
+       unsigned long flags;
+       int status;
+
+       dbg("%s - port %d", __func__, port->number);
+
+       spin_lock_irqsave(&priv->lock, flags);
+       if (priv->outstanding_urbs > URB_UPPER_LIMIT) {
+               spin_unlock_irqrestore(&priv->lock, flags);
+               dbg("%s - write limit hit\n", __func__);
+               return 0;
+       }
+       priv->outstanding_urbs++;
+       spin_unlock_irqrestore(&priv->lock, flags);
+
+       buffer = kmalloc(count, GFP_ATOMIC);
+       if (!buffer) {
+               dev_err(&port->dev, "out of memory\n");
+               count = -ENOMEM;
+               goto error_no_buffer;
+       }
+
+       urb = usb_alloc_urb(0, GFP_ATOMIC);
+       if (!urb) {
+               dev_err(&port->dev, "no more free urbs\n");
+               count = -ENOMEM;
+               goto error_no_urb;
+       }
+
+       memcpy(buffer, buf, count);
+
+       usb_serial_debug_data(debug, &port->dev, __func__, count, buffer);
+
+       usb_fill_bulk_urb(urb, serial->dev,
+                         usb_sndbulkpipe(serial->dev,
+                                         port->bulk_out_endpointAddress),
+                         buffer, count, opticon_write_bulk_callback, priv);
+
+       /* send it down the pipe */
+       status = usb_submit_urb(urb, GFP_ATOMIC);
+       if (status) {
+               dev_err(&port->dev,
+                  "%s - usb_submit_urb(write bulk) failed with status = %d\n",
+                                                       __func__, status);
+               count = status;
+               goto error;
+       }
+
+       /* we are done with this urb, so let the host driver
+        * really free it when it is finished with it */
+       usb_free_urb(urb);
+
+       return count;
+error:
+       usb_free_urb(urb);
+error_no_urb:
+       kfree(buffer);
+error_no_buffer:
+       spin_lock_irqsave(&priv->lock, flags);
+       --priv->outstanding_urbs;
+       spin_unlock_irqrestore(&priv->lock, flags);
+       return count;
+}
+
+static int opticon_write_room(struct tty_struct *tty)
+{
+       struct usb_serial_port *port = tty->driver_data;
+       struct opticon_private *priv = usb_get_serial_data(port->serial);
+       unsigned long flags;
+
+       dbg("%s - port %d", __func__, port->number);
+
+       /*
+        * We really can take almost anything the user throws at us
+        * but let's pick a nice big number to tell the tty
+        * layer that we have lots of free space, unless we don't.
+        */
+       spin_lock_irqsave(&priv->lock, flags);
+       if (priv->outstanding_urbs > URB_UPPER_LIMIT * 2 / 3) {
+               spin_unlock_irqrestore(&priv->lock, flags);
+               dbg("%s - write limit hit\n", __func__);
+               return 0;
+       }
+       spin_unlock_irqrestore(&priv->lock, flags);
+
+       return 2048;
+}
+
 static void opticon_throttle(struct tty_struct *tty)
 {
        struct usb_serial_port *port = tty->driver_data;
@@ -223,6 +341,67 @@ static void opticon_unthrottle(struct tty_struct *tty)
                                                        __func__, result);
 }
 
+static int opticon_tiocmget(struct tty_struct *tty, struct file *file)
+{
+       struct usb_serial_port *port = tty->driver_data;
+       struct opticon_private *priv = usb_get_serial_data(port->serial);
+       unsigned long flags;
+       int result = 0;
+
+       dbg("%s - port %d", __func__, port->number);
+
+       spin_lock_irqsave(&priv->lock, flags);
+       if (priv->rts)
+               result = TIOCM_RTS;
+       spin_unlock_irqrestore(&priv->lock, flags);
+
+       dbg("%s - %x", __func__, result);
+       return result;
+}
+
+static int get_serial_info(struct opticon_private *priv,
+                          struct serial_struct __user *serial)
+{
+       struct serial_struct tmp;
+
+       if (!serial)
+               return -EFAULT;
+
+       memset(&tmp, 0x00, sizeof(tmp));
+
+       /* fake emulate a 16550 uart to make userspace code happy */
+       tmp.type                = PORT_16550A;
+       tmp.line                = priv->serial->minor;
+       tmp.port                = 0;
+       tmp.irq                 = 0;
+       tmp.flags               = ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ;
+       tmp.xmit_fifo_size      = 1024;
+       tmp.baud_base           = 9600;
+       tmp.close_delay         = 5*HZ;
+       tmp.closing_wait        = 30*HZ;
+
+       if (copy_to_user(serial, &tmp, sizeof(*serial)))
+               return -EFAULT;
+       return 0;
+}
+
+static int opticon_ioctl(struct tty_struct *tty, struct file *file,
+                        unsigned int cmd, unsigned long arg)
+{
+       struct usb_serial_port *port = tty->driver_data;
+       struct opticon_private *priv = usb_get_serial_data(port->serial);
+
+       dbg("%s - port %d, cmd = 0x%x", __func__, port->number, cmd);
+
+       switch (cmd) {
+       case TIOCGSERIAL:
+               return get_serial_info(priv,
+                                      (struct serial_struct __user *)arg);
+       }
+
+       return -ENOIOCTLCMD;
+}
+
 static int opticon_startup(struct usb_serial *serial)
 {
        struct opticon_private *priv;
@@ -306,11 +485,37 @@ static void opticon_shutdown(struct usb_serial *serial)
        usb_set_serial_data(serial, NULL);
 }
 
+static int opticon_suspend(struct usb_interface *intf, pm_message_t message)
+{
+       struct usb_serial *serial = usb_get_intfdata(intf);
+       struct opticon_private *priv = usb_get_serial_data(serial);
+
+       usb_kill_urb(priv->bulk_read_urb);
+       return 0;
+}
+
+static int opticon_resume(struct usb_interface *intf)
+{
+       struct usb_serial *serial = usb_get_intfdata(intf);
+       struct opticon_private *priv = usb_get_serial_data(serial);
+       struct usb_serial_port *port = serial->port[0];
+       int result;
+
+       mutex_lock(&port->mutex);
+       if (port->port.count)
+               result = usb_submit_urb(priv->bulk_read_urb, GFP_NOIO);
+       else
+               result = 0;
+       mutex_unlock(&port->mutex);
+       return result;
+}
 
 static struct usb_driver opticon_driver = {
        .name =         "opticon",
        .probe =        usb_serial_probe,
        .disconnect =   usb_serial_disconnect,
+       .suspend =      opticon_suspend,
+       .resume =       opticon_resume,
        .id_table =     id_table,
        .no_dynamic_id =        1,
 };
@@ -326,9 +531,13 @@ static struct usb_serial_driver opticon_device = {
        .attach =               opticon_startup,
        .open =                 opticon_open,
        .close =                opticon_close,
+       .write =                opticon_write,
+       .write_room =           opticon_write_room,
        .shutdown =             opticon_shutdown,
        .throttle =             opticon_throttle,
        .unthrottle =           opticon_unthrottle,
+       .ioctl =                opticon_ioctl,
+       .tiocmget =             opticon_tiocmget,
 };
 
 static int __init opticon_init(void)
index 61ebddc48497092abeba19d9e785258df1e6c7ef..d560c0b54e6e3602b300412873501196ef2c8090 100644 (file)
@@ -62,6 +62,8 @@ static int  option_tiocmget(struct tty_struct *tty, struct file *file);
 static int  option_tiocmset(struct tty_struct *tty, struct file *file,
                                unsigned int set, unsigned int clear);
 static int  option_send_setup(struct tty_struct *tty, struct usb_serial_port *port);
+static int  option_suspend(struct usb_serial *serial, pm_message_t message);
+static int  option_resume(struct usb_serial *serial);
 
 /* Vendor and product IDs */
 #define OPTION_VENDOR_ID                       0x0AF0
@@ -523,6 +525,8 @@ static struct usb_driver option_driver = {
        .name       = "option",
        .probe      = usb_serial_probe,
        .disconnect = usb_serial_disconnect,
+       .suspend    = usb_serial_suspend,
+       .resume     = usb_serial_resume,
        .id_table   = option_ids,
        .no_dynamic_id =        1,
 };
@@ -551,6 +555,8 @@ static struct usb_serial_driver option_1port_device = {
        .attach            = option_startup,
        .shutdown          = option_shutdown,
        .read_int_callback = option_instat_callback,
+       .suspend           = option_suspend,
+       .resume            = option_resume,
 };
 
 static int debug;
@@ -821,10 +827,10 @@ static void option_instat_callback(struct urb *urb)
                                req_pkt->bRequestType, req_pkt->bRequest);
                }
        } else
-               dbg("%s: error %d", __func__, status);
+               err("%s: error %d", __func__, status);
 
        /* Resubmit urb so we continue receiving IRQ data */
-       if (status != -ESHUTDOWN) {
+       if (status != -ESHUTDOWN && status != -ENOENT) {
                urb->dev = serial->dev;
                err = usb_submit_urb(urb, GFP_ATOMIC);
                if (err)
@@ -843,7 +849,6 @@ static int option_write_room(struct tty_struct *tty)
 
        portdata = usb_get_serial_port_data(port);
 
-
        for (i = 0; i < N_OUT_URB; i++) {
                this_urb = portdata->out_urbs[i];
                if (this_urb && !test_bit(i, &portdata->out_busy))
@@ -1105,14 +1110,12 @@ bail_out_error:
        return 1;
 }
 
-static void option_shutdown(struct usb_serial *serial)
+static void stop_read_write_urbs(struct usb_serial *serial)
 {
        int i, j;
        struct usb_serial_port *port;
        struct option_port_private *portdata;
 
-       dbg("%s", __func__);
-
        /* Stop reading/writing urbs */
        for (i = 0; i < serial->num_ports; ++i) {
                port = serial->port[i];
@@ -1122,6 +1125,17 @@ static void option_shutdown(struct usb_serial *serial)
                for (j = 0; j < N_OUT_URB; j++)
                        usb_kill_urb(portdata->out_urbs[j]);
        }
+}
+
+static void option_shutdown(struct usb_serial *serial)
+{
+       int i, j;
+       struct usb_serial_port *port;
+       struct option_port_private *portdata;
+
+       dbg("%s", __func__);
+
+       stop_read_write_urbs(serial);
 
        /* Now free them */
        for (i = 0; i < serial->num_ports; ++i) {
@@ -1152,6 +1166,66 @@ static void option_shutdown(struct usb_serial *serial)
        }
 }
 
+static int option_suspend(struct usb_serial *serial, pm_message_t message)
+{
+       dbg("%s entered", __func__);
+       stop_read_write_urbs(serial);
+
+       return 0;
+}
+
+static int option_resume(struct usb_serial *serial)
+{
+       int err, i, j;
+       struct usb_serial_port *port;
+       struct urb *urb;
+       struct option_port_private *portdata;
+
+       dbg("%s entered", __func__);
+       /* get the interrupt URBs resubmitted unconditionally */
+       for (i = 0; i < serial->num_ports; i++) {
+               port = serial->port[i];
+               if (!port->interrupt_in_urb) {
+                       dbg("%s: No interrupt URB for port %d\n", __func__, i);
+                       continue;
+               }
+               port->interrupt_in_urb->dev = serial->dev;
+               err = usb_submit_urb(port->interrupt_in_urb, GFP_NOIO);
+               dbg("Submitted interrupt URB for port %d (result %d)", i, err);
+               if (err < 0) {
+                       err("%s: Error %d for interrupt URB of port%d",
+                                __func__, err, i);
+                       return err;
+               }
+       }
+
+       for (i = 0; i < serial->num_ports; i++) {
+               /* walk all ports */
+               port = serial->port[i];
+               portdata = usb_get_serial_port_data(port);
+               mutex_lock(&port->mutex);
+
+               /* skip closed ports */
+               if (!port->port.count) {
+                       mutex_unlock(&port->mutex);
+                       continue;
+               }
+
+               for (j = 0; j < N_IN_URB; j++) {
+                       urb = portdata->in_urbs[j];
+                       err = usb_submit_urb(urb, GFP_NOIO);
+                       if (err < 0) {
+                               mutex_unlock(&port->mutex);
+                               err("%s: Error %d for bulk URB %d",
+                                        __func__, err, i);
+                               return err;
+                       }
+               }
+               mutex_unlock(&port->mutex);
+       }
+       return 0;
+}
+
 MODULE_AUTHOR(DRIVER_AUTHOR);
 MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_VERSION(DRIVER_VERSION);
diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c
new file mode 100644 (file)
index 0000000..e6d6b0c
--- /dev/null
@@ -0,0 +1,147 @@
+/*
+ * Qualcomm Serial USB driver
+ *
+ *     Copyright (c) 2008 QUALCOMM Incorporated.
+ *     Copyright (c) 2009 Greg Kroah-Hartman <gregkh@suse.de>
+ *     Copyright (c) 2009 Novell Inc.
+ *
+ *     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/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/usb.h>
+#include <linux/usb/serial.h>
+
+#define DRIVER_AUTHOR "Qualcomm Inc"
+#define DRIVER_DESC "Qualcomm USB Serial driver"
+
+static int debug;
+
+static struct usb_device_id id_table[] = {
+       {USB_DEVICE(0x05c6, 0x9211)},   /* Acer Gobi QDL device */
+       {USB_DEVICE(0x05c6, 0x9212)},   /* Acer Gobi Modem Device */
+       {USB_DEVICE(0x03f0, 0x1f1d)},   /* HP un2400 Gobi Modem Device */
+       {USB_DEVICE(0x03f0, 0x201d)},   /* HP un2400 Gobi QDL Device */
+       { }                             /* Terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, id_table);
+
+static struct usb_driver qcdriver = {
+       .name                   = "qcserial",
+       .probe                  = usb_serial_probe,
+       .disconnect             = usb_serial_disconnect,
+       .id_table               = id_table,
+       .suspend                = usb_serial_suspend,
+       .resume                 = usb_serial_resume,
+       .supports_autosuspend   = true,
+};
+
+static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id)
+{
+       int retval = -ENODEV;
+       __u8 nintf;
+       __u8 ifnum;
+
+       dbg("%s", __func__);
+
+       nintf = serial->dev->actconfig->desc.bNumInterfaces;
+       dbg("Num Interfaces = %d", nintf);
+       ifnum = serial->interface->cur_altsetting->desc.bInterfaceNumber;
+       dbg("This Interface = %d", ifnum);
+
+       switch (nintf) {
+       case 1:
+               /* QDL mode */
+               if (serial->interface->num_altsetting == 2) {
+                       struct usb_host_interface *intf;
+
+                       intf = &serial->interface->altsetting[1];
+                       if (intf->desc.bNumEndpoints == 2) {
+                               if (usb_endpoint_is_bulk_in(&intf->endpoint[0].desc) &&
+                                   usb_endpoint_is_bulk_out(&intf->endpoint[1].desc)) {
+                                       dbg("QDL port found");
+                                       retval = usb_set_interface(serial->dev, ifnum, 1);
+                                       if (retval < 0) {
+                                               dev_err(&serial->dev->dev,
+                                                       "Could not set interface, error %d\n",
+                                                       retval);
+                                               retval = -ENODEV;
+                                       }
+                                       return retval;
+                               }
+                       }
+               }
+               break;
+
+       case 4:
+               /* Composite mode */
+               if (ifnum == 2) {
+                       dbg("Modem port found");
+                       retval = usb_set_interface(serial->dev, ifnum, 0);
+                       if (retval < 0) {
+                               dev_err(&serial->dev->dev,
+                                       "Could not set interface, error %d\n",
+                                       retval);
+                               retval = -ENODEV;
+                       }
+                       return retval;
+               }
+               break;
+
+       default:
+               dev_err(&serial->dev->dev,
+                       "unknown number of interfaces: %d\n", nintf);
+               return -ENODEV;
+       }
+
+       return retval;
+}
+
+static struct usb_serial_driver qcdevice = {
+       .driver = {
+               .owner     = THIS_MODULE,
+               .name      = "qcserial",
+       },
+       .description         = "Qualcomm USB modem",
+       .id_table            = id_table,
+       .usb_driver          = &qcdriver,
+       .num_ports           = 1,
+       .probe               = qcprobe,
+};
+
+static int __init qcinit(void)
+{
+       int retval;
+
+       retval = usb_serial_register(&qcdevice);
+       if (retval)
+               return retval;
+
+       retval = usb_register(&qcdriver);
+       if (retval) {
+               usb_serial_deregister(&qcdevice);
+               return retval;
+       }
+
+       return 0;
+}
+
+static void __exit qcexit(void)
+{
+       usb_deregister(&qcdriver);
+       usb_serial_deregister(&qcdevice);
+}
+
+module_init(qcinit);
+module_exit(qcexit);
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL v2");
+
+module_param(debug, bool, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(debug, "Debug enabled or not");
diff --git a/drivers/usb/serial/symbolserial.c b/drivers/usb/serial/symbolserial.c
new file mode 100644 (file)
index 0000000..8b3cbc8
--- /dev/null
@@ -0,0 +1,399 @@
+/*
+ * Symbol USB barcode to serial driver
+ *
+ * Copyright (C) 2009 Greg Kroah-Hartman <gregkh@suse.de>
+ * Copyright (C) 2009 Novell Inc.
+ *
+ *     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_driver.h>
+#include <linux/tty_flip.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/usb/serial.h>
+#include <linux/uaccess.h>
+
+static int debug;
+
+static struct usb_device_id id_table[] = {
+       { USB_DEVICE(0x05e0, 0x0600) },
+       { },
+};
+MODULE_DEVICE_TABLE(usb, id_table);
+
+/* This structure holds all of the individual device information */
+struct symbol_private {
+       struct usb_device *udev;
+       struct usb_serial *serial;
+       struct usb_serial_port *port;
+       unsigned char *int_buffer;
+       struct urb *int_urb;
+       int buffer_size;
+       u8 bInterval;
+       u8 int_address;
+       spinlock_t lock;        /* protects the following flags */
+       bool throttled;
+       bool actually_throttled;
+       bool rts;
+};
+
+static void symbol_int_callback(struct urb *urb)
+{
+       struct symbol_private *priv = urb->context;
+       unsigned char *data = urb->transfer_buffer;
+       struct usb_serial_port *port = priv->port;
+       int status = urb->status;
+       struct tty_struct *tty;
+       int result;
+       int available_room = 0;
+       int data_length;
+
+       dbg("%s - port %d", __func__, port->number);
+
+       switch (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",
+                   __func__, status);
+               return;
+       default:
+               dbg("%s - nonzero urb status received: %d",
+                   __func__, status);
+               goto exit;
+       }
+
+       usb_serial_debug_data(debug, &port->dev, __func__, urb->actual_length,
+                             data);
+
+       if (urb->actual_length > 1) {
+               data_length = urb->actual_length - 1;
+
+               /*
+                * Data from the device comes with a 1 byte header:
+                *
+                * <size of data>data...
+                *      This is real data to be sent to the tty layer
+                * we pretty much just ignore the size and send everything
+                * else to the tty layer.
+                */
+               tty = tty_port_tty_get(&port->port);
+               if (tty) {
+                       available_room = tty_buffer_request_room(tty,
+                                                       data_length);
+                       if (available_room) {
+                               tty_insert_flip_string(tty, &data[1],
+                                                      available_room);
+                               tty_flip_buffer_push(tty);
+                       }
+                       tty_kref_put(tty);
+               }
+       } else {
+               dev_dbg(&priv->udev->dev,
+                       "Improper ammount of data received from the device, "
+                       "%d bytes", urb->actual_length);
+       }
+
+exit:
+       spin_lock(&priv->lock);
+
+       /* Continue trying to always read if we should */
+       if (!priv->throttled) {
+               usb_fill_int_urb(priv->int_urb, priv->udev,
+                                usb_rcvintpipe(priv->udev,
+                                               priv->int_address),
+                                priv->int_buffer, priv->buffer_size,
+                                symbol_int_callback, priv, priv->bInterval);
+               result = usb_submit_urb(priv->int_urb, GFP_ATOMIC);
+               if (result)
+                       dev_err(&port->dev,
+                           "%s - failed resubmitting read urb, error %d\n",
+                                                       __func__, result);
+       } else
+               priv->actually_throttled = true;
+       spin_unlock(&priv->lock);
+}
+
+static int symbol_open(struct tty_struct *tty, struct usb_serial_port *port,
+                       struct file *filp)
+{
+       struct symbol_private *priv = usb_get_serial_data(port->serial);
+       unsigned long flags;
+       int result = 0;
+
+       dbg("%s - port %d", __func__, port->number);
+
+       spin_lock_irqsave(&priv->lock, flags);
+       priv->throttled = false;
+       priv->actually_throttled = false;
+       priv->port = port;
+       spin_unlock_irqrestore(&priv->lock, flags);
+
+       /*
+        * Force low_latency on so that our tty_push actually forces the data
+        * through, otherwise it is scheduled, and with high data rates (like
+        * with OHCI) data can get lost.
+        */
+       if (tty)
+               tty->low_latency = 1;
+
+       /* Start reading from the device */
+       usb_fill_int_urb(priv->int_urb, priv->udev,
+                        usb_rcvintpipe(priv->udev, priv->int_address),
+                        priv->int_buffer, priv->buffer_size,
+                        symbol_int_callback, priv, priv->bInterval);
+       result = usb_submit_urb(priv->int_urb, GFP_KERNEL);
+       if (result)
+               dev_err(&port->dev,
+                       "%s - failed resubmitting read urb, error %d\n",
+                       __func__, result);
+       return result;
+}
+
+static void symbol_close(struct tty_struct *tty, struct usb_serial_port *port,
+                         struct file *filp)
+{
+       struct symbol_private *priv = usb_get_serial_data(port->serial);
+
+       dbg("%s - port %d", __func__, port->number);
+
+       /* shutdown our urbs */
+       usb_kill_urb(priv->int_urb);
+}
+
+static void symbol_throttle(struct tty_struct *tty)
+{
+       struct usb_serial_port *port = tty->driver_data;
+       struct symbol_private *priv = usb_get_serial_data(port->serial);
+       unsigned long flags;
+
+       dbg("%s - port %d", __func__, port->number);
+       spin_lock_irqsave(&priv->lock, flags);
+       priv->throttled = true;
+       spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+static void symbol_unthrottle(struct tty_struct *tty)
+{
+       struct usb_serial_port *port = tty->driver_data;
+       struct symbol_private *priv = usb_get_serial_data(port->serial);
+       unsigned long flags;
+       int result;
+
+       dbg("%s - port %d", __func__, port->number);
+
+       spin_lock_irqsave(&priv->lock, flags);
+       priv->throttled = false;
+       priv->actually_throttled = false;
+       spin_unlock_irqrestore(&priv->lock, flags);
+
+       priv->int_urb->dev = port->serial->dev;
+       result = usb_submit_urb(priv->int_urb, GFP_ATOMIC);
+       if (result)
+               dev_err(&port->dev,
+                       "%s - failed submitting read urb, error %d\n",
+                                                       __func__, result);
+}
+
+static int symbol_ioctl(struct tty_struct *tty, struct file *file,
+                       unsigned int cmd, unsigned long arg)
+{
+       struct usb_serial_port *port = tty->driver_data;
+       struct device *dev = &port->dev;
+
+       /*
+        * Right now we need to figure out what commands
+        * most userspace tools want to see for this driver,
+        * so just log the things.
+        */
+       switch (cmd) {
+       case TIOCSERGETLSR:
+               dev_info(dev, "%s: TIOCSERGETLSR\n", __func__);
+               break;
+
+       case TIOCGSERIAL:
+               dev_info(dev, "%s: TIOCGSERIAL\n", __func__);
+               break;
+
+       case TIOCMIWAIT:
+               dev_info(dev, "%s: TIOCMIWAIT\n", __func__);
+               break;
+
+       case TIOCGICOUNT:
+               dev_info(dev, "%s: TIOCGICOUNT\n", __func__);
+               break;
+       default:
+               dev_info(dev, "%s: unknown (%d)\n", __func__, cmd);
+       }
+       return -ENOIOCTLCMD;
+}
+
+static int symbol_tiocmget(struct tty_struct *tty, struct file *file)
+{
+       struct usb_serial_port *port = tty->driver_data;
+       struct device *dev = &port->dev;
+
+       /* TODO */
+       /* probably just need to shadow whatever was sent to us here */
+       dev_info(dev, "%s\n", __func__);
+       return 0;
+}
+
+static int symbol_tiocmset(struct tty_struct *tty, struct file *file,
+                          unsigned int set, unsigned int clear)
+{
+       struct usb_serial_port *port = tty->driver_data;
+       struct device *dev = &port->dev;
+
+       /* TODO */
+       /* probably just need to shadow whatever was sent to us here */
+       dev_info(dev, "%s\n", __func__);
+       return 0;
+}
+
+static int symbol_startup(struct usb_serial *serial)
+{
+       struct symbol_private *priv;
+       struct usb_host_interface *intf;
+       int i;
+       int retval = -ENOMEM;
+       bool int_in_found = false;
+
+       /* create our private serial structure */
+       priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+       if (priv == NULL) {
+               dev_err(&serial->dev->dev, "%s - Out of memory\n", __func__);
+               return -ENOMEM;
+       }
+       spin_lock_init(&priv->lock);
+       priv->serial = serial;
+       priv->port = serial->port[0];
+       priv->udev = serial->dev;
+
+       /* find our interrupt endpoint */
+       intf = serial->interface->altsetting;
+       for (i = 0; i < intf->desc.bNumEndpoints; ++i) {
+               struct usb_endpoint_descriptor *endpoint;
+
+               endpoint = &intf->endpoint[i].desc;
+               if (!usb_endpoint_is_int_in(endpoint))
+                       continue;
+
+               priv->int_urb = usb_alloc_urb(0, GFP_KERNEL);
+               if (!priv->int_urb) {
+                       dev_err(&priv->udev->dev, "out of memory\n");
+                       goto error;
+               }
+
+               priv->buffer_size = le16_to_cpu(endpoint->wMaxPacketSize) * 2;
+               priv->int_buffer = kmalloc(priv->buffer_size, GFP_KERNEL);
+               if (!priv->int_buffer) {
+                       dev_err(&priv->udev->dev, "out of memory\n");
+                       goto error;
+               }
+
+               priv->int_address = endpoint->bEndpointAddress;
+               priv->bInterval = endpoint->bInterval;
+
+               /* set up our int urb */
+               usb_fill_int_urb(priv->int_urb, priv->udev,
+                                usb_rcvintpipe(priv->udev,
+                                               endpoint->bEndpointAddress),
+                                priv->int_buffer, priv->buffer_size,
+                                symbol_int_callback, priv, priv->bInterval);
+
+               int_in_found = true;
+               break;
+               }
+
+       if (!int_in_found) {
+               dev_err(&priv->udev->dev,
+                       "Error - the proper endpoints were not found!\n");
+               goto error;
+       }
+
+       usb_set_serial_data(serial, priv);
+       return 0;
+
+error:
+       usb_free_urb(priv->int_urb);
+       kfree(priv->int_buffer);
+       kfree(priv);
+       return retval;
+}
+
+static void symbol_shutdown(struct usb_serial *serial)
+{
+       struct symbol_private *priv = usb_get_serial_data(serial);
+
+       dbg("%s", __func__);
+
+       usb_kill_urb(priv->int_urb);
+       usb_free_urb(priv->int_urb);
+       kfree(priv->int_buffer);
+       kfree(priv);
+       usb_set_serial_data(serial, NULL);
+}
+
+static struct usb_driver symbol_driver = {
+       .name =                 "symbol",
+       .probe =                usb_serial_probe,
+       .disconnect =           usb_serial_disconnect,
+       .id_table =             id_table,
+       .no_dynamic_id =        1,
+};
+
+static struct usb_serial_driver symbol_device = {
+       .driver = {
+               .owner =        THIS_MODULE,
+               .name =         "symbol",
+       },
+       .id_table =             id_table,
+       .usb_driver =           &symbol_driver,
+       .num_ports =            1,
+       .attach =               symbol_startup,
+       .open =                 symbol_open,
+       .close =                symbol_close,
+       .shutdown =             symbol_shutdown,
+       .throttle =             symbol_throttle,
+       .unthrottle =           symbol_unthrottle,
+       .ioctl =                symbol_ioctl,
+       .tiocmget =             symbol_tiocmget,
+       .tiocmset =             symbol_tiocmset,
+};
+
+static int __init symbol_init(void)
+{
+       int retval;
+
+       retval = usb_serial_register(&symbol_device);
+       if (retval)
+               return retval;
+       retval = usb_register(&symbol_driver);
+       if (retval)
+               usb_serial_deregister(&symbol_device);
+       return retval;
+}
+
+static void __exit symbol_exit(void)
+{
+       usb_deregister(&symbol_driver);
+       usb_serial_deregister(&symbol_device);
+}
+
+module_init(symbol_init);
+module_exit(symbol_exit);
+MODULE_LICENSE("GPL");
+
+module_param(debug, bool, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(debug, "Debug enabled or not");
index cfcfd5ab06ceb5838f6bdc274e78a30697714d1a..742a5bc44be8670bdaa1bfc06a93ccbfcc9cfc9a 100644 (file)
@@ -204,6 +204,11 @@ static int serial_open (struct tty_struct *tty, struct file *filp)
                goto bailout_kref_put;
        }
 
+       if (port->serial->disconnected) {
+               retval = -ENODEV;
+               goto bailout_kref_put;
+       }
+
        if (mutex_lock_interruptible(&port->mutex)) {
                retval = -ERESTARTSYS;
                goto bailout_kref_put;
@@ -1067,6 +1072,8 @@ int usb_serial_suspend(struct usb_interface *intf, pm_message_t message)
        struct usb_serial_port *port;
        int i, r = 0;
 
+       serial->suspending = 1;
+
        for (i = 0; i < serial->num_ports; ++i) {
                port = serial->port[i];
                if (port)
@@ -1083,10 +1090,15 @@ EXPORT_SYMBOL(usb_serial_suspend);
 int usb_serial_resume(struct usb_interface *intf)
 {
        struct usb_serial *serial = usb_get_intfdata(intf);
+       int rv;
 
+       serial->suspending = 0;
        if (serial->type->resume)
-               return serial->type->resume(serial);
-       return 0;
+               rv = serial->type->resume(serial);
+       else
+               rv = usb_serial_generic_resume(serial);
+
+       return rv;
 }
 EXPORT_SYMBOL(usb_serial_resume);
 
@@ -1222,7 +1234,6 @@ static void fixup_generic(struct usb_serial_driver *device)
        set_to_generic_if_null(device, read_bulk_callback);
        set_to_generic_if_null(device, write_bulk_callback);
        set_to_generic_if_null(device, shutdown);
-       set_to_generic_if_null(device, resume);
 }
 
 int usb_serial_register(struct usb_serial_driver *driver)
@@ -1230,6 +1241,9 @@ int usb_serial_register(struct usb_serial_driver *driver)
        /* must be called with BKL held */
        int retval;
 
+       if (usb_disabled())
+               return -ENODEV;
+
        fixup_generic(driver);
 
        if (!driver->description)
index 9df6887b91f6bb7c157e878c7f87406a42609b93..8a372bac0e435cf4d57e0a588904bb5d918347f5 100644 (file)
@@ -2,8 +2,8 @@
 # USB Storage driver configuration
 #
 
-comment "NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;"
-comment "see USB_STORAGE Help for more information"
+comment "NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may"
+comment "also be needed; see USB_STORAGE Help for more info"
        depends on USB
 
 config USB_STORAGE
@@ -32,21 +32,25 @@ config USB_STORAGE_DEBUG
          verbose debugging messages.
 
 config USB_STORAGE_DATAFAB
-       bool "Datafab Compact Flash Reader support"
+       tristate "Datafab Compact Flash Reader support"
        depends on USB_STORAGE
        help
          Support for certain Datafab CompactFlash readers.
          Datafab has a web page at <http://www.datafabusa.com/>.
 
+         If this driver is compiled as a module, it will be named ums-datafab.
+
 config USB_STORAGE_FREECOM
-       bool "Freecom USB/ATAPI Bridge support"
+       tristate "Freecom USB/ATAPI Bridge support"
        depends on USB_STORAGE
        help
          Support for the Freecom USB to IDE/ATAPI adaptor.
          Freecom has a web page at <http://www.freecom.de/>.
 
+         If this driver is compiled as a module, it will be named ums-freecom.
+
 config USB_STORAGE_ISD200
-       bool "ISD-200 USB/ATA Bridge support"
+       tristate "ISD-200 USB/ATA Bridge support"
        depends on USB_STORAGE
        ---help---
          Say Y here if you want to use USB Mass Store devices based
@@ -61,8 +65,10 @@ config USB_STORAGE_ISD200
          - CyQ've CQ8060A CDRW drive
          - Planex eXtreme Drive RX-25HU USB-IDE cable (not model RX-25U)
 
+         If this driver is compiled as a module, it will be named ums-isd200.
+
 config USB_STORAGE_USBAT
-       bool "USBAT/USBAT02-based storage support"
+       tristate "USBAT/USBAT02-based storage support"
        depends on USB_STORAGE
        help
          Say Y here to include additional code to support storage devices
@@ -82,30 +88,38 @@ config USB_STORAGE_USBAT
          - RCA LYRA MP3 portable
          - Sandisk ImageMate SDDR-05b
 
+         If this driver is compiled as a module, it will be named ums-usbat.
+
 config USB_STORAGE_SDDR09
-       bool "SanDisk SDDR-09 (and other SmartMedia, including DPCM) support"
+       tristate "SanDisk SDDR-09 (and other SmartMedia, including DPCM) support"
        depends on USB_STORAGE
        help
          Say Y here to include additional code to support the Sandisk SDDR-09
          SmartMedia reader in the USB Mass Storage driver.
          Also works for the Microtech Zio! CompactFlash/SmartMedia reader.
 
+         If this driver is compiled as a module, it will be named ums-sddr09.
+
 config USB_STORAGE_SDDR55
-       bool "SanDisk SDDR-55 SmartMedia support"
+       tristate "SanDisk SDDR-55 SmartMedia support"
        depends on USB_STORAGE
        help
          Say Y here to include additional code to support the Sandisk SDDR-55
          SmartMedia reader in the USB Mass Storage driver.
 
+         If this driver is compiled as a module, it will be named ums-sddr55.
+
 config USB_STORAGE_JUMPSHOT
-       bool "Lexar Jumpshot Compact Flash Reader"
+       tristate "Lexar Jumpshot Compact Flash Reader"
        depends on USB_STORAGE
        help
          Say Y here to include additional code to support the Lexar Jumpshot
          USB CompactFlash reader.
 
+         If this driver is compiled as a module, it will be named ums-jumpshot.
+
 config USB_STORAGE_ALAUDA
-       bool "Olympus MAUSB-10/Fuji DPC-R1 support"
+       tristate "Olympus MAUSB-10/Fuji DPC-R1 support"
        depends on USB_STORAGE
        help
          Say Y here to include additional code to support the Olympus MAUSB-10
@@ -114,8 +128,10 @@ config USB_STORAGE_ALAUDA
          These devices are based on the Alauda chip and support both
          XD and SmartMedia cards.
 
+         If this driver is compiled as a module, it will be named ums-alauda.
+
 config USB_STORAGE_ONETOUCH
-       bool "Support OneTouch Button on Maxtor Hard Drives"
+       tristate "Support OneTouch Button on Maxtor Hard Drives"
        depends on USB_STORAGE
        depends on INPUT=y || INPUT=USB_STORAGE
        help
@@ -127,8 +143,10 @@ config USB_STORAGE_ONETOUCH
          this input in any keybinding software. (e.g. gnome's keyboard short-
          cuts)
 
+         If this driver is compiled as a module, it will be named ums-onetouch.
+
 config USB_STORAGE_KARMA
-       bool "Support for Rio Karma music player"
+       tristate "Support for Rio Karma music player"
        depends on USB_STORAGE
        help
          Say Y here to include additional code to support the Rio Karma
@@ -139,8 +157,10 @@ config USB_STORAGE_KARMA
          on the resulting scsi device node returns the Karma to normal
          operation.
 
+         If this driver is compiled as a module, it will be named ums-karma.
+
 config USB_STORAGE_CYPRESS_ATACB
-       bool "SAT emulation on Cypress USB/ATA Bridge with ATACB"
+       tristate "SAT emulation on Cypress USB/ATA Bridge with ATACB"
        depends on USB_STORAGE
        ---help---
          Say Y here if you want to use SAT (ata pass through) on devices based
@@ -150,6 +170,8 @@ config USB_STORAGE_CYPRESS_ATACB
          If you say no here your device will still work with the standard usb
          mass storage class.
 
+         If this driver is compiled as a module, it will be named ums-cypress.
+
 config USB_LIBUSUAL
        bool "The shared table of common (or usual) storage devices"
        depends on USB
index b32069313390865900b39e2b92c2a36e201aa5ca..5be54c01966219608675b8338cf8d114d7d0cf59 100644 (file)
@@ -10,21 +10,36 @@ EXTRA_CFLAGS        := -Idrivers/scsi
 obj-$(CONFIG_USB_STORAGE)      += usb-storage.o
 
 usb-storage-obj-$(CONFIG_USB_STORAGE_DEBUG)    += debug.o
-usb-storage-obj-$(CONFIG_USB_STORAGE_USBAT)    += shuttle_usbat.o
-usb-storage-obj-$(CONFIG_USB_STORAGE_SDDR09)   += sddr09.o
-usb-storage-obj-$(CONFIG_USB_STORAGE_SDDR55)   += sddr55.o
-usb-storage-obj-$(CONFIG_USB_STORAGE_FREECOM)  += freecom.o
-usb-storage-obj-$(CONFIG_USB_STORAGE_ISD200)   += isd200.o
-usb-storage-obj-$(CONFIG_USB_STORAGE_DATAFAB)  += datafab.o
-usb-storage-obj-$(CONFIG_USB_STORAGE_JUMPSHOT) += jumpshot.o
-usb-storage-obj-$(CONFIG_USB_STORAGE_ALAUDA)   += alauda.o
-usb-storage-obj-$(CONFIG_USB_STORAGE_ONETOUCH) += onetouch.o
-usb-storage-obj-$(CONFIG_USB_STORAGE_KARMA)    += karma.o
-usb-storage-obj-$(CONFIG_USB_STORAGE_CYPRESS_ATACB) += cypress_atacb.o
 
 usb-storage-objs :=    scsiglue.o protocol.o transport.o usb.o \
                        initializers.o sierra_ms.o option_ms.o $(usb-storage-obj-y)
 
-ifneq ($(CONFIG_USB_LIBUSUAL),)
-       obj-$(CONFIG_USB)       += libusual.o
+ifeq ($(CONFIG_USB_LIBUSUAL),)
+       usb-storage-objs        += usual-tables.o
+else
+       obj-$(CONFIG_USB)       += libusual.o usual-tables.o
 endif
+
+obj-$(CONFIG_USB_STORAGE_ALAUDA)       += ums-alauda.o
+obj-$(CONFIG_USB_STORAGE_CYPRESS_ATACB) += ums-cypress.o
+obj-$(CONFIG_USB_STORAGE_DATAFAB)      += ums-datafab.o
+obj-$(CONFIG_USB_STORAGE_FREECOM)      += ums-freecom.o
+obj-$(CONFIG_USB_STORAGE_ISD200)       += ums-isd200.o
+obj-$(CONFIG_USB_STORAGE_JUMPSHOT)     += ums-jumpshot.o
+obj-$(CONFIG_USB_STORAGE_KARMA)                += ums-karma.o
+obj-$(CONFIG_USB_STORAGE_ONETOUCH)     += ums-onetouch.o
+obj-$(CONFIG_USB_STORAGE_SDDR09)       += ums-sddr09.o
+obj-$(CONFIG_USB_STORAGE_SDDR55)       += ums-sddr55.o
+obj-$(CONFIG_USB_STORAGE_USBAT)                += ums-usbat.o
+
+ums-alauda-objs                := alauda.o
+ums-cypress-objs       := cypress_atacb.o
+ums-datafab-objs       := datafab.o
+ums-freecom-objs       := freecom.o
+ums-isd200-objs                := isd200.o
+ums-jumpshot-objs      := jumpshot.o
+ums-karma-objs         := karma.o
+ums-onetouch-objs      := onetouch.o
+ums-sddr09-objs                := sddr09.o
+ums-sddr55-objs                := sddr55.o
+ums-usbat-objs         := shuttle_usbat.o
index 8d3711a7ff0655aa519811a295b6b57c2b8b0253..67edc65acb8efc69e8a214fd032aa4da7c6eebaf 100644 (file)
@@ -31,6 +31,8 @@
  * 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+#include <linux/module.h>
+
 #include <scsi/scsi.h>
 #include <scsi/scsi_cmnd.h>
 #include <scsi/scsi_device.h>
 #include "transport.h"
 #include "protocol.h"
 #include "debug.h"
-#include "alauda.h"
+
+MODULE_DESCRIPTION("Driver for Alauda-based card readers");
+MODULE_AUTHOR("Daniel Drake <dsd@gentoo.org>");
+MODULE_LICENSE("GPL");
+
+/*
+ * Status bytes
+ */
+#define ALAUDA_STATUS_ERROR            0x01
+#define ALAUDA_STATUS_READY            0x40
+
+/*
+ * Control opcodes (for request field)
+ */
+#define ALAUDA_GET_XD_MEDIA_STATUS     0x08
+#define ALAUDA_GET_SM_MEDIA_STATUS     0x98
+#define ALAUDA_ACK_XD_MEDIA_CHANGE     0x0a
+#define ALAUDA_ACK_SM_MEDIA_CHANGE     0x9a
+#define ALAUDA_GET_XD_MEDIA_SIG                0x86
+#define ALAUDA_GET_SM_MEDIA_SIG                0x96
+
+/*
+ * Bulk command identity (byte 0)
+ */
+#define ALAUDA_BULK_CMD                        0x40
+
+/*
+ * Bulk opcodes (byte 1)
+ */
+#define ALAUDA_BULK_GET_REDU_DATA      0x85
+#define ALAUDA_BULK_READ_BLOCK         0x94
+#define ALAUDA_BULK_ERASE_BLOCK                0xa3
+#define ALAUDA_BULK_WRITE_BLOCK                0xb4
+#define ALAUDA_BULK_GET_STATUS2                0xb7
+#define ALAUDA_BULK_RESET_MEDIA                0xe0
+
+/*
+ * Port to operate on (byte 8)
+ */
+#define ALAUDA_PORT_XD                 0x00
+#define ALAUDA_PORT_SM                 0x01
+
+/*
+ * LBA and PBA are unsigned ints. Special values.
+ */
+#define UNDEF    0xffff
+#define SPARE    0xfffe
+#define UNUSABLE 0xfffd
+
+struct alauda_media_info {
+       unsigned long capacity;         /* total media size in bytes */
+       unsigned int pagesize;          /* page size in bytes */
+       unsigned int blocksize;         /* number of pages per block */
+       unsigned int uzonesize;         /* number of usable blocks per zone */
+       unsigned int zonesize;          /* number of blocks per zone */
+       unsigned int blockmask;         /* mask to get page from address */
+
+       unsigned char pageshift;
+       unsigned char blockshift;
+       unsigned char zoneshift;
+
+       u16 **lba_to_pba;               /* logical to physical block map */
+       u16 **pba_to_lba;               /* physical to logical block map */
+};
+
+struct alauda_info {
+       struct alauda_media_info port[2];
+       int wr_ep;                      /* endpoint to write data out of */
+
+       unsigned char sense_key;
+       unsigned long sense_asc;        /* additional sense code */
+       unsigned long sense_ascq;       /* additional sense code qualifier */
+};
 
 #define short_pack(lsb,msb) ( ((u16)(lsb)) | ( ((u16)(msb))<<8 ) )
 #define LSB_of(s) ((s)&0xFF)
 #define PBA_HI(pba) (pba >> 3)
 #define PBA_ZONE(pba) (pba >> 11)
 
+static int init_alauda(struct us_data *us);
+
+
+/*
+ * The table of devices
+ */
+#define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \
+                   vendorName, productName, useProtocol, useTransport, \
+                   initFunction, flags) \
+{ USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \
+  .driver_info = (flags)|(USB_US_TYPE_STOR<<24) }
+
+struct usb_device_id alauda_usb_ids[] = {
+#      include "unusual_alauda.h"
+       { }             /* Terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, alauda_usb_ids);
+
+#undef UNUSUAL_DEV
+
+/*
+ * The flags table
+ */
+#define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \
+                   vendor_name, product_name, use_protocol, use_transport, \
+                   init_function, Flags) \
+{ \
+       .vendorName = vendor_name,      \
+       .productName = product_name,    \
+       .useProtocol = use_protocol,    \
+       .useTransport = use_transport,  \
+       .initFunction = init_function,  \
+}
+
+static struct us_unusual_dev alauda_unusual_dev_list[] = {
+#      include "unusual_alauda.h"
+       { }             /* Terminating entry */
+};
+
+#undef UNUSUAL_DEV
+
+
 /*
  * Media handling
  */
@@ -307,7 +423,8 @@ static int alauda_init_media(struct us_data *us)
                data[0], data[1], data[2], data[3]);
        media_info = alauda_card_find_id(data[1]);
        if (media_info == NULL) {
-               printk("alauda_init_media: Unrecognised media signature: "
+               printk(KERN_WARNING
+                       "alauda_init_media: Unrecognised media signature: "
                        "%02X %02X %02X %02X\n",
                        data[0], data[1], data[2], data[3]);
                return USB_STOR_TRANSPORT_ERROR;
@@ -518,7 +635,8 @@ static int alauda_read_map(struct us_data *us, unsigned int zone)
 
                /* check even parity */
                if (parity[data[6] ^ data[7]]) {
-                       printk("alauda_read_map: Bad parity in LBA for block %d"
+                       printk(KERN_WARNING
+                              "alauda_read_map: Bad parity in LBA for block %d"
                               " (%02X %02X)\n", i, data[6], data[7]);
                        pba_to_lba[i] = UNUSABLE;
                        continue;
@@ -538,13 +656,16 @@ static int alauda_read_map(struct us_data *us, unsigned int zone)
                 */
 
                if (lba_offset >= uzonesize) {
-                       printk("alauda_read_map: Bad low LBA %d for block %d\n",
+                       printk(KERN_WARNING
+                              "alauda_read_map: Bad low LBA %d for block %d\n",
                               lba_real, blocknum);
                        continue;
                }
 
                if (lba_to_pba[lba_offset] != UNDEF) {
-                       printk("alauda_read_map: LBA %d seen for PBA %d and %d\n",
+                       printk(KERN_WARNING
+                              "alauda_read_map: "
+                              "LBA %d seen for PBA %d and %d\n",
                               lba_real, lba_to_pba[lba_offset], blocknum);
                        continue;
                }
@@ -712,13 +833,15 @@ static int alauda_write_lba(struct us_data *us, u16 lba,
        if (pba == 1) {
                /* Maybe it is impossible to write to PBA 1.
                   Fake success, but don't do anything. */
-               printk("alauda_write_lba: avoid writing to pba 1\n");
+               printk(KERN_WARNING
+                      "alauda_write_lba: avoid writing to pba 1\n");
                return USB_STOR_TRANSPORT_GOOD;
        }
 
        new_pba = alauda_find_unused_pba(&MEDIA_INFO(us), zone);
        if (!new_pba) {
-               printk("alauda_write_lba: Out of unused blocks\n");
+               printk(KERN_WARNING
+                      "alauda_write_lba: Out of unused blocks\n");
                return USB_STOR_TRANSPORT_ERROR;
        }
 
@@ -818,7 +941,7 @@ static int alauda_read_data(struct us_data *us, unsigned long address,
        len = min(sectors, blocksize) * (pagesize + 64);
        buffer = kmalloc(len, GFP_NOIO);
        if (buffer == NULL) {
-               printk("alauda_read_data: Out of memory\n");
+               printk(KERN_WARNING "alauda_read_data: Out of memory\n");
                return USB_STOR_TRANSPORT_ERROR;
        }
 
@@ -911,7 +1034,7 @@ static int alauda_write_data(struct us_data *us, unsigned long address,
        len = min(sectors, blocksize) * pagesize;
        buffer = kmalloc(len, GFP_NOIO);
        if (buffer == NULL) {
-               printk("alauda_write_data: Out of memory\n");
+               printk(KERN_WARNING "alauda_write_data: Out of memory\n");
                return USB_STOR_TRANSPORT_ERROR;
        }
 
@@ -921,7 +1044,7 @@ static int alauda_write_data(struct us_data *us, unsigned long address,
         */
        blockbuffer = kmalloc((pagesize + 64) * blocksize, GFP_NOIO);
        if (blockbuffer == NULL) {
-               printk("alauda_write_data: Out of memory\n");
+               printk(KERN_WARNING "alauda_write_data: Out of memory\n");
                kfree(buffer);
                return USB_STOR_TRANSPORT_ERROR;
        }
@@ -991,7 +1114,7 @@ static void alauda_info_destructor(void *extra)
 /*
  * Initialize alauda_info struct and find the data-write endpoint
  */
-int init_alauda(struct us_data *us)
+static int init_alauda(struct us_data *us)
 {
        struct alauda_info *info;
        struct usb_host_interface *altsetting = us->pusb_intf->cur_altsetting;
@@ -1013,7 +1136,7 @@ int init_alauda(struct us_data *us)
        return USB_STOR_TRANSPORT_GOOD;
 }
 
-int alauda_transport(struct scsi_cmnd *srb, struct us_data *us)
+static int alauda_transport(struct scsi_cmnd *srb, struct us_data *us)
 {
        int rc;
        struct alauda_info *info = (struct alauda_info *) us->extra;
@@ -1121,3 +1244,48 @@ int alauda_transport(struct scsi_cmnd *srb, struct us_data *us)
        return USB_STOR_TRANSPORT_FAILED;
 }
 
+static int alauda_probe(struct usb_interface *intf,
+                        const struct usb_device_id *id)
+{
+       struct us_data *us;
+       int result;
+
+       result = usb_stor_probe1(&us, intf, id,
+                       (id - alauda_usb_ids) + alauda_unusual_dev_list);
+       if (result)
+               return result;
+
+       us->transport_name  = "Alauda Control/Bulk";
+       us->transport = alauda_transport;
+       us->transport_reset = usb_stor_Bulk_reset;
+       us->max_lun = 1;
+
+       result = usb_stor_probe2(us);
+       return result;
+}
+
+static struct usb_driver alauda_driver = {
+       .name =         "ums-alauda",
+       .probe =        alauda_probe,
+       .disconnect =   usb_stor_disconnect,
+       .suspend =      usb_stor_suspend,
+       .resume =       usb_stor_resume,
+       .reset_resume = usb_stor_reset_resume,
+       .pre_reset =    usb_stor_pre_reset,
+       .post_reset =   usb_stor_post_reset,
+       .id_table =     alauda_usb_ids,
+       .soft_unbind =  1,
+};
+
+static int __init alauda_init(void)
+{
+       return usb_register(&alauda_driver);
+}
+
+static void __exit alauda_exit(void)
+{
+       usb_deregister(&alauda_driver);
+}
+
+module_init(alauda_init);
+module_exit(alauda_exit);
diff --git a/drivers/usb/storage/alauda.h b/drivers/usb/storage/alauda.h
deleted file mode 100644 (file)
index a700f87..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Driver for Alauda-based card readers
- *
- * Current development and maintenance by:
- *    (c) 2005 Daniel Drake <dsd@gentoo.org>
- *
- * See alauda.c for more explanation.
- *
- * 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_ALAUDA_H
-#define _USB_ALAUDA_H
-
-/*
- * Status bytes
- */
-#define ALAUDA_STATUS_ERROR            0x01
-#define ALAUDA_STATUS_READY            0x40
-
-/*
- * Control opcodes (for request field)
- */
-#define ALAUDA_GET_XD_MEDIA_STATUS     0x08
-#define ALAUDA_GET_SM_MEDIA_STATUS     0x98
-#define ALAUDA_ACK_XD_MEDIA_CHANGE     0x0a
-#define ALAUDA_ACK_SM_MEDIA_CHANGE     0x9a
-#define ALAUDA_GET_XD_MEDIA_SIG                0x86
-#define ALAUDA_GET_SM_MEDIA_SIG                0x96
-
-/*
- * Bulk command identity (byte 0)
- */
-#define ALAUDA_BULK_CMD                        0x40
-
-/*
- * Bulk opcodes (byte 1)
- */
-#define ALAUDA_BULK_GET_REDU_DATA      0x85
-#define ALAUDA_BULK_READ_BLOCK         0x94
-#define ALAUDA_BULK_ERASE_BLOCK                0xa3
-#define ALAUDA_BULK_WRITE_BLOCK                0xb4
-#define ALAUDA_BULK_GET_STATUS2                0xb7
-#define ALAUDA_BULK_RESET_MEDIA                0xe0
-
-/*
- * Port to operate on (byte 8)
- */
-#define ALAUDA_PORT_XD                 0x00
-#define ALAUDA_PORT_SM                 0x01
-
-/*
- * LBA and PBA are unsigned ints. Special values.
- */
-#define UNDEF    0xffff
-#define SPARE    0xfffe
-#define UNUSABLE 0xfffd
-
-int init_alauda(struct us_data *us);
-int alauda_transport(struct scsi_cmnd *srb, struct us_data *us);
-
-struct alauda_media_info {
-       unsigned long capacity;         /* total media size in bytes */
-       unsigned int pagesize;          /* page size in bytes */
-       unsigned int blocksize;         /* number of pages per block */
-       unsigned int uzonesize;         /* number of usable blocks per zone */
-       unsigned int zonesize;          /* number of blocks per zone */
-       unsigned int blockmask;         /* mask to get page from address */
-
-       unsigned char pageshift;
-       unsigned char blockshift;
-       unsigned char zoneshift;
-
-       u16 **lba_to_pba;               /* logical to physical block map */
-       u16 **pba_to_lba;               /* physical to logical block map */
-};
-
-struct alauda_info {
-       struct alauda_media_info port[2];
-       int wr_ep;                      /* endpoint to write data out of */
-
-       unsigned char sense_key;
-       unsigned long sense_asc;        /* additional sense code */
-       unsigned long sense_ascq;       /* additional sense code qualifier */
-};
-
-#endif
-
index 898e67d30e563bfc4b8a11cf1715cee5a1edec56..c8447182118374b62ef78f5bcf1b27c26b41a5f9 100644 (file)
@@ -19,6 +19,7 @@
  * 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+#include <linux/module.h>
 #include <scsi/scsi.h>
 #include <scsi/scsi_cmnd.h>
 #include <scsi/scsi_eh.h>
 #include "scsiglue.h"
 #include "debug.h"
 
+MODULE_DESCRIPTION("SAT support for Cypress USB/ATA bridges with ATACB");
+MODULE_AUTHOR("Matthieu Castet <castet.matthieu@free.fr>");
+MODULE_LICENSE("GPL");
+
+/*
+ * The table of devices
+ */
+#define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \
+                   vendorName, productName, useProtocol, useTransport, \
+                   initFunction, flags) \
+{ USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \
+  .driver_info = (flags)|(USB_US_TYPE_STOR<<24) }
+
+struct usb_device_id cypress_usb_ids[] = {
+#      include "unusual_cypress.h"
+       { }             /* Terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, cypress_usb_ids);
+
+#undef UNUSUAL_DEV
+
+/*
+ * The flags table
+ */
+#define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \
+                   vendor_name, product_name, use_protocol, use_transport, \
+                   init_function, Flags) \
+{ \
+       .vendorName = vendor_name,      \
+       .productName = product_name,    \
+       .useProtocol = use_protocol,    \
+       .useTransport = use_transport,  \
+       .initFunction = init_function,  \
+}
+
+static struct us_unusual_dev cypress_unusual_dev_list[] = {
+#      include "unusual_cypress.h"
+       { }             /* Terminating entry */
+};
+
+#undef UNUSUAL_DEV
+
+
 /*
  * ATACB is a protocol used on cypress usb<->ata bridge to
  * send raw ATA command over mass storage
@@ -36,7 +80,7 @@
  * More info that be found on cy7c68310_8.pdf and cy7c68300c_8.pdf
  * datasheet from cypress.com.
  */
-void cypress_atacb_passthrough(struct scsi_cmnd *srb, struct us_data *us)
+static void cypress_atacb_passthrough(struct scsi_cmnd *srb, struct us_data *us)
 {
        unsigned char save_cmnd[MAX_COMMAND_SIZE];
 
@@ -133,19 +177,18 @@ void cypress_atacb_passthrough(struct scsi_cmnd *srb, struct us_data *us)
 
                /* build the command for
                 * reading the ATA registers */
-               scsi_eh_prep_cmnd(srb, &ses, NULL, 0, 0);
-               srb->sdb.length = sizeof(regs);
-               sg_init_one(&ses.sense_sgl, regs, srb->sdb.length);
-               srb->sdb.table.sgl = &ses.sense_sgl;
-               srb->sc_data_direction = DMA_FROM_DEVICE;
-               srb->sdb.table.nents = 1;
+               scsi_eh_prep_cmnd(srb, &ses, NULL, 0, sizeof(regs));
+
                /* we use the same command as before, but we set
                 * the read taskfile bit, for not executing atacb command,
                 * but reading register selected in srb->cmnd[4]
                 */
+               srb->cmd_len = 16;
+               srb->cmnd = ses.cmnd;
                srb->cmnd[2] = 1;
 
                usb_stor_transparent_scsi_command(srb, us);
+               memcpy(regs, srb->sense_buffer, sizeof(regs));
                tmp_result = srb->result;
                scsi_eh_restore_cmnd(srb, &ses);
                /* we fail to get registers, report invalid command */
@@ -162,8 +205,8 @@ void cypress_atacb_passthrough(struct scsi_cmnd *srb, struct us_data *us)
 
                /* XXX we should generate sk, asc, ascq from status and error
                 * regs
-                * (see 11.1 Error translation Â­ ATA device error to SCSI error map)
-                * and ata_to_sense_error from libata.
+                * (see 11.1 Error translation ATA device error to SCSI error
+                *  map, and ata_to_sense_error from libata.)
                 */
 
                /* Sense data is current and format is descriptor. */
@@ -198,3 +241,48 @@ end:
        if (srb->cmnd[0] == ATA_12)
                srb->cmd_len = 12;
 }
+
+
+static int cypress_probe(struct usb_interface *intf,
+                        const struct usb_device_id *id)
+{
+       struct us_data *us;
+       int result;
+
+       result = usb_stor_probe1(&us, intf, id,
+                       (id - cypress_usb_ids) + cypress_unusual_dev_list);
+       if (result)
+               return result;
+
+       us->protocol_name = "Transparent SCSI with Cypress ATACB";
+       us->proto_handler = cypress_atacb_passthrough;
+
+       result = usb_stor_probe2(us);
+       return result;
+}
+
+static struct usb_driver cypress_driver = {
+       .name =         "ums-cypress",
+       .probe =        cypress_probe,
+       .disconnect =   usb_stor_disconnect,
+       .suspend =      usb_stor_suspend,
+       .resume =       usb_stor_resume,
+       .reset_resume = usb_stor_reset_resume,
+       .pre_reset =    usb_stor_pre_reset,
+       .post_reset =   usb_stor_post_reset,
+       .id_table =     cypress_usb_ids,
+       .soft_unbind =  1,
+};
+
+static int __init cypress_init(void)
+{
+       return usb_register(&cypress_driver);
+}
+
+static void __exit cypress_exit(void)
+{
+       usb_deregister(&cypress_driver);
+}
+
+module_init(cypress_init);
+module_exit(cypress_exit);
index 17f1ae232919ebc5123e778f6c10d404f7651d49..2b6e565262c24d3801b418b7c1b2d529d4e694b3 100644 (file)
@@ -49,6 +49,7 @@
  */
 
 #include <linux/errno.h>
+#include <linux/module.h>
 #include <linux/slab.h>
 
 #include <scsi/scsi.h>
 #include "transport.h"
 #include "protocol.h"
 #include "debug.h"
-#include "datafab.h"
+
+MODULE_DESCRIPTION("Driver for Datafab USB Compact Flash reader");
+MODULE_AUTHOR("Jimmie Mayfield <mayfield+datafab@sackheads.org>");
+MODULE_LICENSE("GPL");
+
+struct datafab_info {
+       unsigned long   sectors;        /* total sector count */
+       unsigned long   ssize;          /* sector size in bytes */
+       signed char     lun;            /* used for dual-slot readers */
+
+       /* the following aren't used yet */
+       unsigned char   sense_key;
+       unsigned long   sense_asc;      /* additional sense code */
+       unsigned long   sense_ascq;     /* additional sense code qualifier */
+};
 
 static int datafab_determine_lun(struct us_data *us,
                                 struct datafab_info *info);
 
 
+/*
+ * The table of devices
+ */
+#define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \
+                   vendorName, productName, useProtocol, useTransport, \
+                   initFunction, flags) \
+{ USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \
+  .driver_info = (flags)|(USB_US_TYPE_STOR<<24) }
+
+struct usb_device_id datafab_usb_ids[] = {
+#      include "unusual_datafab.h"
+       { }             /* Terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, datafab_usb_ids);
+
+#undef UNUSUAL_DEV
+
+/*
+ * The flags table
+ */
+#define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \
+                   vendor_name, product_name, use_protocol, use_transport, \
+                   init_function, Flags) \
+{ \
+       .vendorName = vendor_name,      \
+       .productName = product_name,    \
+       .useProtocol = use_protocol,    \
+       .useTransport = use_transport,  \
+       .initFunction = init_function,  \
+}
+
+static struct us_unusual_dev datafab_unusual_dev_list[] = {
+#      include "unusual_datafab.h"
+       { }             /* Terminating entry */
+};
+
+#undef UNUSUAL_DEV
+
+
 static inline int
 datafab_bulk_read(struct us_data *us, unsigned char *data, unsigned int len) {
        if (len == 0)
@@ -500,7 +554,7 @@ static void datafab_info_destructor(void *extra)
 
 // Transport for the Datafab MDCFE-B
 //
-int datafab_transport(struct scsi_cmnd * srb, struct us_data *us)
+static int datafab_transport(struct scsi_cmnd *srb, struct us_data *us)
 {
        struct datafab_info *info;
        int rc;
@@ -665,3 +719,49 @@ int datafab_transport(struct scsi_cmnd * srb, struct us_data *us)
        info->sense_ascq = 0x00;
        return USB_STOR_TRANSPORT_FAILED;
 }
+
+static int datafab_probe(struct usb_interface *intf,
+                        const struct usb_device_id *id)
+{
+       struct us_data *us;
+       int result;
+
+       result = usb_stor_probe1(&us, intf, id,
+                       (id - datafab_usb_ids) + datafab_unusual_dev_list);
+       if (result)
+               return result;
+
+       us->transport_name  = "Datafab Bulk-Only";
+       us->transport = datafab_transport;
+       us->transport_reset = usb_stor_Bulk_reset;
+       us->max_lun = 1;
+
+       result = usb_stor_probe2(us);
+       return result;
+}
+
+static struct usb_driver datafab_driver = {
+       .name =         "ums-datafab",
+       .probe =        datafab_probe,
+       .disconnect =   usb_stor_disconnect,
+       .suspend =      usb_stor_suspend,
+       .resume =       usb_stor_resume,
+       .reset_resume = usb_stor_reset_resume,
+       .pre_reset =    usb_stor_pre_reset,
+       .post_reset =   usb_stor_post_reset,
+       .id_table =     datafab_usb_ids,
+       .soft_unbind =  1,
+};
+
+static int __init datafab_init(void)
+{
+       return usb_register(&datafab_driver);
+}
+
+static void __exit datafab_exit(void)
+{
+       usb_deregister(&datafab_driver);
+}
+
+module_init(datafab_init);
+module_exit(datafab_exit);
diff --git a/drivers/usb/storage/datafab.h b/drivers/usb/storage/datafab.h
deleted file mode 100644 (file)
index 32e3f27..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/* Driver for Datafab MDCFE-B USB Compact Flash reader
- * Header File
- *
- * Current development and maintenance by:
- *   (c) 2000 Jimmie Mayfield (mayfield+datafab@sackheads.org)
- *
- * See datafab.c for more explanation
- *
- * 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_DATAFAB_MDCFE_B_H
-#define _USB_DATAFAB_MDCFE_B_H
-
-extern int datafab_transport(struct scsi_cmnd *srb, struct us_data *us);
-
-struct datafab_info {
-       unsigned long   sectors;        // total sector count
-       unsigned long   ssize;          // sector size in bytes
-       signed char     lun;            // used for dual-slot readers
-       
-       // the following aren't used yet
-       unsigned char   sense_key;
-       unsigned long   sense_asc;      // additional sense code
-       unsigned long   sense_ascq;     // additional sense code qualifier
-};
-
-#endif
index 73ac7262239e510ad9af1ec62883b4d588ca0332..54cc94277acbb7dbb8962723c4510d1a2ea70aa8 100644 (file)
@@ -26,6 +26,7 @@
  * (http://www.freecom.de/)
  */
 
+#include <linux/module.h>
 #include <scsi/scsi.h>
 #include <scsi/scsi_cmnd.h>
 
 #include "transport.h"
 #include "protocol.h"
 #include "debug.h"
-#include "freecom.h"
+
+MODULE_DESCRIPTION("Driver for Freecom USB/IDE adaptor");
+MODULE_AUTHOR("David Brown <usb-storage@davidb.org>");
+MODULE_LICENSE("GPL");
 
 #ifdef CONFIG_USB_STORAGE_DEBUG
 static void pdump (void *, int);
@@ -103,6 +107,47 @@ struct freecom_status {
 #define FCM_PACKET_LENGTH              64
 #define FCM_STATUS_PACKET_LENGTH       4
 
+static int init_freecom(struct us_data *us);
+
+
+/*
+ * The table of devices
+ */
+#define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \
+                   vendorName, productName, useProtocol, useTransport, \
+                   initFunction, flags) \
+{ USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \
+  .driver_info = (flags)|(USB_US_TYPE_STOR<<24) }
+
+struct usb_device_id freecom_usb_ids[] = {
+#      include "unusual_freecom.h"
+       { }             /* Terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, freecom_usb_ids);
+
+#undef UNUSUAL_DEV
+
+/*
+ * The flags table
+ */
+#define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \
+                   vendor_name, product_name, use_protocol, use_transport, \
+                   init_function, Flags) \
+{ \
+       .vendorName = vendor_name,      \
+       .productName = product_name,    \
+       .useProtocol = use_protocol,    \
+       .useTransport = use_transport,  \
+       .initFunction = init_function,  \
+}
+
+static struct us_unusual_dev freecom_unusual_dev_list[] = {
+#      include "unusual_freecom.h"
+       { }             /* Terminating entry */
+};
+
+#undef UNUSUAL_DEV
+
 static int
 freecom_readdata (struct scsi_cmnd *srb, struct us_data *us,
                unsigned int ipipe, unsigned int opipe, int count)
@@ -173,7 +218,7 @@ freecom_writedata (struct scsi_cmnd *srb, struct us_data *us,
  * Transport for the Freecom USB/IDE adaptor.
  *
  */
-int freecom_transport(struct scsi_cmnd *srb, struct us_data *us)
+static int freecom_transport(struct scsi_cmnd *srb, struct us_data *us)
 {
        struct freecom_cb_wrap *fcb;
        struct freecom_status  *fst;
@@ -377,8 +422,7 @@ int freecom_transport(struct scsi_cmnd *srb, struct us_data *us)
        return USB_STOR_TRANSPORT_GOOD;
 }
 
-int
-freecom_init (struct us_data *us)
+static int init_freecom(struct us_data *us)
 {
        int result;
        char *buffer = us->iobuf;
@@ -417,7 +461,7 @@ freecom_init (struct us_data *us)
        return USB_STOR_TRANSPORT_GOOD;
 }
 
-int usb_stor_freecom_reset(struct us_data *us)
+static int usb_stor_freecom_reset(struct us_data *us)
 {
        printk (KERN_CRIT "freecom reset called\n");
 
@@ -479,3 +523,48 @@ static void pdump (void *ibuffer, int length)
 }
 #endif
 
+static int freecom_probe(struct usb_interface *intf,
+                        const struct usb_device_id *id)
+{
+       struct us_data *us;
+       int result;
+
+       result = usb_stor_probe1(&us, intf, id,
+                       (id - freecom_usb_ids) + freecom_unusual_dev_list);
+       if (result)
+               return result;
+
+       us->transport_name = "Freecom";
+       us->transport = freecom_transport;
+       us->transport_reset = usb_stor_freecom_reset;
+       us->max_lun = 0;
+
+       result = usb_stor_probe2(us);
+       return result;
+}
+
+static struct usb_driver freecom_driver = {
+       .name =         "ums-freecom",
+       .probe =        freecom_probe,
+       .disconnect =   usb_stor_disconnect,
+       .suspend =      usb_stor_suspend,
+       .resume =       usb_stor_resume,
+       .reset_resume = usb_stor_reset_resume,
+       .pre_reset =    usb_stor_pre_reset,
+       .post_reset =   usb_stor_post_reset,
+       .id_table =     freecom_usb_ids,
+       .soft_unbind =  1,
+};
+
+static int __init freecom_init(void)
+{
+       return usb_register(&freecom_driver);
+}
+
+static void __exit freecom_exit(void)
+{
+       usb_deregister(&freecom_driver);
+}
+
+module_init(freecom_init);
+module_exit(freecom_exit);
index 383abf2516a520a6756c99349a854fb9ee89a2ab..882c57b399f7d94944ac93011807e4380bda6df6 100644 (file)
@@ -44,6 +44,7 @@
 
 #include <linux/jiffies.h>
 #include <linux/errno.h>
+#include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/hdreg.h>
 #include <linux/scatterlist.h>
 #include "protocol.h"
 #include "debug.h"
 #include "scsiglue.h"
-#include "isd200.h"
+
+MODULE_DESCRIPTION("Driver for In-System Design, Inc. ISD200 ASIC");
+MODULE_AUTHOR("Björn Stenberg <bjorn@haxx.se>");
+MODULE_LICENSE("GPL");
+
+static int isd200_Initialization(struct us_data *us);
+
+
+/*
+ * The table of devices
+ */
+#define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \
+                   vendorName, productName, useProtocol, useTransport, \
+                   initFunction, flags) \
+{ USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \
+  .driver_info = (flags)|(USB_US_TYPE_STOR<<24) }
+
+struct usb_device_id isd200_usb_ids[] = {
+#      include "unusual_isd200.h"
+       { }             /* Terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, isd200_usb_ids);
+
+#undef UNUSUAL_DEV
+#undef USUAL_DEV
+
+/*
+ * The flags table
+ */
+#define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \
+                   vendor_name, product_name, use_protocol, use_transport, \
+                   init_function, Flags) \
+{ \
+       .vendorName = vendor_name,      \
+       .productName = product_name,    \
+       .useProtocol = use_protocol,    \
+       .useTransport = use_transport,  \
+       .initFunction = init_function,  \
+}
+
+static struct us_unusual_dev isd200_unusual_dev_list[] = {
+#      include "unusual_isd200.h"
+       { }             /* Terminating entry */
+};
+
+#undef UNUSUAL_DEV
+#undef USUAL_DEV
 
 
 /* Timeout defines (in Seconds) */
@@ -1518,7 +1565,7 @@ static int isd200_init_info(struct us_data *us)
  * Initialization for the ISD200 
  */
 
-int isd200_Initialization(struct us_data *us)
+static int isd200_Initialization(struct us_data *us)
 {
        US_DEBUGP("ISD200 Initialization...\n");
 
@@ -1549,7 +1596,7 @@ int isd200_Initialization(struct us_data *us)
  *
  */
 
-void isd200_ata_command(struct scsi_cmnd *srb, struct us_data *us)
+static void isd200_ata_command(struct scsi_cmnd *srb, struct us_data *us)
 {
        int sendToTransport = 1, orig_bufflen;
        union ata_cdb ataCdb;
@@ -1570,3 +1617,47 @@ void isd200_ata_command(struct scsi_cmnd *srb, struct us_data *us)
 
        isd200_srb_set_bufflen(srb, orig_bufflen);
 }
+
+static int isd200_probe(struct usb_interface *intf,
+                        const struct usb_device_id *id)
+{
+       struct us_data *us;
+       int result;
+
+       result = usb_stor_probe1(&us, intf, id,
+                       (id - isd200_usb_ids) + isd200_unusual_dev_list);
+       if (result)
+               return result;
+
+       us->protocol_name = "ISD200 ATA/ATAPI";
+       us->proto_handler = isd200_ata_command;
+
+       result = usb_stor_probe2(us);
+       return result;
+}
+
+static struct usb_driver isd200_driver = {
+       .name =         "ums-isd200",
+       .probe =        isd200_probe,
+       .disconnect =   usb_stor_disconnect,
+       .suspend =      usb_stor_suspend,
+       .resume =       usb_stor_resume,
+       .reset_resume = usb_stor_reset_resume,
+       .pre_reset =    usb_stor_pre_reset,
+       .post_reset =   usb_stor_post_reset,
+       .id_table =     isd200_usb_ids,
+       .soft_unbind =  1,
+};
+
+static int __init isd200_init(void)
+{
+       return usb_register(&isd200_driver);
+}
+
+static void __exit isd200_exit(void)
+{
+       usb_deregister(&isd200_driver);
+}
+
+module_init(isd200_init);
+module_exit(isd200_exit);
index df67f13c9e73ebcc3dc85a8d354acd0568d7e145..1c69420e3acfbca73efd926d10d2f592dfdc685d 100644 (file)
@@ -46,6 +46,7 @@
   */
 
 #include <linux/errno.h>
+#include <linux/module.h>
 #include <linux/slab.h>
 
 #include <scsi/scsi.h>
 #include "transport.h"
 #include "protocol.h"
 #include "debug.h"
-#include "jumpshot.h"
 
 
+MODULE_DESCRIPTION("Driver for Lexar \"Jumpshot\" Compact Flash reader");
+MODULE_AUTHOR("Jimmie Mayfield <mayfield+usb@sackheads.org>");
+MODULE_LICENSE("GPL");
+
+/*
+ * The table of devices
+ */
+#define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \
+                   vendorName, productName, useProtocol, useTransport, \
+                   initFunction, flags) \
+{ USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \
+  .driver_info = (flags)|(USB_US_TYPE_STOR<<24) }
+
+struct usb_device_id jumpshot_usb_ids[] = {
+#      include "unusual_jumpshot.h"
+       { }             /* Terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, jumpshot_usb_ids);
+
+#undef UNUSUAL_DEV
+
+/*
+ * The flags table
+ */
+#define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \
+                   vendor_name, product_name, use_protocol, use_transport, \
+                   init_function, Flags) \
+{ \
+       .vendorName = vendor_name,      \
+       .productName = product_name,    \
+       .useProtocol = use_protocol,    \
+       .useTransport = use_transport,  \
+       .initFunction = init_function,  \
+}
+
+static struct us_unusual_dev jumpshot_unusual_dev_list[] = {
+#      include "unusual_jumpshot.h"
+       { }             /* Terminating entry */
+};
+
+#undef UNUSUAL_DEV
+
+
+struct jumpshot_info {
+   unsigned long   sectors;     /* total sector count */
+   unsigned long   ssize;       /* sector size in bytes */
+
+   /* the following aren't used yet */
+   unsigned char   sense_key;
+   unsigned long   sense_asc;   /* additional sense code */
+   unsigned long   sense_ascq;  /* additional sense code qualifier */
+};
+
 static inline int jumpshot_bulk_read(struct us_data *us,
                                     unsigned char *data, 
                                     unsigned int len)
@@ -429,7 +482,7 @@ static void jumpshot_info_destructor(void *extra)
 
 // Transport for the Lexar 'Jumpshot'
 //
-int jumpshot_transport(struct scsi_cmnd * srb, struct us_data *us)
+static int jumpshot_transport(struct scsi_cmnd *srb, struct us_data *us)
 {
        struct jumpshot_info *info;
        int rc;
@@ -592,3 +645,49 @@ int jumpshot_transport(struct scsi_cmnd * srb, struct us_data *us)
        info->sense_ascq = 0x00;
        return USB_STOR_TRANSPORT_FAILED;
 }
+
+static int jumpshot_probe(struct usb_interface *intf,
+                        const struct usb_device_id *id)
+{
+       struct us_data *us;
+       int result;
+
+       result = usb_stor_probe1(&us, intf, id,
+                       (id - jumpshot_usb_ids) + jumpshot_unusual_dev_list);
+       if (result)
+               return result;
+
+       us->transport_name  = "Lexar Jumpshot Control/Bulk";
+       us->transport = jumpshot_transport;
+       us->transport_reset = usb_stor_Bulk_reset;
+       us->max_lun = 1;
+
+       result = usb_stor_probe2(us);
+       return result;
+}
+
+static struct usb_driver jumpshot_driver = {
+       .name =         "ums-jumpshot",
+       .probe =        jumpshot_probe,
+       .disconnect =   usb_stor_disconnect,
+       .suspend =      usb_stor_suspend,
+       .resume =       usb_stor_resume,
+       .reset_resume = usb_stor_reset_resume,
+       .pre_reset =    usb_stor_pre_reset,
+       .post_reset =   usb_stor_post_reset,
+       .id_table =     jumpshot_usb_ids,
+       .soft_unbind =  1,
+};
+
+static int __init jumpshot_init(void)
+{
+       return usb_register(&jumpshot_driver);
+}
+
+static void __exit jumpshot_exit(void)
+{
+       usb_deregister(&jumpshot_driver);
+}
+
+module_init(jumpshot_init);
+module_exit(jumpshot_exit);
diff --git a/drivers/usb/storage/jumpshot.h b/drivers/usb/storage/jumpshot.h
deleted file mode 100644 (file)
index 19bac9d..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/* Driver for Lexar "Jumpshot" USB Compact Flash reader
- * Header File
- *
- * Current development and maintenance by:
- *   (c) 2000 Jimmie Mayfield (mayfield+usb@sackheads.org)
- *
- * See jumpshot.c for more explanation
- *
- * 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_JUMPSHOT_H
-#define _USB_JUMPSHOT_H
-
-extern int jumpshot_transport(struct scsi_cmnd *srb, struct us_data *us);
-
-struct jumpshot_info {
-   unsigned long   sectors;     // total sector count
-   unsigned long   ssize;       // sector size in bytes
-   // the following aren't used yet
-   unsigned char   sense_key;
-   unsigned long   sense_asc;   // additional sense code
-   unsigned long   sense_ascq;  // additional sense code qualifier
-};
-
-#endif
index 0d79ae5683f76eaa0e76410b5734a1f15ce77f88..7953d93a7739bd6ac5d89902a7f257e3c8d3c37d 100644 (file)
@@ -18,6 +18,8 @@
  * 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+#include <linux/module.h>
+
 #include <scsi/scsi.h>
 #include <scsi/scsi_cmnd.h>
 #include <scsi/scsi_device.h>
 #include "usb.h"
 #include "transport.h"
 #include "debug.h"
-#include "karma.h"
+
+MODULE_DESCRIPTION("Driver for Rio Karma");
+MODULE_AUTHOR("Bob Copeland <me@bobcopeland.com>, Keith Bennett <keith@mcs.st-and.ac.uk>");
+MODULE_LICENSE("GPL");
 
 #define RIO_PREFIX "RIOP\x00"
 #define RIO_PREFIX_LEN 5
 #define RIO_LEAVE_STORAGE 0x2
 #define RIO_RESET 0xC
 
-extern int usb_stor_Bulk_transport(struct scsi_cmnd *, struct us_data *);
-
 struct karma_data {
        int in_storage;
        char *recv;
 };
 
+static int rio_karma_init(struct us_data *us);
+
+
+/*
+ * The table of devices
+ */
+#define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \
+                   vendorName, productName, useProtocol, useTransport, \
+                   initFunction, flags) \
+{ USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \
+  .driver_info = (flags)|(USB_US_TYPE_STOR<<24) }
+
+struct usb_device_id karma_usb_ids[] = {
+#      include "unusual_karma.h"
+       { }             /* Terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, karma_usb_ids);
+
+#undef UNUSUAL_DEV
+
+/*
+ * The flags table
+ */
+#define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \
+                   vendor_name, product_name, use_protocol, use_transport, \
+                   init_function, Flags) \
+{ \
+       .vendorName = vendor_name,      \
+       .productName = product_name,    \
+       .useProtocol = use_protocol,    \
+       .useTransport = use_transport,  \
+       .initFunction = init_function,  \
+}
+
+static struct us_unusual_dev karma_unusual_dev_list[] = {
+#      include "unusual_karma.h"
+       { }             /* Terminating entry */
+};
+
+#undef UNUSUAL_DEV
+
+
 /*
  * Send commands to Rio Karma.
  *
@@ -104,7 +149,7 @@ err:
  * Trap START_STOP and READ_10 to leave/re-enter storage mode.
  * Everything else is propagated to the normal bulk layer.
  */
-int rio_karma_transport(struct scsi_cmnd *srb, struct us_data *us)
+static int rio_karma_transport(struct scsi_cmnd *srb, struct us_data *us)
 {
        int ret;
        struct karma_data *data = (struct karma_data *) us->extra;
@@ -133,7 +178,7 @@ static void rio_karma_destructor(void *extra)
        kfree(data->recv);
 }
 
-int rio_karma_init(struct us_data *us)
+static int rio_karma_init(struct us_data *us)
 {
        int ret = 0;
        struct karma_data *data = kzalloc(sizeof(struct karma_data), GFP_NOIO);
@@ -153,3 +198,48 @@ int rio_karma_init(struct us_data *us)
 out:
        return ret;
 }
+
+static int karma_probe(struct usb_interface *intf,
+                        const struct usb_device_id *id)
+{
+       struct us_data *us;
+       int result;
+
+       result = usb_stor_probe1(&us, intf, id,
+                       (id - karma_usb_ids) + karma_unusual_dev_list);
+       if (result)
+               return result;
+
+       us->transport_name = "Rio Karma/Bulk";
+       us->transport = rio_karma_transport;
+       us->transport_reset = usb_stor_Bulk_reset;
+
+       result = usb_stor_probe2(us);
+       return result;
+}
+
+static struct usb_driver karma_driver = {
+       .name =         "ums-karma",
+       .probe =        karma_probe,
+       .disconnect =   usb_stor_disconnect,
+       .suspend =      usb_stor_suspend,
+       .resume =       usb_stor_resume,
+       .reset_resume = usb_stor_reset_resume,
+       .pre_reset =    usb_stor_pre_reset,
+       .post_reset =   usb_stor_post_reset,
+       .id_table =     karma_usb_ids,
+       .soft_unbind =  1,
+};
+
+static int __init karma_init(void)
+{
+       return usb_register(&karma_driver);
+}
+
+static void __exit karma_exit(void)
+{
+       usb_deregister(&karma_driver);
+}
+
+module_init(karma_init);
+module_exit(karma_exit);
diff --git a/drivers/usb/storage/karma.h b/drivers/usb/storage/karma.h
deleted file mode 100644 (file)
index 8a60972..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef _KARMA_USB_H
-#define _KARMA_USB_H
-
-extern int rio_karma_init(struct us_data *us);
-extern int rio_karma_transport(struct scsi_cmnd *srb, struct us_data *us);
-
-#endif
index f970b27ba3083ef6cbd4ae62a477caab6d74eae8..fe3ffe1459b224c0b90220db0347b143bb72a56a 100644 (file)
@@ -37,37 +37,6 @@ static atomic_t total_threads = ATOMIC_INIT(0);
 
 static int usu_probe_thread(void *arg);
 
-/*
- * The table.
- */
-#define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \
-                   vendorName, productName,useProtocol, useTransport, \
-                   initFunction, flags) \
-{ USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin,bcdDeviceMax), \
-  .driver_info = (flags)|(USB_US_TYPE_STOR<<24) }
-
-#define COMPLIANT_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \
-                   vendorName, productName, useProtocol, useTransport, \
-                   initFunction, flags) \
-{ USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \
-  .driver_info = (flags) }
-
-#define USUAL_DEV(useProto, useTrans, useType) \
-{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, useProto, useTrans), \
-  .driver_info = ((useType)<<24) }
-
-struct usb_device_id storage_usb_ids [] = {
-#      include "unusual_devs.h"
-       { } /* Terminating entry */
-};
-
-#undef USUAL_DEV
-#undef UNUSUAL_DEV
-#undef COMPLIANT_DEV
-
-MODULE_DEVICE_TABLE(usb, storage_usb_ids);
-EXPORT_SYMBOL_GPL(storage_usb_ids);
-
 /*
  * @type: the module type as an integer
  */
@@ -167,7 +136,7 @@ static struct usb_driver usu_driver = {
        .name =         "libusual",
        .probe =        usu_probe,
        .disconnect =   usu_disconnect,
-       .id_table =     storage_usb_ids,
+       .id_table =     usb_storage_usb_ids,
 };
 
 /*
index c7bf8954b4e4de35af0be81e9d7244ed9881eb16..380233bd6a393c3522655922297849fa346f3f7a 100644 (file)
 #include <linux/module.h>
 #include <linux/usb/input.h>
 #include "usb.h"
-#include "onetouch.h"
 #include "debug.h"
 
+MODULE_DESCRIPTION("Maxtor USB OneTouch hard drive button driver");
+MODULE_AUTHOR("Nick Sillik <n.sillik@temple.edu>");
+MODULE_LICENSE("GPL");
+
+#define ONETOUCH_PKT_LEN        0x02
+#define ONETOUCH_BUTTON         KEY_PROG1
+
+static int onetouch_connect_input(struct us_data *ss);
 static void onetouch_release_input(void *onetouch_);
 
 struct usb_onetouch {
@@ -52,6 +59,46 @@ struct usb_onetouch {
        unsigned int is_open:1;
 };
 
+
+/*
+ * The table of devices
+ */
+#define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \
+                   vendorName, productName, useProtocol, useTransport, \
+                   initFunction, flags) \
+{ USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \
+  .driver_info = (flags)|(USB_US_TYPE_STOR<<24) }
+
+struct usb_device_id onetouch_usb_ids[] = {
+#      include "unusual_onetouch.h"
+       { }             /* Terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, onetouch_usb_ids);
+
+#undef UNUSUAL_DEV
+
+/*
+ * The flags table
+ */
+#define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \
+                   vendor_name, product_name, use_protocol, use_transport, \
+                   init_function, Flags) \
+{ \
+       .vendorName = vendor_name,      \
+       .productName = product_name,    \
+       .useProtocol = use_protocol,    \
+       .useTransport = use_transport,  \
+       .initFunction = init_function,  \
+}
+
+static struct us_unusual_dev onetouch_unusual_dev_list[] = {
+#      include "unusual_onetouch.h"
+       { }             /* Terminating entry */
+};
+
+#undef UNUSUAL_DEV
+
+
 static void usb_onetouch_irq(struct urb *urb)
 {
        struct usb_onetouch *onetouch = urb->context;
@@ -127,7 +174,7 @@ static void usb_onetouch_pm_hook(struct us_data *us, int action)
 }
 #endif /* CONFIG_PM */
 
-int onetouch_connect_input(struct us_data *ss)
+static int onetouch_connect_input(struct us_data *ss)
 {
        struct usb_device *udev = ss->pusb_dev;
        struct usb_host_interface *interface;
@@ -236,3 +283,46 @@ static void onetouch_release_input(void *onetouch_)
                                onetouch->data, onetouch->data_dma);
        }
 }
+
+static int onetouch_probe(struct usb_interface *intf,
+                        const struct usb_device_id *id)
+{
+       struct us_data *us;
+       int result;
+
+       result = usb_stor_probe1(&us, intf, id,
+                       (id - onetouch_usb_ids) + onetouch_unusual_dev_list);
+       if (result)
+               return result;
+
+       /* Use default transport and protocol */
+
+       result = usb_stor_probe2(us);
+       return result;
+}
+
+static struct usb_driver onetouch_driver = {
+       .name =         "ums-onetouch",
+       .probe =        onetouch_probe,
+       .disconnect =   usb_stor_disconnect,
+       .suspend =      usb_stor_suspend,
+       .resume =       usb_stor_resume,
+       .reset_resume = usb_stor_reset_resume,
+       .pre_reset =    usb_stor_pre_reset,
+       .post_reset =   usb_stor_post_reset,
+       .id_table =     onetouch_usb_ids,
+       .soft_unbind =  1,
+};
+
+static int __init onetouch_init(void)
+{
+       return usb_register(&onetouch_driver);
+}
+
+static void __exit onetouch_exit(void)
+{
+       usb_deregister(&onetouch_driver);
+}
+
+module_init(onetouch_init);
+module_exit(onetouch_exit);
diff --git a/drivers/usb/storage/onetouch.h b/drivers/usb/storage/onetouch.h
deleted file mode 100644 (file)
index 41c7aa8..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-#ifndef _ONETOUCH_H_
-#define _ONETOUCH_H_
-
-#define ONETOUCH_PKT_LEN        0x02
-#define ONETOUCH_BUTTON         KEY_PROG1
-
-int onetouch_connect_input(struct us_data *ss);
-
-#endif
index be441d84bc6460db0b56a89c067010a4804eb9e9..fc310f75eada97c0c64da9d5886882eef9631dbf 100644 (file)
@@ -121,6 +121,7 @@ void usb_stor_transparent_scsi_command(struct scsi_cmnd *srb,
        /* send the command to the transport layer */
        usb_stor_invoke_transport(srb, us);
 }
+EXPORT_SYMBOL_GPL(usb_stor_transparent_scsi_command);
 
 /***********************************************************************
  * Scatter-gather transfer buffer access routines
@@ -199,6 +200,7 @@ unsigned int usb_stor_access_xfer_buf(unsigned char *buffer,
        /* Return the amount actually transferred */
        return cnt;
 }
+EXPORT_SYMBOL_GPL(usb_stor_access_xfer_buf);
 
 /* Store the contents of buffer into srb's transfer buffer and set the
  * SCSI residue.
@@ -215,3 +217,4 @@ void usb_stor_set_xfer_buf(unsigned char *buffer,
        if (buflen < scsi_bufflen(srb))
                scsi_set_resid(srb, scsi_bufflen(srb) - buflen);
 }
+EXPORT_SYMBOL_GPL(usb_stor_set_xfer_buf);
index 727c506417ccb1fd275fb2aab3f15037b0016fba..4ca3b586064375c939ae195e260221b519ed06d0 100644 (file)
@@ -135,6 +135,12 @@ static int slave_configure(struct scsi_device *sdev)
                if (sdev->request_queue->max_sectors > max_sectors)
                        blk_queue_max_sectors(sdev->request_queue,
                                              max_sectors);
+       } else if (sdev->type == TYPE_TAPE) {
+               /* Tapes need much higher max_sector limits, so just
+                * raise it to the maximum possible (4 GB / 512) and
+                * let the queue segment size sort out the real limit.
+                */
+               blk_queue_max_sectors(sdev->request_queue, 0x7FFFFF);
        }
 
        /* Some USB host controllers can't do DMA; they have to use PIO.
@@ -563,4 +569,4 @@ unsigned char usb_stor_sense_invalidCDB[18] = {
        [7]     = 0x0a,                     /* additional length */
        [12]    = 0x24                      /* Invalid Field in CDB */
 };
-
+EXPORT_SYMBOL_GPL(usb_stor_sense_invalidCDB);
index 531ae5c5abf3bf5d9d97abaac36c371ae82bb766..ab5f9f37575a08543f6c50ac7b481dd68bf5eb98 100644 (file)
@@ -41,6 +41,7 @@
  */
 
 #include <linux/errno.h>
+#include <linux/module.h>
 #include <linux/slab.h>
 
 #include <scsi/scsi.h>
 #include "transport.h"
 #include "protocol.h"
 #include "debug.h"
-#include "sddr09.h"
+
+MODULE_DESCRIPTION("Driver for SanDisk SDDR-09 SmartMedia reader");
+MODULE_AUTHOR("Andries Brouwer <aeb@cwi.nl>, Robert Baruch <autophile@starband.net>");
+MODULE_LICENSE("GPL");
+
+static int usb_stor_sddr09_dpcm_init(struct us_data *us);
+static int sddr09_transport(struct scsi_cmnd *srb, struct us_data *us);
+static int usb_stor_sddr09_init(struct us_data *us);
+
+
+/*
+ * The table of devices
+ */
+#define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \
+                   vendorName, productName, useProtocol, useTransport, \
+                   initFunction, flags) \
+{ USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \
+  .driver_info = (flags)|(USB_US_TYPE_STOR<<24) }
+
+struct usb_device_id sddr09_usb_ids[] = {
+#      include "unusual_sddr09.h"
+       { }             /* Terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, sddr09_usb_ids);
+
+#undef UNUSUAL_DEV
+
+/*
+ * The flags table
+ */
+#define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \
+                   vendor_name, product_name, use_protocol, use_transport, \
+                   init_function, Flags) \
+{ \
+       .vendorName = vendor_name,      \
+       .productName = product_name,    \
+       .useProtocol = use_protocol,    \
+       .useTransport = use_transport,  \
+       .initFunction = init_function,  \
+}
+
+static struct us_unusual_dev sddr09_unusual_dev_list[] = {
+#      include "unusual_sddr09.h"
+       { }             /* Terminating entry */
+};
+
+#undef UNUSUAL_DEV
 
 
 #define short_pack(lsb,msb) ( ((u16)(lsb)) | ( ((u16)(msb))<<8 ) )
@@ -723,7 +770,7 @@ sddr09_read_data(struct us_data *us,
        len = min(sectors, (unsigned int) info->blocksize) * info->pagesize;
        buffer = kmalloc(len, GFP_NOIO);
        if (buffer == NULL) {
-               printk("sddr09_read_data: Out of memory\n");
+               printk(KERN_WARNING "sddr09_read_data: Out of memory\n");
                return -ENOMEM;
        }
 
@@ -838,7 +885,8 @@ sddr09_write_lba(struct us_data *us, unsigned int lba,
        if (pba == UNDEF) {
                pba = sddr09_find_unused_pba(info, lba);
                if (!pba) {
-                       printk("sddr09_write_lba: Out of unused blocks\n");
+                       printk(KERN_WARNING
+                              "sddr09_write_lba: Out of unused blocks\n");
                        return -ENOSPC;
                }
                info->pba_to_lba[pba] = lba;
@@ -849,7 +897,7 @@ sddr09_write_lba(struct us_data *us, unsigned int lba,
        if (pba == 1) {
                /* Maybe it is impossible to write to PBA 1.
                   Fake success, but don't do anything. */
-               printk("sddr09: avoid writing to pba 1\n");
+               printk(KERN_WARNING "sddr09: avoid writing to pba 1\n");
                return 0;
        }
 
@@ -954,7 +1002,7 @@ sddr09_write_data(struct us_data *us,
        blocklen = (pagelen << info->blockshift);
        blockbuffer = kmalloc(blocklen, GFP_NOIO);
        if (!blockbuffer) {
-               printk("sddr09_write_data: Out of memory\n");
+               printk(KERN_WARNING "sddr09_write_data: Out of memory\n");
                return -ENOMEM;
        }
 
@@ -965,7 +1013,7 @@ sddr09_write_data(struct us_data *us,
        len = min(sectors, (unsigned int) info->blocksize) * info->pagesize;
        buffer = kmalloc(len, GFP_NOIO);
        if (buffer == NULL) {
-               printk("sddr09_write_data: Out of memory\n");
+               printk(KERN_WARNING "sddr09_write_data: Out of memory\n");
                kfree(blockbuffer);
                return -ENOMEM;
        }
@@ -1112,7 +1160,7 @@ sddr09_get_cardinfo(struct us_data *us, unsigned char flags) {
 
        if (result) {
                US_DEBUGP("Result of read_deviceID is %d\n", result);
-               printk("sddr09: could not read card info\n");
+               printk(KERN_WARNING "sddr09: could not read card info\n");
                return NULL;
        }
 
@@ -1153,7 +1201,7 @@ sddr09_get_cardinfo(struct us_data *us, unsigned char flags) {
                sprintf(blurbtxt + strlen(blurbtxt),
                        ", WP");
 
-       printk("%s\n", blurbtxt);
+       printk(KERN_WARNING "%s\n", blurbtxt);
 
        return cardinfo;
 }
@@ -1184,7 +1232,7 @@ sddr09_read_map(struct us_data *us) {
        alloc_len = (alloc_blocks << CONTROL_SHIFT);
        buffer = kmalloc(alloc_len, GFP_NOIO);
        if (buffer == NULL) {
-               printk("sddr09_read_map: out of memory\n");
+               printk(KERN_WARNING "sddr09_read_map: out of memory\n");
                result = -1;
                goto done;
        }
@@ -1198,7 +1246,7 @@ sddr09_read_map(struct us_data *us) {
        info->pba_to_lba = kmalloc(numblocks*sizeof(int), GFP_NOIO);
 
        if (info->lba_to_pba == NULL || info->pba_to_lba == NULL) {
-               printk("sddr09_read_map: out of memory\n");
+               printk(KERN_WARNING "sddr09_read_map: out of memory\n");
                result = -1;
                goto done;
        }
@@ -1238,7 +1286,8 @@ sddr09_read_map(struct us_data *us) {
                        if (ptr[j] != 0)
                                goto nonz;
                info->pba_to_lba[i] = UNUSABLE;
-               printk("sddr09: PBA %d has no logical mapping\n", i);
+               printk(KERN_WARNING "sddr09: PBA %d has no logical mapping\n",
+                      i);
                continue;
 
        nonz:
@@ -1251,7 +1300,8 @@ sddr09_read_map(struct us_data *us) {
        nonff:
                /* normal PBAs start with six FFs */
                if (j < 6) {
-                       printk("sddr09: PBA %d has no logical mapping: "
+                       printk(KERN_WARNING
+                              "sddr09: PBA %d has no logical mapping: "
                               "reserved area = %02X%02X%02X%02X "
                               "data status %02X block status %02X\n",
                               i, ptr[0], ptr[1], ptr[2], ptr[3],
@@ -1261,7 +1311,8 @@ sddr09_read_map(struct us_data *us) {
                }
 
                if ((ptr[6] >> 4) != 0x01) {
-                       printk("sddr09: PBA %d has invalid address field "
+                       printk(KERN_WARNING
+                              "sddr09: PBA %d has invalid address field "
                               "%02X%02X/%02X%02X\n",
                               i, ptr[6], ptr[7], ptr[11], ptr[12]);
                        info->pba_to_lba[i] = UNUSABLE;
@@ -1270,7 +1321,8 @@ sddr09_read_map(struct us_data *us) {
 
                /* check even parity */
                if (parity[ptr[6] ^ ptr[7]]) {
-                       printk("sddr09: Bad parity in LBA for block %d"
+                       printk(KERN_WARNING
+                              "sddr09: Bad parity in LBA for block %d"
                               " (%02X %02X)\n", i, ptr[6], ptr[7]);
                        info->pba_to_lba[i] = UNUSABLE;
                        continue;
@@ -1289,7 +1341,8 @@ sddr09_read_map(struct us_data *us) {
                 */
 
                if (lba >= 1000) {
-                       printk("sddr09: Bad low LBA %d for block %d\n",
+                       printk(KERN_WARNING
+                              "sddr09: Bad low LBA %d for block %d\n",
                               lba, i);
                        goto possibly_erase;
                }
@@ -1297,7 +1350,8 @@ sddr09_read_map(struct us_data *us) {
                lba += 1000*(i/0x400);
 
                if (info->lba_to_pba[lba] != UNDEF) {
-                       printk("sddr09: LBA %d seen for PBA %d and %d\n",
+                       printk(KERN_WARNING
+                              "sddr09: LBA %d seen for PBA %d and %d\n",
                               lba, info->lba_to_pba[lba], i);
                        goto possibly_erase;
                }
@@ -1399,7 +1453,7 @@ sddr09_common_init(struct us_data *us) {
  * unusual devices list but called from here then LUN 0 of the combo reader
  * is not recognized. But I do not know what precisely these calls do.
  */
-int
+static int
 usb_stor_sddr09_dpcm_init(struct us_data *us) {
        int result;
        unsigned char *data = us->iobuf;
@@ -1449,7 +1503,7 @@ usb_stor_sddr09_dpcm_init(struct us_data *us) {
 /*
  * Transport for the Microtech DPCM-USB
  */
-int dpcm_transport(struct scsi_cmnd *srb, struct us_data *us)
+static int dpcm_transport(struct scsi_cmnd *srb, struct us_data *us)
 {
        int ret;
 
@@ -1491,7 +1545,7 @@ int dpcm_transport(struct scsi_cmnd *srb, struct us_data *us)
 /*
  * Transport for the Sandisk SDDR-09
  */
-int sddr09_transport(struct scsi_cmnd *srb, struct us_data *us)
+static int sddr09_transport(struct scsi_cmnd *srb, struct us_data *us)
 {
        static unsigned char sensekey = 0, sensecode = 0;
        static unsigned char havefakesense = 0;
@@ -1690,7 +1744,60 @@ int sddr09_transport(struct scsi_cmnd *srb, struct us_data *us)
 /*
  * Initialization routine for the sddr09 subdriver
  */
-int
+static int
 usb_stor_sddr09_init(struct us_data *us) {
        return sddr09_common_init(us);
 }
+
+static int sddr09_probe(struct usb_interface *intf,
+                        const struct usb_device_id *id)
+{
+       struct us_data *us;
+       int result;
+
+       result = usb_stor_probe1(&us, intf, id,
+                       (id - sddr09_usb_ids) + sddr09_unusual_dev_list);
+       if (result)
+               return result;
+
+       if (us->protocol == US_PR_DPCM_USB) {
+               us->transport_name = "Control/Bulk-EUSB/SDDR09";
+               us->transport = dpcm_transport;
+               us->transport_reset = usb_stor_CB_reset;
+               us->max_lun = 1;
+       } else {
+               us->transport_name = "EUSB/SDDR09";
+               us->transport = sddr09_transport;
+               us->transport_reset = usb_stor_CB_reset;
+               us->max_lun = 0;
+       }
+
+       result = usb_stor_probe2(us);
+       return result;
+}
+
+static struct usb_driver sddr09_driver = {
+       .name =         "ums-sddr09",
+       .probe =        sddr09_probe,
+       .disconnect =   usb_stor_disconnect,
+       .suspend =      usb_stor_suspend,
+       .resume =       usb_stor_resume,
+       .reset_resume = usb_stor_reset_resume,
+       .pre_reset =    usb_stor_pre_reset,
+       .post_reset =   usb_stor_post_reset,
+       .id_table =     sddr09_usb_ids,
+       .soft_unbind =  1,
+};
+
+static int __init sddr09_init(void)
+{
+       return usb_register(&sddr09_driver);
+}
+
+static void __exit sddr09_exit(void)
+{
+       usb_deregister(&sddr09_driver);
+}
+
+module_init(sddr09_init);
+module_exit(sddr09_exit);
diff --git a/drivers/usb/storage/sddr09.h b/drivers/usb/storage/sddr09.h
deleted file mode 100644 (file)
index b701172..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/* Driver for SanDisk SDDR-09 SmartMedia reader
- * Header File
- *
- * Current development and maintenance by:
- *   (c) 2000 Robert Baruch (autophile@dol.net)
- *   (c) 2002 Andries Brouwer (aeb@cwi.nl)
- *
- * See sddr09.c for more explanation
- *
- * 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_SHUTTLE_EUSB_SDDR09_H
-#define _USB_SHUTTLE_EUSB_SDDR09_H
-
-/* Sandisk SDDR-09 stuff */
-
-extern int sddr09_transport(struct scsi_cmnd *srb, struct us_data *us);
-extern int usb_stor_sddr09_init(struct us_data *us);
-
-/* Microtech DPCM-USB stuff */
-
-extern int dpcm_transport(struct scsi_cmnd *srb, struct us_data *us);
-extern int usb_stor_sddr09_dpcm_init(struct us_data *us);
-
-#endif
index 0d8df7577899e3c3d7de0e580e54fee0889fd57e..44dfed7754edb0444763b045229d4f32465812ab 100644 (file)
@@ -24,6 +24,7 @@
 
 #include <linux/jiffies.h>
 #include <linux/errno.h>
+#include <linux/module.h>
 #include <linux/slab.h>
 
 #include <scsi/scsi.h>
 #include "transport.h"
 #include "protocol.h"
 #include "debug.h"
-#include "sddr55.h"
+
+MODULE_DESCRIPTION("Driver for SanDisk SDDR-55 SmartMedia reader");
+MODULE_AUTHOR("Simon Munton");
+MODULE_LICENSE("GPL");
+
+/*
+ * The table of devices
+ */
+#define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \
+                   vendorName, productName, useProtocol, useTransport, \
+                   initFunction, flags) \
+{ USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \
+  .driver_info = (flags)|(USB_US_TYPE_STOR<<24) }
+
+struct usb_device_id sddr55_usb_ids[] = {
+#      include "unusual_sddr55.h"
+       { }             /* Terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, sddr55_usb_ids);
+
+#undef UNUSUAL_DEV
+
+/*
+ * The flags table
+ */
+#define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \
+                   vendor_name, product_name, use_protocol, use_transport, \
+                   init_function, Flags) \
+{ \
+       .vendorName = vendor_name,      \
+       .productName = product_name,    \
+       .useProtocol = use_protocol,    \
+       .useTransport = use_transport,  \
+       .initFunction = init_function,  \
+}
+
+static struct us_unusual_dev sddr55_unusual_dev_list[] = {
+#      include "unusual_sddr55.h"
+       { }             /* Terminating entry */
+};
+
+#undef UNUSUAL_DEV
 
 
 #define short_pack(lsb,msb) ( ((u16)(lsb)) | ( ((u16)(msb))<<8 ) )
@@ -513,7 +555,8 @@ static int sddr55_read_deviceID(struct us_data *us,
 }
 
 
-int sddr55_reset(struct us_data *us) {
+static int sddr55_reset(struct us_data *us)
+{
        return 0;
 }
 
@@ -703,7 +746,9 @@ static int sddr55_read_map(struct us_data *us) {
                
                if (info->lba_to_pba[lba + zone * 1000] != NOT_ALLOCATED &&
                    !info->force_read_only) {
-                       printk("sddr55: map inconsistency at LBA %04X\n", lba + zone * 1000);
+                       printk(KERN_WARNING
+                              "sddr55: map inconsistency at LBA %04X\n",
+                              lba + zone * 1000);
                        info->force_read_only = 1;
                }
 
@@ -732,7 +777,7 @@ static void sddr55_card_info_destructor(void *extra) {
 /*
  * Transport for the Sandisk SDDR-55
  */
-int sddr55_transport(struct scsi_cmnd *srb, struct us_data *us)
+static int sddr55_transport(struct scsi_cmnd *srb, struct us_data *us)
 {
        int result;
        static unsigned char inquiry_response[8] = {
@@ -929,3 +974,49 @@ int sddr55_transport(struct scsi_cmnd *srb, struct us_data *us)
        return USB_STOR_TRANSPORT_FAILED; // FIXME: sense buffer?
 }
 
+
+static int sddr55_probe(struct usb_interface *intf,
+                        const struct usb_device_id *id)
+{
+       struct us_data *us;
+       int result;
+
+       result = usb_stor_probe1(&us, intf, id,
+                       (id - sddr55_usb_ids) + sddr55_unusual_dev_list);
+       if (result)
+               return result;
+
+       us->transport_name = "SDDR55";
+       us->transport = sddr55_transport;
+       us->transport_reset = sddr55_reset;
+       us->max_lun = 0;
+
+       result = usb_stor_probe2(us);
+       return result;
+}
+
+static struct usb_driver sddr55_driver = {
+       .name =         "ums-sddr55",
+       .probe =        sddr55_probe,
+       .disconnect =   usb_stor_disconnect,
+       .suspend =      usb_stor_suspend,
+       .resume =       usb_stor_resume,
+       .reset_resume = usb_stor_reset_resume,
+       .pre_reset =    usb_stor_pre_reset,
+       .post_reset =   usb_stor_post_reset,
+       .id_table =     sddr55_usb_ids,
+       .soft_unbind =  1,
+};
+
+static int __init sddr55_init(void)
+{
+       return usb_register(&sddr55_driver);
+}
+
+static void __exit sddr55_exit(void)
+{
+       usb_deregister(&sddr55_driver);
+}
+
+module_init(sddr55_init);
+module_exit(sddr55_exit);
index ae6d64810d2a9d4cc8fc9db09fd68047136df801..b62a28814ebeaec12d0a1989c433f0c067572ce9 100644 (file)
@@ -42,6 +42,7 @@
  */
 
 #include <linux/errno.h>
+#include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/cdrom.h>
 
 #include "transport.h"
 #include "protocol.h"
 #include "debug.h"
-#include "shuttle_usbat.h"
+
+MODULE_DESCRIPTION("Driver for SCM Microsystems (a.k.a. Shuttle) USB-ATAPI cable");
+MODULE_AUTHOR("Daniel Drake <dsd@gentoo.org>, Robert Baruch <autophile@starband.net>");
+MODULE_LICENSE("GPL");
+
+/* Supported device types */
+#define USBAT_DEV_HP8200       0x01
+#define USBAT_DEV_FLASH                0x02
+
+#define USBAT_EPP_PORT         0x10
+#define USBAT_EPP_REGISTER     0x30
+#define USBAT_ATA              0x40
+#define USBAT_ISA              0x50
+
+/* Commands (need to be logically OR'd with an access type */
+#define USBAT_CMD_READ_REG             0x00
+#define USBAT_CMD_WRITE_REG            0x01
+#define USBAT_CMD_READ_BLOCK   0x02
+#define USBAT_CMD_WRITE_BLOCK  0x03
+#define USBAT_CMD_COND_READ_BLOCK      0x04
+#define USBAT_CMD_COND_WRITE_BLOCK     0x05
+#define USBAT_CMD_WRITE_REGS   0x07
+
+/* Commands (these don't need an access type) */
+#define USBAT_CMD_EXEC_CMD     0x80
+#define USBAT_CMD_SET_FEAT     0x81
+#define USBAT_CMD_UIO          0x82
+
+/* Methods of accessing UIO register */
+#define USBAT_UIO_READ 1
+#define USBAT_UIO_WRITE        0
+
+/* Qualifier bits */
+#define USBAT_QUAL_FCQ 0x20    /* full compare */
+#define USBAT_QUAL_ALQ 0x10    /* auto load subcount */
+
+/* USBAT Flash Media status types */
+#define USBAT_FLASH_MEDIA_NONE 0
+#define USBAT_FLASH_MEDIA_CF   1
+
+/* USBAT Flash Media change types */
+#define USBAT_FLASH_MEDIA_SAME 0
+#define USBAT_FLASH_MEDIA_CHANGED      1
+
+/* USBAT ATA registers */
+#define USBAT_ATA_DATA      0x10  /* read/write data (R/W) */
+#define USBAT_ATA_FEATURES  0x11  /* set features (W) */
+#define USBAT_ATA_ERROR     0x11  /* error (R) */
+#define USBAT_ATA_SECCNT    0x12  /* sector count (R/W) */
+#define USBAT_ATA_SECNUM    0x13  /* sector number (R/W) */
+#define USBAT_ATA_LBA_ME    0x14  /* cylinder low (R/W) */
+#define USBAT_ATA_LBA_HI    0x15  /* cylinder high (R/W) */
+#define USBAT_ATA_DEVICE    0x16  /* head/device selection (R/W) */
+#define USBAT_ATA_STATUS    0x17  /* device status (R) */
+#define USBAT_ATA_CMD       0x17  /* device command (W) */
+#define USBAT_ATA_ALTSTATUS 0x0E  /* status (no clear IRQ) (R) */
+
+/* USBAT User I/O Data registers */
+#define USBAT_UIO_EPAD         0x80 /* Enable Peripheral Control Signals */
+#define USBAT_UIO_CDT          0x40 /* Card Detect (Read Only) */
+                                    /* CDT = ACKD & !UI1 & !UI0 */
+#define USBAT_UIO_1            0x20 /* I/O 1 */
+#define USBAT_UIO_0            0x10 /* I/O 0 */
+#define USBAT_UIO_EPP_ATA      0x08 /* 1=EPP mode, 0=ATA mode */
+#define USBAT_UIO_UI1          0x04 /* Input 1 */
+#define USBAT_UIO_UI0          0x02 /* Input 0 */
+#define USBAT_UIO_INTR_ACK     0x01 /* Interrupt (ATA/ISA)/Acknowledge (EPP) */
+
+/* USBAT User I/O Enable registers */
+#define USBAT_UIO_DRVRST       0x80 /* Reset Peripheral */
+#define USBAT_UIO_ACKD         0x40 /* Enable Card Detect */
+#define USBAT_UIO_OE1          0x20 /* I/O 1 set=output/clr=input */
+                                    /* If ACKD=1, set OE1 to 1 also. */
+#define USBAT_UIO_OE0          0x10 /* I/O 0 set=output/clr=input */
+#define USBAT_UIO_ADPRST       0x01 /* Reset SCM chip */
+
+/* USBAT Features */
+#define USBAT_FEAT_ETEN        0x80    /* External trigger enable */
+#define USBAT_FEAT_U1  0x08
+#define USBAT_FEAT_U0  0x04
+#define USBAT_FEAT_ET1 0x02
+#define USBAT_FEAT_ET2 0x01
+
+struct usbat_info {
+       int devicetype;
+
+       /* Used for Flash readers only */
+       unsigned long sectors;     /* total sector count */
+       unsigned long ssize;       /* sector size in bytes */
+
+       unsigned char sense_key;
+       unsigned long sense_asc;   /* additional sense code */
+       unsigned long sense_ascq;  /* additional sense code qualifier */
+};
 
 #define short_pack(LSB,MSB) ( ((u16)(LSB)) | ( ((u16)(MSB))<<8 ) )
 #define LSB_of(s) ((s)&0xFF)
@@ -63,6 +157,48 @@ static int transferred = 0;
 static int usbat_flash_transport(struct scsi_cmnd * srb, struct us_data *us);
 static int usbat_hp8200e_transport(struct scsi_cmnd *srb, struct us_data *us);
 
+static int init_usbat_cd(struct us_data *us);
+static int init_usbat_flash(struct us_data *us);
+
+
+/*
+ * The table of devices
+ */
+#define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \
+                   vendorName, productName, useProtocol, useTransport, \
+                   initFunction, flags) \
+{ USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \
+  .driver_info = (flags)|(USB_US_TYPE_STOR<<24) }
+
+struct usb_device_id usbat_usb_ids[] = {
+#      include "unusual_usbat.h"
+       { }             /* Terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, usbat_usb_ids);
+
+#undef UNUSUAL_DEV
+
+/*
+ * The flags table
+ */
+#define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \
+                   vendor_name, product_name, use_protocol, use_transport, \
+                   init_function, Flags) \
+{ \
+       .vendorName = vendor_name,      \
+       .productName = product_name,    \
+       .useProtocol = use_protocol,    \
+       .useTransport = use_transport,  \
+       .initFunction = init_function,  \
+}
+
+static struct us_unusual_dev usbat_unusual_dev_list[] = {
+#      include "unusual_usbat.h"
+       { }             /* Terminating entry */
+};
+
+#undef UNUSUAL_DEV
+
 /*
  * Convenience function to produce an ATA read/write sectors command
  * Use cmd=0x20 for read, cmd=0x30 for write
@@ -1684,37 +1820,61 @@ static int usbat_flash_transport(struct scsi_cmnd * srb, struct us_data *us)
        return USB_STOR_TRANSPORT_FAILED;
 }
 
-int init_usbat_cd(struct us_data *us)
+static int init_usbat_cd(struct us_data *us)
 {
        return init_usbat(us, USBAT_DEV_HP8200);
 }
 
-
-int init_usbat_flash(struct us_data *us)
+static int init_usbat_flash(struct us_data *us)
 {
        return init_usbat(us, USBAT_DEV_FLASH);
 }
 
-int init_usbat_probe(struct us_data *us)
+static int usbat_probe(struct usb_interface *intf,
+                        const struct usb_device_id *id)
 {
-       return init_usbat(us, 0);
+       struct us_data *us;
+       int result;
+
+       result = usb_stor_probe1(&us, intf, id,
+                       (id - usbat_usb_ids) + usbat_unusual_dev_list);
+       if (result)
+               return result;
+
+       /* The actual transport will be determined later by the
+        * initialization routine; this is just a placeholder.
+        */
+       us->transport_name = "Shuttle USBAT";
+       us->transport = usbat_flash_transport;
+       us->transport_reset = usb_stor_CB_reset;
+       us->max_lun = 1;
+
+       result = usb_stor_probe2(us);
+       return result;
 }
 
-/*
- * Default transport function. Attempts to detect which transport function
- * should be called, makes it the new default, and calls it.
- *
- * This function should never be called. Our usbat_init() function detects the
- * device type and changes the us->transport ptr to the transport function
- * relevant to the device.
- * However, we'll support this impossible(?) case anyway.
- */
-int usbat_transport(struct scsi_cmnd *srb, struct us_data *us)
+static struct usb_driver usbat_driver = {
+       .name =         "ums-usbat",
+       .probe =        usbat_probe,
+       .disconnect =   usb_stor_disconnect,
+       .suspend =      usb_stor_suspend,
+       .resume =       usb_stor_resume,
+       .reset_resume = usb_stor_reset_resume,
+       .pre_reset =    usb_stor_pre_reset,
+       .post_reset =   usb_stor_post_reset,
+       .id_table =     usbat_usb_ids,
+       .soft_unbind =  1,
+};
+
+static int __init usbat_init(void)
 {
-       struct usbat_info *info = (struct usbat_info*) (us->extra);
-
-       if (usbat_set_transport(us, info, 0))
-               return USB_STOR_TRANSPORT_ERROR;
+       return usb_register(&usbat_driver);
+}
 
-       return us->transport(srb, us);  
+static void __exit usbat_exit(void)
+{
+       usb_deregister(&usbat_driver);
 }
+
+module_init(usbat_init);
+module_exit(usbat_exit);
diff --git a/drivers/usb/storage/shuttle_usbat.h b/drivers/usb/storage/shuttle_usbat.h
deleted file mode 100644 (file)
index d8bfc43..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-/* Driver for SCM Microsystems USB-ATAPI cable
- * Header File
- *
- * Current development and maintenance by:
- *   (c) 2000 Robert Baruch (autophile@dol.net)
- *   (c) 2004, 2005 Daniel Drake <dsd@gentoo.org>
- *
- * See shuttle_usbat.c for more explanation
- *
- * 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_SHUTTLE_USBAT_H
-#define _USB_SHUTTLE_USBAT_H
-
-/* Supported device types */
-#define USBAT_DEV_HP8200       0x01
-#define USBAT_DEV_FLASH                0x02
-
-#define USBAT_EPP_PORT         0x10
-#define USBAT_EPP_REGISTER     0x30
-#define USBAT_ATA              0x40
-#define USBAT_ISA              0x50
-
-/* Commands (need to be logically OR'd with an access type */
-#define USBAT_CMD_READ_REG             0x00
-#define USBAT_CMD_WRITE_REG            0x01
-#define USBAT_CMD_READ_BLOCK   0x02
-#define USBAT_CMD_WRITE_BLOCK  0x03
-#define USBAT_CMD_COND_READ_BLOCK      0x04
-#define USBAT_CMD_COND_WRITE_BLOCK     0x05
-#define USBAT_CMD_WRITE_REGS   0x07
-
-/* Commands (these don't need an access type) */
-#define USBAT_CMD_EXEC_CMD     0x80
-#define USBAT_CMD_SET_FEAT     0x81
-#define USBAT_CMD_UIO          0x82
-
-/* Methods of accessing UIO register */
-#define USBAT_UIO_READ 1
-#define USBAT_UIO_WRITE        0
-
-/* Qualifier bits */
-#define USBAT_QUAL_FCQ 0x20    /* full compare */
-#define USBAT_QUAL_ALQ 0x10    /* auto load subcount */
-
-/* USBAT Flash Media status types */
-#define USBAT_FLASH_MEDIA_NONE 0
-#define USBAT_FLASH_MEDIA_CF   1
-
-/* USBAT Flash Media change types */
-#define USBAT_FLASH_MEDIA_SAME 0
-#define USBAT_FLASH_MEDIA_CHANGED      1
-
-/* USBAT ATA registers */
-#define USBAT_ATA_DATA      0x10  /* read/write data (R/W) */
-#define USBAT_ATA_FEATURES  0x11  /* set features (W) */
-#define USBAT_ATA_ERROR     0x11  /* error (R) */
-#define USBAT_ATA_SECCNT    0x12  /* sector count (R/W) */
-#define USBAT_ATA_SECNUM    0x13  /* sector number (R/W) */
-#define USBAT_ATA_LBA_ME    0x14  /* cylinder low (R/W) */
-#define USBAT_ATA_LBA_HI    0x15  /* cylinder high (R/W) */
-#define USBAT_ATA_DEVICE    0x16  /* head/device selection (R/W) */
-#define USBAT_ATA_STATUS    0x17  /* device status (R) */
-#define USBAT_ATA_CMD       0x17  /* device command (W) */
-#define USBAT_ATA_ALTSTATUS 0x0E  /* status (no clear IRQ) (R) */
-
-/* USBAT User I/O Data registers */
-#define USBAT_UIO_EPAD         0x80 /* Enable Peripheral Control Signals */
-#define USBAT_UIO_CDT          0x40 /* Card Detect (Read Only) */
-                                    /* CDT = ACKD & !UI1 & !UI0 */
-#define USBAT_UIO_1            0x20 /* I/O 1 */
-#define USBAT_UIO_0            0x10 /* I/O 0 */
-#define USBAT_UIO_EPP_ATA      0x08 /* 1=EPP mode, 0=ATA mode */
-#define USBAT_UIO_UI1          0x04 /* Input 1 */
-#define USBAT_UIO_UI0          0x02 /* Input 0 */
-#define USBAT_UIO_INTR_ACK     0x01 /* Interrupt (ATA/ISA)/Acknowledge (EPP) */
-
-/* USBAT User I/O Enable registers */
-#define USBAT_UIO_DRVRST       0x80 /* Reset Peripheral */
-#define USBAT_UIO_ACKD         0x40 /* Enable Card Detect */
-#define USBAT_UIO_OE1          0x20 /* I/O 1 set=output/clr=input */
-                                    /* If ACKD=1, set OE1 to 1 also. */
-#define USBAT_UIO_OE0          0x10 /* I/O 0 set=output/clr=input */
-#define USBAT_UIO_ADPRST       0x01 /* Reset SCM chip */
-
-/* USBAT Features */
-#define USBAT_FEAT_ETEN        0x80    /* External trigger enable */
-#define USBAT_FEAT_U1  0x08
-#define USBAT_FEAT_U0  0x04
-#define USBAT_FEAT_ET1 0x02
-#define USBAT_FEAT_ET2 0x01
-
-extern int usbat_transport(struct scsi_cmnd *srb, struct us_data *us);
-extern int init_usbat_cd(struct us_data *us);
-extern int init_usbat_flash(struct us_data *us);
-extern int init_usbat_probe(struct us_data *us);
-
-struct usbat_info {
-       int devicetype;
-
-       /* Used for Flash readers only */
-       unsigned long sectors;     /* total sector count */
-       unsigned long ssize;       /* sector size in bytes */
-
-       unsigned char sense_key;
-       unsigned long sense_asc;   /* additional sense code */
-       unsigned long sense_ascq;  /* additional sense code qualifier */
-};
-
-#endif
index fb65d221cedf8cfaf5e6051687904dc4a12911db..d48c8553539dd6354acb6b3323304589aa19a8e1 100644 (file)
@@ -220,6 +220,7 @@ int usb_stor_control_msg(struct us_data *us, unsigned int pipe,
                status = us->current_urb->actual_length;
        return status;
 }
+EXPORT_SYMBOL_GPL(usb_stor_control_msg);
 
 /* This is a version of usb_clear_halt() that allows early termination and
  * doesn't read the status from the device -- this is because some devices
@@ -254,6 +255,7 @@ int usb_stor_clear_halt(struct us_data *us, unsigned int pipe)
        US_DEBUGP("%s: result = %d\n", __func__, result);
        return result;
 }
+EXPORT_SYMBOL_GPL(usb_stor_clear_halt);
 
 
 /*
@@ -352,6 +354,7 @@ int usb_stor_ctrl_transfer(struct us_data *us, unsigned int pipe,
        return interpret_urb_result(us, pipe, size, result,
                        us->current_urb->actual_length);
 }
+EXPORT_SYMBOL_GPL(usb_stor_ctrl_transfer);
 
 /*
  * Receive one interrupt buffer, without timeouts, but allowing early
@@ -407,6 +410,7 @@ int usb_stor_bulk_transfer_buf(struct us_data *us, unsigned int pipe,
        return interpret_urb_result(us, pipe, length, result, 
                        us->current_urb->actual_length);
 }
+EXPORT_SYMBOL_GPL(usb_stor_bulk_transfer_buf);
 
 /*
  * Transfer a scatter-gather list via bulk transfer
@@ -474,6 +478,7 @@ int usb_stor_bulk_srb(struct us_data* us, unsigned int pipe,
        scsi_set_resid(srb, scsi_bufflen(srb) - partial);
        return result;
 }
+EXPORT_SYMBOL_GPL(usb_stor_bulk_srb);
 
 /*
  * Transfer an entire SCSI command's worth of data payload over the bulk
@@ -509,6 +514,7 @@ int usb_stor_bulk_transfer_sg(struct us_data* us, unsigned int pipe,
                *residual = length_left;
        return result;
 }
+EXPORT_SYMBOL_GPL(usb_stor_bulk_transfer_sg);
 
 /***********************************************************************
  * Transport routines
@@ -940,6 +946,7 @@ int usb_stor_CB_transport(struct scsi_cmnd *srb, struct us_data *us)
                usb_stor_clear_halt(us, pipe);
        return USB_STOR_TRANSPORT_FAILED;
 }
+EXPORT_SYMBOL_GPL(usb_stor_CB_transport);
 
 /*
  * Bulk only transport
@@ -1156,6 +1163,7 @@ int usb_stor_Bulk_transport(struct scsi_cmnd *srb, struct us_data *us)
        /* we should never get here, but if we do, we're in trouble */
        return USB_STOR_TRANSPORT_ERROR;
 }
+EXPORT_SYMBOL_GPL(usb_stor_Bulk_transport);
 
 /***********************************************************************
  * Reset routines
@@ -1230,6 +1238,7 @@ int usb_stor_CB_reset(struct us_data *us)
                                 USB_TYPE_CLASS | USB_RECIP_INTERFACE,
                                 0, us->ifnum, us->iobuf, CB_RESET_CMD_SIZE);
 }
+EXPORT_SYMBOL_GPL(usb_stor_CB_reset);
 
 /* This issues a Bulk-only Reset to the device in question, including
  * clearing the subsequent endpoint halts that may occur.
@@ -1242,6 +1251,7 @@ int usb_stor_Bulk_reset(struct us_data *us)
                                 USB_TYPE_CLASS | USB_RECIP_INTERFACE,
                                 0, us->ifnum, NULL, 0);
 }
+EXPORT_SYMBOL_GPL(usb_stor_Bulk_reset);
 
 /* Issue a USB port reset to the device.  The caller must not hold
  * us->dev_mutex.
similarity index 60%
rename from drivers/usb/storage/freecom.h
rename to drivers/usb/storage/unusual_alauda.h
index 20d0fe6ba0c89f4c3af6fed1032767522a6cac33..8c412f885dd2e59543c2247e72edbb835274395b 100644 (file)
@@ -1,13 +1,4 @@
-/* Driver for Freecom USB/IDE adaptor
- *
- * Freecom v0.1:
- *
- * First release
- *
- * Current development and maintenance by:
- *   (c) 2000 David Brown <usb-storage@davidb.org>
- *
- * See freecom.c for more explanation
+/* Unusual Devices File for the Alauda-based card readers
  *
  * 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
  * 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#ifndef _FREECOM_USB_H
-#define _FREECOM_USB_H
+#if defined(CONFIG_USB_STORAGE_ALAUDA) || \
+               defined(CONFIG_USB_STORAGE_ALAUDA_MODULE)
+
+UNUSUAL_DEV(  0x0584, 0x0008, 0x0102, 0x0102,
+               "Fujifilm",
+               "DPC-R1 (Alauda)",
+               US_SC_SCSI, US_PR_ALAUDA, init_alauda, 0),
 
-extern int freecom_transport(struct scsi_cmnd *srb, struct us_data *us);
-extern int usb_stor_freecom_reset(struct us_data *us);
-extern int freecom_init (struct us_data *us);
+UNUSUAL_DEV(  0x07b4, 0x010a, 0x0102, 0x0102,
+               "Olympus",
+               "MAUSB-10 (Alauda)",
+               US_SC_SCSI, US_PR_ALAUDA, init_alauda, 0),
 
-#endif
+#endif /* defined(CONFIG_USB_STORAGE_ALAUDA) || ... */
diff --git a/drivers/usb/storage/unusual_cypress.h b/drivers/usb/storage/unusual_cypress.h
new file mode 100644 (file)
index 0000000..44be6d7
--- /dev/null
@@ -0,0 +1,34 @@
+/* Unusual Devices File for devices based on the Cypress USB/ATA bridge
+ *     with support for ATACB
+ *
+ * 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.
+ */
+
+#if defined(CONFIG_USB_STORAGE_CYPRESS_ATACB) || \
+               defined(CONFIG_USB_STORAGE_CYPRESS_ATACB_MODULE)
+
+/* CY7C68300 : support atacb */
+UNUSUAL_DEV(  0x04b4, 0x6830, 0x0000, 0x9999,
+               "Cypress",
+               "Cypress AT2LP",
+               US_SC_CYP_ATACB, US_PR_DEVICE, NULL, 0),
+
+/* CY7C68310 : support atacb and atacb2 */
+UNUSUAL_DEV(  0x04b4, 0x6831, 0x0000, 0x9999,
+               "Cypress",
+               "Cypress ISD-300LP",
+               US_SC_CYP_ATACB, US_PR_DEVICE, NULL, 0),
+
+#endif /* defined(CONFIG_USB_STORAGE_CYPRESS_ATACB) || ... */
diff --git a/drivers/usb/storage/unusual_datafab.h b/drivers/usb/storage/unusual_datafab.h
new file mode 100644 (file)
index 0000000..c9298ce
--- /dev/null
@@ -0,0 +1,98 @@
+/* Unusual Devices File for the Datafab USB Compact Flash reader
+ *
+ * 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.
+ */
+
+#if defined(CONFIG_USB_STORAGE_DATAFAB) || \
+               defined(CONFIG_USB_STORAGE_DATAFAB_MODULE)
+
+UNUSUAL_DEV(  0x07c4, 0xa000, 0x0000, 0x0015,
+               "Datafab",
+               "MDCFE-B USB CF Reader",
+               US_SC_SCSI, US_PR_DATAFAB, NULL,
+               0),
+
+/*
+ * The following Datafab-based devices may or may not work
+ * using the current driver...the 0xffff is arbitrary since I
+ * don't know what device versions exist for these guys.
+ *
+ * The 0xa003 and 0xa004 devices in particular I'm curious about.
+ * I'm told they exist but so far nobody has come forward to say that
+ * they work with this driver.  Given the success we've had getting
+ * other Datafab-based cards operational with this driver, I've decided
+ * to leave these two devices in the list.
+ */
+UNUSUAL_DEV( 0x07c4, 0xa001, 0x0000, 0xffff,
+               "SIIG/Datafab",
+               "SIIG/Datafab Memory Stick+CF Reader/Writer",
+               US_SC_SCSI, US_PR_DATAFAB, NULL,
+               0),
+
+/* Reported by Josef Reisinger <josef.reisinger@netcologne.de> */
+UNUSUAL_DEV( 0x07c4, 0xa002, 0x0000, 0xffff,
+               "Datafab/Unknown",
+               "MD2/MD3 Disk enclosure",
+               US_SC_SCSI, US_PR_DATAFAB, NULL,
+               US_FL_SINGLE_LUN),
+
+UNUSUAL_DEV( 0x07c4, 0xa003, 0x0000, 0xffff,
+               "Datafab/Unknown",
+               "Datafab-based Reader",
+               US_SC_SCSI, US_PR_DATAFAB, NULL,
+               0),
+
+UNUSUAL_DEV( 0x07c4, 0xa004, 0x0000, 0xffff,
+               "Datafab/Unknown",
+               "Datafab-based Reader",
+               US_SC_SCSI, US_PR_DATAFAB, NULL,
+               0),
+
+UNUSUAL_DEV( 0x07c4, 0xa005, 0x0000, 0xffff,
+               "PNY/Datafab",
+               "PNY/Datafab CF+SM Reader",
+               US_SC_SCSI, US_PR_DATAFAB, NULL,
+               0),
+
+UNUSUAL_DEV( 0x07c4, 0xa006, 0x0000, 0xffff,
+               "Simple Tech/Datafab",
+               "Simple Tech/Datafab CF+SM Reader",
+               US_SC_SCSI, US_PR_DATAFAB, NULL,
+               0),
+
+/* Submitted by Olaf Hering <olh@suse.de> */
+UNUSUAL_DEV(  0x07c4, 0xa109, 0x0000, 0xffff,
+               "Datafab Systems, Inc.",
+               "USB to CF + SM Combo (LC1)",
+               US_SC_SCSI, US_PR_DATAFAB, NULL,
+               0),
+
+/* Reported by Felix Moeller <felix@derklecks.de>
+ * in Germany this is sold by Hama with the productnumber 46952
+ * as "DualSlot CompactFlash(TM) & MStick Drive USB"
+ */
+UNUSUAL_DEV(  0x07c4, 0xa10b, 0x0000, 0xffff,
+               "DataFab Systems Inc.",
+               "USB CF+MS",
+               US_SC_SCSI, US_PR_DATAFAB, NULL,
+               0),
+
+UNUSUAL_DEV( 0x0c0b, 0xa109, 0x0000, 0xffff,
+               "Acomdata",
+               "CF",
+               US_SC_SCSI, US_PR_DATAFAB, NULL,
+               US_FL_SINGLE_LUN),
+
+#endif /* defined(CONFIG_USB_STORAGE_DATAFAB) || ... */
index cfde74a6faa3f158e65b2bea0f77b229131fc1e1..1c1f643e8a78f7e3d85c4823caef6b11388cc54e 100644 (file)
  * as opposed to devices that do something strangely or wrongly.
  */
 
+#if !defined(CONFIG_USB_STORAGE_SDDR09) && \
+               !defined(CONFIG_USB_STORAGE_SDDR09_MODULE)
+#define NO_SDDR09
+#endif
+
 /* patch submitted by Vivian Bregier <Vivian.Bregier@imag.fr>
  */
 UNUSUAL_DEV(  0x03eb, 0x2002, 0x0100, 0x0100,
@@ -80,18 +85,6 @@ UNUSUAL_DEV(  0x03f0, 0x0107, 0x0200, 0x0200,
                "CD-Writer+",
                US_SC_8070, US_PR_CB, NULL, 0),
 
-#ifdef CONFIG_USB_STORAGE_USBAT
-UNUSUAL_DEV(  0x03f0, 0x0207, 0x0001, 0x0001,
-               "HP",
-               "CD-Writer+ 8200e",
-               US_SC_8070, US_PR_USBAT, init_usbat_cd, 0),
-
-UNUSUAL_DEV(  0x03f0, 0x0307, 0x0001, 0x0001,
-               "HP",
-               "CD-Writer+ CD-4e",
-               US_SC_8070, US_PR_USBAT, init_usbat_cd, 0),
-#endif
-
 /* Reported by Ben Efros <ben@pc-doctor.com> */
 UNUSUAL_DEV(  0x03f0, 0x070c, 0x0000, 0x0000,
                "HP",
@@ -246,12 +239,7 @@ UNUSUAL_DEV(  0x0424, 0x0fdc, 0x0210, 0x0210,
                US_SC_DEVICE, US_PR_DEVICE, NULL,
                US_FL_SINGLE_LUN ),
 
-#ifdef CONFIG_USB_STORAGE_SDDR09
-UNUSUAL_DEV(  0x0436, 0x0005, 0x0100, 0x0100,
-               "Microtech",
-               "CameraMate (DPCM_USB)",
-               US_SC_SCSI, US_PR_DPCM_USB, NULL, 0 ),
-#else
+#ifdef NO_SDDR09
 UNUSUAL_DEV(  0x0436, 0x0005, 0x0100, 0x0100,
                "Microtech",
                "CameraMate",
@@ -288,13 +276,6 @@ UNUSUAL_DEV(  0x0457, 0x0151, 0x0100, 0x0100,
                US_SC_DEVICE, US_PR_DEVICE, NULL,
                US_FL_NOT_LOCKABLE ),
 
-#ifdef CONFIG_USB_STORAGE_KARMA
-UNUSUAL_DEV(  0x045a, 0x5210, 0x0101, 0x0101,
-               "Rio",
-               "Rio Karma",
-               US_SC_SCSI, US_PR_KARMA, rio_karma_init, 0),
-#endif
-
 /* Reported by Tamas Kerecsen <kerecsen@bigfoot.com>
  * Obviously the PROM has not been customized by the VAR;
  * the Vendor and Product string descriptors are:
@@ -375,22 +356,6 @@ UNUSUAL_DEV(  0x04b3, 0x4001, 0x0110, 0x0110,
                US_SC_DEVICE, US_PR_CB, NULL,
                US_FL_MAX_SECTORS_MIN),
 
-#ifdef CONFIG_USB_STORAGE_CYPRESS_ATACB
-/* CY7C68300 : support atacb */
-UNUSUAL_DEV(  0x04b4, 0x6830, 0x0000, 0x9999,
-               "Cypress",
-               "Cypress AT2LP",
-               US_SC_CYP_ATACB, US_PR_DEVICE, NULL,
-               0),
-
-/* CY7C68310 : support atacb and atacb2 */
-UNUSUAL_DEV(  0x04b4, 0x6831, 0x0000, 0x9999,
-               "Cypress",
-               "Cypress ISD-300LP",
-               US_SC_CYP_ATACB, US_PR_DEVICE, NULL,
-               0),
-#endif
-
 /* Reported by Simon Levitt <simon@whattf.com>
  * This entry needs Sub and Proto fields */
 UNUSUAL_DEV(  0x04b8, 0x0601, 0x0100, 0x0100,
@@ -467,20 +432,7 @@ UNUSUAL_DEV(  0x04e6, 0x0002, 0x0100, 0x0100,
                US_SC_DEVICE, US_PR_DEVICE, usb_stor_euscsi_init, 
                US_FL_SCM_MULT_TARG ),
 
-#ifdef CONFIG_USB_STORAGE_SDDR09
-UNUSUAL_DEV(  0x04e6, 0x0003, 0x0000, 0x9999,
-               "Sandisk",
-               "ImageMate SDDR09",
-               US_SC_SCSI, US_PR_EUSB_SDDR09, usb_stor_sddr09_init,
-               0),
-
-/* This entry is from Andries.Brouwer@cwi.nl */
-UNUSUAL_DEV(  0x04e6, 0x0005, 0x0100, 0x0208,
-               "SCM Microsystems",
-               "eUSB SmartMedia / CompactFlash Adapter",
-               US_SC_SCSI, US_PR_DPCM_USB, usb_stor_sddr09_dpcm_init,
-               0),
-#else
+#ifdef NO_SDDR09
 UNUSUAL_DEV(  0x04e6, 0x0005, 0x0100, 0x0208,
                "SCM Microsystems",
                "eUSB CompactFlash Adapter",
@@ -535,14 +487,6 @@ UNUSUAL_DEV(  0x04e6, 0x0101, 0x0200, 0x0200,
                "CD-RW Device",
                US_SC_8020, US_PR_CB, NULL, 0),
 
-#ifdef CONFIG_USB_STORAGE_USBAT
-UNUSUAL_DEV(  0x04e6, 0x1010, 0x0000, 0x9999,
-               "Shuttle/SCM",
-               "USBAT-02",
-               US_SC_SCSI, US_PR_USBAT, init_usbat_flash,
-               US_FL_SINGLE_LUN),
-#endif
-
 /* Reported by Dmitry Khlystov <adminimus@gmail.com> */
 UNUSUAL_DEV(  0x04e8, 0x507c, 0x0220, 0x0220,
                "Samsung",
@@ -645,14 +589,6 @@ UNUSUAL_DEV(  0x054c, 0x0025, 0x0100, 0x0100,
                US_SC_DEVICE, US_PR_DEVICE, NULL,
                US_FL_SINGLE_LUN ),
 
-#ifdef CONFIG_USB_STORAGE_ISD200
-UNUSUAL_DEV(  0x054c, 0x002b, 0x0100, 0x0110,
-               "Sony",
-               "Portable USB Harddrive V2",
-               US_SC_ISD200, US_PR_BULK, isd200_Initialization,
-               0 ),
-#endif
-
 /* Submitted by Olaf Hering, <olh@suse.de> SuSE Bugzilla #49049 */
 UNUSUAL_DEV(  0x054c, 0x002c, 0x0501, 0x2000,
                "Sony",
@@ -749,13 +685,6 @@ UNUSUAL_DEV(  0x057b, 0x0022, 0x0000, 0x9999,
                "Silicon Media R/W",
                US_SC_DEVICE, US_PR_DEVICE, NULL, 0),
 
-#ifdef CONFIG_USB_STORAGE_ALAUDA
-UNUSUAL_DEV(  0x0584, 0x0008, 0x0102, 0x0102,
-               "Fujifilm",
-               "DPC-R1 (Alauda)",
-               US_SC_SCSI, US_PR_ALAUDA, init_alauda, 0 ),
-#endif
-
 /* Reported by RTE <raszilki@yandex.ru> */
 UNUSUAL_DEV(  0x058f, 0x6387, 0x0141, 0x0141,
                "JetFlash",
@@ -798,32 +727,6 @@ UNUSUAL_DEV(  0x05ab, 0x0060, 0x1104, 0x1110,
                US_SC_SCSI, US_PR_BULK, NULL,
                US_FL_NEED_OVERRIDE ),
 
-#ifdef CONFIG_USB_STORAGE_ISD200
-UNUSUAL_DEV(  0x05ab, 0x0031, 0x0100, 0x0110,
-               "In-System",
-               "USB/IDE Bridge (ATA/ATAPI)",
-               US_SC_ISD200, US_PR_BULK, isd200_Initialization,
-               0 ),
-
-UNUSUAL_DEV(  0x05ab, 0x0301, 0x0100, 0x0110,
-               "In-System",
-               "Portable USB Harddrive V2",
-               US_SC_ISD200, US_PR_BULK, isd200_Initialization,
-               0 ),
-
-UNUSUAL_DEV(  0x05ab, 0x0351, 0x0100, 0x0110,
-               "In-System",
-               "Portable USB Harddrive V2",
-               US_SC_ISD200, US_PR_BULK, isd200_Initialization,
-               0 ),
-
-UNUSUAL_DEV(  0x05ab, 0x5701, 0x0100, 0x0110,
-               "In-System",
-               "USB Storage Adapter V2",
-               US_SC_ISD200, US_PR_BULK, isd200_Initialization,
-               0 ),
-#endif
-
 /* Submitted by Sven Anderson <sven-linux@anderson.de>
  * There are at least four ProductIDs used for iPods, so I added 0x1202 and
  * 0x1204. They just need the US_FL_FIX_CAPACITY. As the bcdDevice appears
@@ -877,14 +780,6 @@ UNUSUAL_DEV(  0x05c6, 0x1000, 0x0000, 0x9999,
                US_SC_DEVICE, US_PR_DEVICE, option_ms_init,
                0),
 
-#ifdef CONFIG_USB_STORAGE_JUMPSHOT
-UNUSUAL_DEV(  0x05dc, 0x0001, 0x0000, 0x0001,
-               "Lexar",
-               "Jumpshot USB CF Reader",
-               US_SC_SCSI, US_PR_JUMPSHOT, NULL,
-               US_FL_NEED_OVERRIDE ),
-#endif
-
 /* Reported by Blake Matheny <bmatheny@purdue.edu> */
 UNUSUAL_DEV(  0x05dc, 0xb002, 0x0000, 0x0113,
                "Lexar",
@@ -935,14 +830,6 @@ UNUSUAL_DEV(  0x0644, 0x0000, 0x0100, 0x0100,
                "Floppy Drive",
                US_SC_UFI, US_PR_CB, NULL, 0 ),
 
-#ifdef CONFIG_USB_STORAGE_SDDR09
-UNUSUAL_DEV(  0x066b, 0x0105, 0x0100, 0x0100,
-               "Olympus",
-               "Camedia MAUSB-2",
-               US_SC_SCSI, US_PR_EUSB_SDDR09, usb_stor_sddr09_init,
-               0),
-#endif
-
 /* Reported by Darsen Lu <darsen@micro.ee.nthu.edu.tw> */
 UNUSUAL_DEV( 0x066f, 0x8000, 0x0001, 0x0001,
                "SigmaTel",
@@ -1043,35 +930,12 @@ UNUSUAL_DEV(  0x0781, 0x0002, 0x0009, 0x0009,
                US_SC_DEVICE, US_PR_DEVICE, NULL,
                US_FL_FIX_CAPACITY ),
 
-#ifdef CONFIG_USB_STORAGE_USBAT
-UNUSUAL_DEV(  0x0781, 0x0005, 0x0005, 0x0005,
-               "Sandisk",
-               "ImageMate SDDR-05b",
-               US_SC_SCSI, US_PR_USBAT, init_usbat_flash,
-               US_FL_SINGLE_LUN ),
-#endif
-
 UNUSUAL_DEV(  0x0781, 0x0100, 0x0100, 0x0100,
                "Sandisk",
                "ImageMate SDDR-12",
                US_SC_SCSI, US_PR_CB, NULL,
                US_FL_SINGLE_LUN ),
 
-#ifdef CONFIG_USB_STORAGE_SDDR09
-UNUSUAL_DEV(  0x0781, 0x0200, 0x0000, 0x9999,
-               "Sandisk",
-               "ImageMate SDDR-09",
-               US_SC_SCSI, US_PR_EUSB_SDDR09, usb_stor_sddr09_init,
-               0),
-#endif
-
-#ifdef CONFIG_USB_STORAGE_FREECOM
-UNUSUAL_DEV(  0x07ab, 0xfc01, 0x0000, 0x9999,
-               "Freecom",
-               "USB-IDE",
-               US_SC_QIC, US_PR_FREECOM, freecom_init, 0),
-#endif
-
 /* Reported by Eero Volotinen <eero@ping-viini.org> */
 UNUSUAL_DEV(  0x07ab, 0xfccd, 0x0000, 0x9999,
                "Freecom Technologies",
@@ -1091,12 +955,7 @@ UNUSUAL_DEV(  0x07af, 0x0005, 0x0100, 0x0100,
                US_SC_DEVICE, US_PR_DEVICE, usb_stor_euscsi_init,
                US_FL_SCM_MULT_TARG ),
 
-#ifdef CONFIG_USB_STORAGE_SDDR09
-UNUSUAL_DEV(  0x07af, 0x0006, 0x0100, 0x0100,
-               "Microtech",
-               "CameraMate (DPCM_USB)",
-               US_SC_SCSI, US_PR_DPCM_USB, NULL, 0 ),
-#else
+#ifdef NO_SDDR09
 UNUSUAL_DEV(  0x07af, 0x0006, 0x0100, 0x0100,
                "Microtech",
                "CameraMate",
@@ -1104,108 +963,6 @@ UNUSUAL_DEV(  0x07af, 0x0006, 0x0100, 0x0100,
                US_FL_SINGLE_LUN ),
 #endif
 
-#ifdef CONFIG_USB_STORAGE_ALAUDA
-UNUSUAL_DEV(  0x07b4, 0x010a, 0x0102, 0x0102,
-               "Olympus",
-               "MAUSB-10 (Alauda)",
-               US_SC_SCSI, US_PR_ALAUDA, init_alauda, 0 ),
-#endif
-
-#ifdef CONFIG_USB_STORAGE_DATAFAB
-UNUSUAL_DEV(  0x07c4, 0xa000, 0x0000, 0x0015,
-               "Datafab",
-               "MDCFE-B USB CF Reader",
-               US_SC_SCSI, US_PR_DATAFAB, NULL,
-               0 ),
-
-/*
- * The following Datafab-based devices may or may not work
- * using the current driver...the 0xffff is arbitrary since I
- * don't know what device versions exist for these guys.
- *
- * The 0xa003 and 0xa004 devices in particular I'm curious about.
- * I'm told they exist but so far nobody has come forward to say that
- * they work with this driver.  Given the success we've had getting
- * other Datafab-based cards operational with this driver, I've decided
- * to leave these two devices in the list.
- */
-UNUSUAL_DEV( 0x07c4, 0xa001, 0x0000, 0xffff,
-               "SIIG/Datafab",
-               "SIIG/Datafab Memory Stick+CF Reader/Writer",
-               US_SC_SCSI, US_PR_DATAFAB, NULL,
-               0 ),
-
-/* Reported by Josef Reisinger <josef.reisinger@netcologne.de> */
-UNUSUAL_DEV( 0x07c4, 0xa002, 0x0000, 0xffff,
-               "Datafab/Unknown",
-               "MD2/MD3 Disk enclosure",
-               US_SC_SCSI, US_PR_DATAFAB, NULL,
-               US_FL_SINGLE_LUN ),
-
-UNUSUAL_DEV( 0x07c4, 0xa003, 0x0000, 0xffff,
-               "Datafab/Unknown",
-               "Datafab-based Reader",
-               US_SC_SCSI, US_PR_DATAFAB, NULL,
-               0 ),
-
-UNUSUAL_DEV( 0x07c4, 0xa004, 0x0000, 0xffff,
-               "Datafab/Unknown",
-               "Datafab-based Reader",
-               US_SC_SCSI, US_PR_DATAFAB, NULL,
-               0 ),
-
-UNUSUAL_DEV( 0x07c4, 0xa005, 0x0000, 0xffff,
-               "PNY/Datafab",
-               "PNY/Datafab CF+SM Reader",
-               US_SC_SCSI, US_PR_DATAFAB, NULL,
-               0 ),
-
-UNUSUAL_DEV( 0x07c4, 0xa006, 0x0000, 0xffff,
-               "Simple Tech/Datafab",
-               "Simple Tech/Datafab CF+SM Reader",
-               US_SC_SCSI, US_PR_DATAFAB, NULL,
-               0 ),
-#endif
-               
-#ifdef CONFIG_USB_STORAGE_SDDR55
-/* Contributed by Peter Waechtler */
-UNUSUAL_DEV( 0x07c4, 0xa103, 0x0000, 0x9999,
-               "Datafab",
-               "MDSM-B reader",
-               US_SC_SCSI, US_PR_SDDR55, NULL,
-               US_FL_FIX_INQUIRY ),
-#endif
-
-#ifdef CONFIG_USB_STORAGE_DATAFAB
-/* Submitted by Olaf Hering <olh@suse.de> */
-UNUSUAL_DEV(  0x07c4, 0xa109, 0x0000, 0xffff,
-               "Datafab Systems, Inc.",
-               "USB to CF + SM Combo (LC1)",
-               US_SC_SCSI, US_PR_DATAFAB, NULL,
-               0 ),
-#endif
-#ifdef CONFIG_USB_STORAGE_SDDR55
-/* SM part - aeb <Andries.Brouwer@cwi.nl> */
-UNUSUAL_DEV(  0x07c4, 0xa109, 0x0000, 0xffff,
-               "Datafab Systems, Inc.",
-               "USB to CF + SM Combo (LC1)",
-               US_SC_SCSI, US_PR_SDDR55, NULL,
-               US_FL_SINGLE_LUN ),
-#endif
-
-#ifdef CONFIG_USB_STORAGE_DATAFAB
-/* Reported by Felix Moeller <felix@derklecks.de>
- * in Germany this is sold by Hama with the productnumber 46952
- * as "DualSlot CompactFlash(TM) & MStick Drive USB"
- */
-UNUSUAL_DEV(  0x07c4, 0xa10b, 0x0000, 0xffff,
-               "DataFab Systems Inc.",
-               "USB CF+MS",
-               US_SC_SCSI, US_PR_DATAFAB, NULL,
-               0 ),
-
-#endif
-
 /* Datafab KECF-USB / Sagatek DCS-CF / Simpletech Flashlink UCF-100
  * Only revision 1.13 tested (same for all of the above devices,
  * based on the Datafab DF-UG-07 chip).  Needed for US_FL_FIX_INQUIRY.
@@ -1409,29 +1166,6 @@ UNUSUAL_DEV( 0x0bc2, 0x3010, 0x0000, 0x0000,
                US_SC_DEVICE, US_PR_DEVICE, NULL,
                US_FL_SANE_SENSE ),
 
-#ifdef CONFIG_USB_STORAGE_ISD200
-UNUSUAL_DEV(  0x0bf6, 0xa001, 0x0100, 0x0110,
-               "ATI",
-               "USB Cable 205",
-               US_SC_ISD200, US_PR_BULK, isd200_Initialization,
-               0 ),
-#endif
-
-#ifdef CONFIG_USB_STORAGE_DATAFAB
-UNUSUAL_DEV( 0x0c0b, 0xa109, 0x0000, 0xffff,
-               "Acomdata",
-               "CF",
-               US_SC_SCSI, US_PR_DATAFAB, NULL,
-               US_FL_SINGLE_LUN ),
-#endif
-#ifdef CONFIG_USB_STORAGE_SDDR55
-UNUSUAL_DEV( 0x0c0b, 0xa109, 0x0000, 0xffff,
-               "Acomdata",
-               "SM",
-               US_SC_SCSI, US_PR_SDDR55, NULL,
-               US_FL_SINGLE_LUN ),
-#endif
-
 UNUSUAL_DEV(  0x0d49, 0x7310, 0x0000, 0x9999,
                "Maxtor",
                "USB to SATA",
@@ -1448,23 +1182,6 @@ UNUSUAL_DEV( 0x0c45, 0x1060, 0x0100, 0x0100,
                US_SC_DEVICE, US_PR_DEVICE, NULL,
                US_FL_SINGLE_LUN ),
 
-/* Submitted by: Nick Sillik <n.sillik@temple.edu>
- * Needed for OneTouch extension to usb-storage
- *
- */
-#ifdef CONFIG_USB_STORAGE_ONETOUCH
-       UNUSUAL_DEV(  0x0d49, 0x7000, 0x0000, 0x9999,
-                       "Maxtor",
-                       "OneTouch External Harddrive",
-                       US_SC_DEVICE, US_PR_DEVICE, onetouch_connect_input,
-                       0),
-       UNUSUAL_DEV(  0x0d49, 0x7010, 0x0000, 0x9999,
-                       "Maxtor",
-                       "OneTouch External Harddrive",
-                       US_SC_DEVICE, US_PR_DEVICE, onetouch_connect_input,
-                       0),
-#endif
-
 /* Submitted by Joris Struyve <joris@struyve.be> */
 UNUSUAL_DEV( 0x0d96, 0x410a, 0x0001, 0xffff,
                "Medion",
@@ -2117,14 +1834,6 @@ UNUSUAL_DEV(  0x4146, 0xba01, 0x0100, 0x0100,
                "Micro Mini 1GB",
                US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_NOT_LOCKABLE ),
 
-#ifdef CONFIG_USB_STORAGE_SDDR55
-UNUSUAL_DEV(  0x55aa, 0xa103, 0x0000, 0x9999, 
-               "Sandisk",
-               "ImageMate SDDR55",
-               US_SC_SCSI, US_PR_SDDR55, NULL,
-               US_FL_SINGLE_LUN),
-#endif
-
 /* Reported by Andrew Simmons <andrew.simmons@gmail.com> */
 UNUSUAL_DEV(  0xed06, 0x4500, 0x0001, 0x0001,
                "DataStor",
similarity index 68%
rename from drivers/usb/storage/cypress_atacb.h
rename to drivers/usb/storage/unusual_freecom.h
index fbada898d56b371255687727cb7762ae4ea22021..3758679423918d9879906b492243600f3115c637 100644 (file)
@@ -1,8 +1,4 @@
-/*
- * Support for emulating SAT (ata pass through) on devices based
- *       on the Cypress USB/ATA bridge supporting ATACB.
- *
- * Copyright (c) 2008 Matthieu Castet (castet.matthieu@free.fr)
+/* Unusual Devices File for the Freecom USB/IDE adaptor
  *
  * 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
  * 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#ifndef _CYPRESS_ATACB_H_
-#define _CYPRESS_ATACB_H_
-extern void cypress_atacb_passthrough(struct scsi_cmnd*, struct us_data*);
-#endif
+#if defined(CONFIG_USB_STORAGE_FREECOM) || \
+               defined(CONFIG_USB_STORAGE_FREECOM_MODULE)
+
+UNUSUAL_DEV(  0x07ab, 0xfc01, 0x0000, 0x9999,
+               "Freecom",
+               "USB-IDE",
+               US_SC_QIC, US_PR_FREECOM, init_freecom, 0),
+
+#endif /* defined(CONFIG_USB_STORAGE_FREECOM) || ... */
diff --git a/drivers/usb/storage/unusual_isd200.h b/drivers/usb/storage/unusual_isd200.h
new file mode 100644 (file)
index 0000000..0d99dde
--- /dev/null
@@ -0,0 +1,57 @@
+/* Unusual Devices File for In-System Design, Inc. ISD200 ASIC
+ *
+ * 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.
+ */
+
+#if defined(CONFIG_USB_STORAGE_ISD200) || \
+               defined(CONFIG_USB_STORAGE_ISD200_MODULE)
+
+UNUSUAL_DEV(  0x054c, 0x002b, 0x0100, 0x0110,
+               "Sony",
+               "Portable USB Harddrive V2",
+               US_SC_ISD200, US_PR_BULK, isd200_Initialization,
+               0),
+
+UNUSUAL_DEV(  0x05ab, 0x0031, 0x0100, 0x0110,
+               "In-System",
+               "USB/IDE Bridge (ATA/ATAPI)",
+               US_SC_ISD200, US_PR_BULK, isd200_Initialization,
+               0),
+
+UNUSUAL_DEV(  0x05ab, 0x0301, 0x0100, 0x0110,
+               "In-System",
+               "Portable USB Harddrive V2",
+               US_SC_ISD200, US_PR_BULK, isd200_Initialization,
+               0),
+
+UNUSUAL_DEV(  0x05ab, 0x0351, 0x0100, 0x0110,
+               "In-System",
+               "Portable USB Harddrive V2",
+               US_SC_ISD200, US_PR_BULK, isd200_Initialization,
+               0),
+
+UNUSUAL_DEV(  0x05ab, 0x5701, 0x0100, 0x0110,
+               "In-System",
+               "USB Storage Adapter V2",
+               US_SC_ISD200, US_PR_BULK, isd200_Initialization,
+               0),
+
+UNUSUAL_DEV(  0x0bf6, 0xa001, 0x0100, 0x0110,
+               "ATI",
+               "USB Cable 205",
+               US_SC_ISD200, US_PR_BULK, isd200_Initialization,
+               0),
+
+#endif /* defined(CONFIG_USB_STORAGE_ISD200) || ... */
similarity index 63%
rename from drivers/usb/storage/sddr55.h
rename to drivers/usb/storage/unusual_jumpshot.h
index a815a0470c84707bd14b47f32cc2502e84fd5e7d..2e549b1c2c6205af9adf42031428448196ee597c 100644 (file)
@@ -1,10 +1,4 @@
-/* Driver for SanDisk SDDR-55 SmartMedia reader
- * Header File
- *
- * Current development and maintenance by:
- *   (c) 2002 Simon Munton
- *
- * See sddr55.c for more explanation
+/* Unusual Devices File for the Lexar "Jumpshot" Compact Flash reader
  *
  * 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
  * 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#ifndef _USB_SHUTTLE_EUSB_SDDR55_H
-#define _USB_SHUTTLE_EUSB_SDDR55_H
-
-/* Sandisk SDDR-55 stuff */
+#if defined(CONFIG_USB_STORAGE_JUMPSHOT) || \
+               defined(CONFIG_USB_STORAGE_JUMPSHOT_MODULE)
 
-extern int sddr55_transport(struct scsi_cmnd *srb, struct us_data *us);
-extern int sddr55_reset(struct us_data *us);
+UNUSUAL_DEV(  0x05dc, 0x0001, 0x0000, 0x0001,
+               "Lexar",
+               "Jumpshot USB CF Reader",
+               US_SC_SCSI, US_PR_JUMPSHOT, NULL,
+               US_FL_NEED_OVERRIDE),
 
-#endif
+#endif /* defined(CONFIG_USB_STORAGE_JUMPSHOT) || ... */
similarity index 63%
rename from drivers/usb/storage/isd200.h
rename to drivers/usb/storage/unusual_karma.h
index 0a35f4fa78f8d156a25261b29c7842e9781f84d8..12ae3a03e802cf4a6193971c25008fa3d87ddd53 100644 (file)
@@ -1,11 +1,4 @@
-/* Header File for In-System Design, Inc. ISD200 ASIC
- *
- * First release
- *
- * Current development and maintenance by:
- *   (c) 2000 In-System Design, Inc. (support@in-system.com)
- *
- * See isd200.c for more information.
+/* Unusual Devices File for the Rio Karma
  *
  * 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
  * 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#ifndef _USB_ISD200_H
-#define _USB_ISD200_H
+#if defined(CONFIG_USB_STORAGE_KARMA) || \
+               defined(CONFIG_USB_STORAGE_KARMA_MODULE)
 
-extern void isd200_ata_command(struct scsi_cmnd *srb, struct us_data *us);
-extern int isd200_Initialization(struct us_data *us);
+UNUSUAL_DEV(  0x045a, 0x5210, 0x0101, 0x0101,
+               "Rio",
+               "Rio Karma",
+               US_SC_SCSI, US_PR_KARMA, rio_karma_init, 0),
 
-#endif
+#endif /* defined(CONFIG_USB_STORAGE_KARMA) || ... */
diff --git a/drivers/usb/storage/unusual_onetouch.h b/drivers/usb/storage/unusual_onetouch.h
new file mode 100644 (file)
index 0000000..bd9306b
--- /dev/null
@@ -0,0 +1,36 @@
+/* Unusual Devices File for the Maxtor OneTouch USB hard drive's button
+ *
+ * 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.
+ */
+
+#if defined(CONFIG_USB_STORAGE_ONETOUCH) || \
+               defined(CONFIG_USB_STORAGE_ONETOUCH_MODULE)
+
+/* Submitted by: Nick Sillik <n.sillik@temple.edu>
+ * Needed for OneTouch extension to usb-storage
+ */
+UNUSUAL_DEV(  0x0d49, 0x7000, 0x0000, 0x9999,
+               "Maxtor",
+               "OneTouch External Harddrive",
+               US_SC_DEVICE, US_PR_DEVICE, onetouch_connect_input,
+               0),
+
+UNUSUAL_DEV(  0x0d49, 0x7010, 0x0000, 0x9999,
+               "Maxtor",
+               "OneTouch External Harddrive",
+               US_SC_DEVICE, US_PR_DEVICE, onetouch_connect_input,
+               0),
+
+#endif /* defined(CONFIG_USB_STORAGE_ONETOUCH) || ... */
diff --git a/drivers/usb/storage/unusual_sddr09.h b/drivers/usb/storage/unusual_sddr09.h
new file mode 100644 (file)
index 0000000..50cab51
--- /dev/null
@@ -0,0 +1,56 @@
+/* Unusual Devices File for SanDisk SDDR-09 SmartMedia reader
+ *
+ * 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.
+ */
+
+#if defined(CONFIG_USB_STORAGE_SDDR09) || \
+               defined(CONFIG_USB_STORAGE_SDDR09_MODULE)
+
+UNUSUAL_DEV(  0x0436, 0x0005, 0x0100, 0x0100,
+               "Microtech",
+               "CameraMate (DPCM_USB)",
+               US_SC_SCSI, US_PR_DPCM_USB, NULL, 0),
+
+UNUSUAL_DEV(  0x04e6, 0x0003, 0x0000, 0x9999,
+               "Sandisk",
+               "ImageMate SDDR09",
+               US_SC_SCSI, US_PR_EUSB_SDDR09, usb_stor_sddr09_init,
+               0),
+
+/* This entry is from Andries.Brouwer@cwi.nl */
+UNUSUAL_DEV(  0x04e6, 0x0005, 0x0100, 0x0208,
+               "SCM Microsystems",
+               "eUSB SmartMedia / CompactFlash Adapter",
+               US_SC_SCSI, US_PR_DPCM_USB, usb_stor_sddr09_dpcm_init,
+               0),
+
+UNUSUAL_DEV(  0x066b, 0x0105, 0x0100, 0x0100,
+               "Olympus",
+               "Camedia MAUSB-2",
+               US_SC_SCSI, US_PR_EUSB_SDDR09, usb_stor_sddr09_init,
+               0),
+
+UNUSUAL_DEV(  0x0781, 0x0200, 0x0000, 0x9999,
+               "Sandisk",
+               "ImageMate SDDR-09",
+               US_SC_SCSI, US_PR_EUSB_SDDR09, usb_stor_sddr09_init,
+               0),
+
+UNUSUAL_DEV(  0x07af, 0x0006, 0x0100, 0x0100,
+               "Microtech",
+               "CameraMate (DPCM_USB)",
+               US_SC_SCSI, US_PR_DPCM_USB, NULL, 0),
+
+#endif /* defined(CONFIG_USB_STORAGE_SDDR09) || ... */
diff --git a/drivers/usb/storage/unusual_sddr55.h b/drivers/usb/storage/unusual_sddr55.h
new file mode 100644 (file)
index 0000000..ae81ef7
--- /dev/null
@@ -0,0 +1,44 @@
+/* Unusual Devices File for SanDisk SDDR-55 SmartMedia reader
+ *
+ * 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.
+ */
+
+#if defined(CONFIG_USB_STORAGE_SDDR55) || \
+               defined(CONFIG_USB_STORAGE_SDDR55_MODULE)
+
+/* Contributed by Peter Waechtler */
+UNUSUAL_DEV( 0x07c4, 0xa103, 0x0000, 0x9999,
+               "Datafab",
+               "MDSM-B reader",
+               US_SC_SCSI, US_PR_SDDR55, NULL,
+               US_FL_FIX_INQUIRY),
+
+/* SM part - aeb <Andries.Brouwer@cwi.nl> */
+UNUSUAL_DEV(  0x07c4, 0xa109, 0x0000, 0xffff,
+               "Datafab Systems, Inc.",
+               "USB to CF + SM Combo (LC1)",
+               US_SC_SCSI, US_PR_SDDR55, NULL, 0),
+
+UNUSUAL_DEV( 0x0c0b, 0xa109, 0x0000, 0xffff,
+               "Acomdata",
+               "SM",
+               US_SC_SCSI, US_PR_SDDR55, NULL, 0),
+
+UNUSUAL_DEV(  0x55aa, 0xa103, 0x0000, 0x9999,
+               "Sandisk",
+               "ImageMate SDDR55",
+               US_SC_SCSI, US_PR_SDDR55, NULL, 0),
+
+#endif /* defined(CONFIG_USB_STORAGE_SDDR55) || ... */
diff --git a/drivers/usb/storage/unusual_usbat.h b/drivers/usb/storage/unusual_usbat.h
new file mode 100644 (file)
index 0000000..80e869f
--- /dev/null
@@ -0,0 +1,43 @@
+/* Unusual Devices File for SCM Microsystems (a.k.a. Shuttle) USB-ATAPI cable
+ *
+ * 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.
+ */
+
+#if defined(CONFIG_USB_STORAGE_USBAT) || \
+               defined(CONFIG_USB_STORAGE_USBAT_MODULE)
+
+UNUSUAL_DEV(  0x03f0, 0x0207, 0x0001, 0x0001,
+               "HP",
+               "CD-Writer+ 8200e",
+               US_SC_8070, US_PR_USBAT, init_usbat_cd, 0),
+
+UNUSUAL_DEV(  0x03f0, 0x0307, 0x0001, 0x0001,
+               "HP",
+               "CD-Writer+ CD-4e",
+               US_SC_8070, US_PR_USBAT, init_usbat_cd, 0),
+
+UNUSUAL_DEV(  0x04e6, 0x1010, 0x0000, 0x9999,
+               "Shuttle/SCM",
+               "USBAT-02",
+               US_SC_SCSI, US_PR_USBAT, init_usbat_flash,
+               US_FL_SINGLE_LUN),
+
+UNUSUAL_DEV(  0x0781, 0x0005, 0x0005, 0x0005,
+               "Sandisk",
+               "ImageMate SDDR-05b",
+               US_SC_SCSI, US_PR_USBAT, init_usbat_flash,
+               US_FL_SINGLE_LUN),
+
+#endif /* defined(CONFIG_USB_STORAGE_USBAT) || ... */
index 4becf495ca2dc7cb4a092fdc898550e83e3a2144..8060b85fe1a3fb377476e1cd0a6de55df6de9014 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Developed with the assistance of:
  *   (c) 2000 David L. Brown, Jr. (usb-storage@davidb.org)
- *   (c) 2003 Alan Stern (stern@rowland.harvard.edu)
+ *   (c) 2003-2009 Alan Stern (stern@rowland.harvard.edu)
  *
  * Initial work by:
  *   (c) 1999 Michael Gee (michael@linuxspecific.com)
 #include "debug.h"
 #include "initializers.h"
 
-#ifdef CONFIG_USB_STORAGE_USBAT
-#include "shuttle_usbat.h"
-#endif
-#ifdef CONFIG_USB_STORAGE_SDDR09
-#include "sddr09.h"
-#endif
-#ifdef CONFIG_USB_STORAGE_SDDR55
-#include "sddr55.h"
-#endif
-#ifdef CONFIG_USB_STORAGE_FREECOM
-#include "freecom.h"
-#endif
-#ifdef CONFIG_USB_STORAGE_ISD200
-#include "isd200.h"
-#endif
-#ifdef CONFIG_USB_STORAGE_DATAFAB
-#include "datafab.h"
-#endif
-#ifdef CONFIG_USB_STORAGE_JUMPSHOT
-#include "jumpshot.h"
-#endif
-#ifdef CONFIG_USB_STORAGE_ONETOUCH
-#include "onetouch.h"
-#endif
-#ifdef CONFIG_USB_STORAGE_ALAUDA
-#include "alauda.h"
-#endif
-#ifdef CONFIG_USB_STORAGE_KARMA
-#include "karma.h"
-#endif
-#ifdef CONFIG_USB_STORAGE_CYPRESS_ATACB
-#include "cypress_atacb.h"
-#endif
 #include "sierra_ms.h"
 #include "option_ms.h"
 
@@ -118,36 +85,8 @@ MODULE_PARM_DESC(quirks, "supplemental list of device IDs and their quirks");
 
 /*
  * The entries in this table correspond, line for line,
- * with the entries of us_unusual_dev_list[].
+ * with the entries in usb_storage_usb_ids[], defined in usual-tables.c.
  */
-#ifndef CONFIG_USB_LIBUSUAL
-
-#define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \
-                   vendorName, productName,useProtocol, useTransport, \
-                   initFunction, flags) \
-{ USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin,bcdDeviceMax), \
-  .driver_info = (flags)|(USB_US_TYPE_STOR<<24) }
-
-#define COMPLIANT_DEV  UNUSUAL_DEV
-
-#define USUAL_DEV(useProto, useTrans, useType) \
-{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, useProto, useTrans), \
-  .driver_info = (USB_US_TYPE_STOR<<24) }
-
-static struct usb_device_id storage_usb_ids [] = {
-
-#      include "unusual_devs.h"
-#undef UNUSUAL_DEV
-#undef COMPLIANT_DEV
-#undef USUAL_DEV
-       /* Terminating entry */
-       { }
-};
-
-MODULE_DEVICE_TABLE (usb, storage_usb_ids);
-#endif /* CONFIG_USB_LIBUSUAL */
-
-/* This is the list of devices we recognize, along with their flag data */
 
 /* The vendor name should be kept at eight characters or less, and
  * the product name should be kept at 16 characters or less. If a device
@@ -179,18 +118,17 @@ MODULE_DEVICE_TABLE (usb, storage_usb_ids);
 
 static struct us_unusual_dev us_unusual_dev_list[] = {
 #      include "unusual_devs.h" 
-#      undef UNUSUAL_DEV
-#      undef COMPLIANT_DEV
-#      undef USUAL_DEV
-
-       /* Terminating entry */
-       { NULL }
+       { }             /* Terminating entry */
 };
 
+#undef UNUSUAL_DEV
+#undef COMPLIANT_DEV
+#undef USUAL_DEV
+
 
 #ifdef CONFIG_PM       /* Minimal support for suspend and resume */
 
-static int storage_suspend(struct usb_interface *iface, pm_message_t message)
+int usb_stor_suspend(struct usb_interface *iface, pm_message_t message)
 {
        struct us_data *us = usb_get_intfdata(iface);
 
@@ -207,8 +145,9 @@ static int storage_suspend(struct usb_interface *iface, pm_message_t message)
        mutex_unlock(&us->dev_mutex);
        return 0;
 }
+EXPORT_SYMBOL_GPL(usb_stor_suspend);
 
-static int storage_resume(struct usb_interface *iface)
+int usb_stor_resume(struct usb_interface *iface)
 {
        struct us_data *us = usb_get_intfdata(iface);
 
@@ -221,8 +160,9 @@ static int storage_resume(struct usb_interface *iface)
        mutex_unlock(&us->dev_mutex);
        return 0;
 }
+EXPORT_SYMBOL_GPL(usb_stor_resume);
 
-static int storage_reset_resume(struct usb_interface *iface)
+int usb_stor_reset_resume(struct usb_interface *iface)
 {
        struct us_data *us = usb_get_intfdata(iface);
 
@@ -235,6 +175,7 @@ static int storage_reset_resume(struct usb_interface *iface)
         * the device */
        return 0;
 }
+EXPORT_SYMBOL_GPL(usb_stor_reset_resume);
 
 #endif /* CONFIG_PM */
 
@@ -243,7 +184,7 @@ static int storage_reset_resume(struct usb_interface *iface)
  * a USB port reset, whether from this driver or a different one.
  */
 
-static int storage_pre_reset(struct usb_interface *iface)
+int usb_stor_pre_reset(struct usb_interface *iface)
 {
        struct us_data *us = usb_get_intfdata(iface);
 
@@ -253,8 +194,9 @@ static int storage_pre_reset(struct usb_interface *iface)
        mutex_lock(&us->dev_mutex);
        return 0;
 }
+EXPORT_SYMBOL_GPL(usb_stor_pre_reset);
 
-static int storage_post_reset(struct usb_interface *iface)
+int usb_stor_post_reset(struct usb_interface *iface)
 {
        struct us_data *us = usb_get_intfdata(iface);
 
@@ -269,6 +211,7 @@ static int storage_post_reset(struct usb_interface *iface)
        mutex_unlock(&us->dev_mutex);
        return 0;
 }
+EXPORT_SYMBOL_GPL(usb_stor_post_reset);
 
 /*
  * fill_inquiry_response takes an unsigned char array (which must
@@ -311,6 +254,7 @@ void fill_inquiry_response(struct us_data *us, unsigned char *data,
 
        usb_stor_set_xfer_buf(data, data_len, us->srb);
 }
+EXPORT_SYMBOL_GPL(fill_inquiry_response);
 
 static int usb_stor_control_thread(void * __us)
 {
@@ -551,20 +495,13 @@ static void adjust_quirks(struct us_data *us)
                        vid, pid, f);
 }
 
-/* Find an unusual_dev descriptor (always succeeds in the current code) */
-static struct us_unusual_dev *find_unusual(const struct usb_device_id *id)
-{
-       const int id_index = id - storage_usb_ids;
-       return &us_unusual_dev_list[id_index];
-}
-
 /* Get the unusual_devs entries and the string descriptors */
-static int get_device_info(struct us_data *us, const struct usb_device_id *id)
+static int get_device_info(struct us_data *us, const struct usb_device_id *id,
+               struct us_unusual_dev *unusual_dev)
 {
        struct usb_device *dev = us->pusb_dev;
        struct usb_interface_descriptor *idesc =
                &us->pusb_intf->cur_altsetting->desc;
-       struct us_unusual_dev *unusual_dev = find_unusual(id);
 
        /* Store the entries */
        us->unusual_dev = unusual_dev;
@@ -629,7 +566,7 @@ static int get_device_info(struct us_data *us, const struct usb_device_id *id)
 }
 
 /* Get the transport settings */
-static int get_transport(struct us_data *us)
+static void get_transport(struct us_data *us)
 {
        switch (us->protocol) {
        case US_PR_CB:
@@ -651,100 +588,11 @@ static int get_transport(struct us_data *us)
                us->transport = usb_stor_Bulk_transport;
                us->transport_reset = usb_stor_Bulk_reset;
                break;
-
-#ifdef CONFIG_USB_STORAGE_USBAT
-       case US_PR_USBAT:
-               us->transport_name = "Shuttle USBAT";
-               us->transport = usbat_transport;
-               us->transport_reset = usb_stor_CB_reset;
-               us->max_lun = 1;
-               break;
-#endif
-
-#ifdef CONFIG_USB_STORAGE_SDDR09
-       case US_PR_EUSB_SDDR09:
-               us->transport_name = "EUSB/SDDR09";
-               us->transport = sddr09_transport;
-               us->transport_reset = usb_stor_CB_reset;
-               us->max_lun = 0;
-               break;
-#endif
-
-#ifdef CONFIG_USB_STORAGE_SDDR55
-       case US_PR_SDDR55:
-               us->transport_name = "SDDR55";
-               us->transport = sddr55_transport;
-               us->transport_reset = sddr55_reset;
-               us->max_lun = 0;
-               break;
-#endif
-
-#ifdef CONFIG_USB_STORAGE_DPCM
-       case US_PR_DPCM_USB:
-               us->transport_name = "Control/Bulk-EUSB/SDDR09";
-               us->transport = dpcm_transport;
-               us->transport_reset = usb_stor_CB_reset;
-               us->max_lun = 1;
-               break;
-#endif
-
-#ifdef CONFIG_USB_STORAGE_FREECOM
-       case US_PR_FREECOM:
-               us->transport_name = "Freecom";
-               us->transport = freecom_transport;
-               us->transport_reset = usb_stor_freecom_reset;
-               us->max_lun = 0;
-               break;
-#endif
-
-#ifdef CONFIG_USB_STORAGE_DATAFAB
-       case US_PR_DATAFAB:
-               us->transport_name  = "Datafab Bulk-Only";
-               us->transport = datafab_transport;
-               us->transport_reset = usb_stor_Bulk_reset;
-               us->max_lun = 1;
-               break;
-#endif
-
-#ifdef CONFIG_USB_STORAGE_JUMPSHOT
-       case US_PR_JUMPSHOT:
-               us->transport_name  = "Lexar Jumpshot Control/Bulk";
-               us->transport = jumpshot_transport;
-               us->transport_reset = usb_stor_Bulk_reset;
-               us->max_lun = 1;
-               break;
-#endif
-
-#ifdef CONFIG_USB_STORAGE_ALAUDA
-       case US_PR_ALAUDA:
-               us->transport_name  = "Alauda Control/Bulk";
-               us->transport = alauda_transport;
-               us->transport_reset = usb_stor_Bulk_reset;
-               us->max_lun = 1;
-               break;
-#endif
-
-#ifdef CONFIG_USB_STORAGE_KARMA
-       case US_PR_KARMA:
-               us->transport_name = "Rio Karma/Bulk";
-               us->transport = rio_karma_transport;
-               us->transport_reset = usb_stor_Bulk_reset;
-               break;
-#endif
-
-       default:
-               return -EIO;
        }
-       US_DEBUGP("Transport: %s\n", us->transport_name);
-
-       /* fix for single-lun devices */
-       if (us->fflags & US_FL_SINGLE_LUN)
-               us->max_lun = 0;
-       return 0;
 }
 
 /* Get the protocol settings */
-static int get_protocol(struct us_data *us)
+static void get_protocol(struct us_data *us)
 {
        switch (us->subclass) {
        case US_SC_RBC:
@@ -779,26 +627,7 @@ static int get_protocol(struct us_data *us)
                us->protocol_name = "Uniform Floppy Interface (UFI)";
                us->proto_handler = usb_stor_ufi_command;
                break;
-
-#ifdef CONFIG_USB_STORAGE_ISD200
-       case US_SC_ISD200:
-               us->protocol_name = "ISD200 ATA/ATAPI";
-               us->proto_handler = isd200_ata_command;
-               break;
-#endif
-
-#ifdef CONFIG_USB_STORAGE_CYPRESS_ATACB
-       case US_SC_CYP_ATACB:
-               us->protocol_name = "Transparent SCSI with Cypress ATACB";
-               us->proto_handler = cypress_atacb_passthrough;
-               break;
-#endif
-
-       default:
-               return -EIO;
        }
-       US_DEBUGP("Protocol: %s\n", us->protocol_name);
-       return 0;
 }
 
 /* Get the pipe settings */
@@ -846,12 +675,12 @@ static int get_pipes(struct us_data *us)
        us->send_ctrl_pipe = usb_sndctrlpipe(us->pusb_dev, 0);
        us->recv_ctrl_pipe = usb_rcvctrlpipe(us->pusb_dev, 0);
        us->send_bulk_pipe = usb_sndbulkpipe(us->pusb_dev,
-               ep_out->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
+               usb_endpoint_num(ep_out));
        us->recv_bulk_pipe = usb_rcvbulkpipe(us->pusb_dev, 
-               ep_in->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
+               usb_endpoint_num(ep_in));
        if (ep_int) {
                us->recv_intr_pipe = usb_rcvintpipe(us->pusb_dev,
-                       ep_int->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
+                       usb_endpoint_num(ep_int));
                us->ep_bInterval = ep_int->bInterval;
        }
        return 0;
@@ -1012,17 +841,15 @@ static int usb_stor_scan_thread(void * __us)
 }
 
 
-/* Probe to see if we can drive a newly-connected USB device */
-static int storage_probe(struct usb_interface *intf,
-                        const struct usb_device_id *id)
+/* First part of general USB mass-storage probing */
+int usb_stor_probe1(struct us_data **pus,
+               struct usb_interface *intf,
+               const struct usb_device_id *id,
+               struct us_unusual_dev *unusual_dev)
 {
        struct Scsi_Host *host;
        struct us_data *us;
        int result;
-       struct task_struct *th;
-
-       if (usb_usual_check_type(id, USB_US_TYPE_STOR))
-               return -ENXIO;
 
        US_DEBUGP("USB Mass Storage device detected\n");
 
@@ -1041,7 +868,7 @@ static int storage_probe(struct usb_interface *intf,
         * Allow 16-byte CDBs and thus > 2TB
         */
        host->max_cmd_len = 16;
-       us = host_to_us(host);
+       *pus = us = host_to_us(host);
        memset(us, 0, sizeof(struct us_data));
        mutex_init(&(us->dev_mutex));
        init_completion(&us->cmnd_ready);
@@ -1054,24 +881,46 @@ static int storage_probe(struct usb_interface *intf,
        if (result)
                goto BadDevice;
 
-       /*
-        * Get the unusual_devs entries and the descriptors
-        *
-        * id_index is calculated in the declaration to be the index number
-        * of the match from the usb_device_id table, so we can find the
-        * corresponding entry in the private table.
-        */
-       result = get_device_info(us, id);
+       /* Get the unusual_devs entries and the descriptors */
+       result = get_device_info(us, id, unusual_dev);
        if (result)
                goto BadDevice;
 
-       /* Get the transport, protocol, and pipe settings */
-       result = get_transport(us);
-       if (result)
-               goto BadDevice;
-       result = get_protocol(us);
-       if (result)
+       /* Get standard transport and protocol settings */
+       get_transport(us);
+       get_protocol(us);
+
+       /* Give the caller a chance to fill in specialized transport
+        * or protocol settings.
+        */
+       return 0;
+
+BadDevice:
+       US_DEBUGP("storage_probe() failed\n");
+       release_everything(us);
+       return result;
+}
+EXPORT_SYMBOL_GPL(usb_stor_probe1);
+
+/* Second part of general USB mass-storage probing */
+int usb_stor_probe2(struct us_data *us)
+{
+       struct task_struct *th;
+       int result;
+
+       /* Make sure the transport and protocol have both been set */
+       if (!us->transport || !us->proto_handler) {
+               result = -ENXIO;
                goto BadDevice;
+       }
+       US_DEBUGP("Transport: %s\n", us->transport_name);
+       US_DEBUGP("Protocol: %s\n", us->protocol_name);
+
+       /* fix for single-lun devices */
+       if (us->fflags & US_FL_SINGLE_LUN)
+               us->max_lun = 0;
+
+       /* Find the endpoints and calculate pipe values */
        result = get_pipes(us);
        if (result)
                goto BadDevice;
@@ -1080,7 +929,7 @@ static int storage_probe(struct usb_interface *intf,
        result = usb_stor_acquire_resources(us);
        if (result)
                goto BadDevice;
-       result = scsi_add_host(host, &intf->dev);
+       result = scsi_add_host(us_to_host(us), &us->pusb_intf->dev);
        if (result) {
                printk(KERN_WARNING USB_STORAGE
                        "Unable to add the scsi host\n");
@@ -1108,9 +957,10 @@ BadDevice:
        release_everything(us);
        return result;
 }
+EXPORT_SYMBOL_GPL(usb_stor_probe2);
 
-/* Handle a disconnect event from the USB core */
-static void storage_disconnect(struct usb_interface *intf)
+/* Handle a USB mass-storage disconnect */
+void usb_stor_disconnect(struct usb_interface *intf)
 {
        struct us_data *us = usb_get_intfdata(intf);
 
@@ -1118,6 +968,42 @@ static void storage_disconnect(struct usb_interface *intf)
        quiesce_and_remove_host(us);
        release_everything(us);
 }
+EXPORT_SYMBOL_GPL(usb_stor_disconnect);
+
+/* The main probe routine for standard devices */
+static int storage_probe(struct usb_interface *intf,
+                        const struct usb_device_id *id)
+{
+       struct us_data *us;
+       int result;
+
+       /*
+        * If libusual is configured, let it decide whether a standard
+        * device should be handled by usb-storage or by ub.
+        * If the device isn't standard (is handled by a subdriver
+        * module) then don't accept it.
+        */
+       if (usb_usual_check_type(id, USB_US_TYPE_STOR) ||
+                       usb_usual_ignore_device(intf))
+               return -ENXIO;
+
+       /*
+        * Call the general probe procedures.
+        *
+        * The unusual_dev_list array is parallel to the usb_storage_usb_ids
+        * table, so we use the index of the id entry to find the
+        * corresponding unusual_devs entry.
+        */
+       result = usb_stor_probe1(&us, intf, id,
+                       (id - usb_storage_usb_ids) + us_unusual_dev_list);
+       if (result)
+               return result;
+
+       /* No special transport or protocol settings in the main module */
+
+       result = usb_stor_probe2(us);
+       return result;
+}
 
 /***********************************************************************
  * Initialization and registration
@@ -1126,15 +1012,13 @@ static void storage_disconnect(struct usb_interface *intf)
 static struct usb_driver usb_storage_driver = {
        .name =         "usb-storage",
        .probe =        storage_probe,
-       .disconnect =   storage_disconnect,
-#ifdef CONFIG_PM
-       .suspend =      storage_suspend,
-       .resume =       storage_resume,
-       .reset_resume = storage_reset_resume,
-#endif
-       .pre_reset =    storage_pre_reset,
-       .post_reset =   storage_post_reset,
-       .id_table =     storage_usb_ids,
+       .disconnect =   usb_stor_disconnect,
+       .suspend =      usb_stor_suspend,
+       .resume =       usb_stor_resume,
+       .reset_resume = usb_stor_reset_resume,
+       .pre_reset =    usb_stor_pre_reset,
+       .post_reset =   usb_stor_post_reset,
+       .id_table =     usb_storage_usb_ids,
        .soft_unbind =  1,
 };
 
index 65e674e4be99add0b5a2f81b4bef7d81e7fbb51c..2609efb2bd7ea86da818450e241aaf835ea46a77 100644 (file)
@@ -177,4 +177,25 @@ extern void fill_inquiry_response(struct us_data *us,
 #define scsi_unlock(host)      spin_unlock_irq(host->host_lock)
 #define scsi_lock(host)                spin_lock_irq(host->host_lock)
 
+/* General routines provided by the usb-storage standard core */
+#ifdef CONFIG_PM
+extern int usb_stor_suspend(struct usb_interface *iface, pm_message_t message);
+extern int usb_stor_resume(struct usb_interface *iface);
+extern int usb_stor_reset_resume(struct usb_interface *iface);
+#else
+#define usb_stor_suspend       NULL
+#define usb_stor_resume                NULL
+#define usb_stor_reset_resume  NULL
+#endif
+
+extern int usb_stor_pre_reset(struct usb_interface *iface);
+extern int usb_stor_post_reset(struct usb_interface *iface);
+
+extern int usb_stor_probe1(struct us_data **pus,
+               struct usb_interface *intf,
+               const struct usb_device_id *id,
+               struct us_unusual_dev *unusual_dev);
+extern int usb_stor_probe2(struct us_data *us);
+extern void usb_stor_disconnect(struct usb_interface *intf);
+
 #endif
diff --git a/drivers/usb/storage/usual-tables.c b/drivers/usb/storage/usual-tables.c
new file mode 100644 (file)
index 0000000..468bde7
--- /dev/null
@@ -0,0 +1,116 @@
+/* Driver for USB Mass Storage devices
+ * Usual Tables File for usb-storage and libusual
+ *
+ * Copyright (C) 2009 Alan Stern (stern@rowland.harvard.edu)
+ *
+ * Please see http://www.one-eyed-alien.net/~mdharm/linux-usb for more
+ * information about this driver.
+ *
+ * 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/usb_usual.h>
+
+
+/*
+ * The table of devices
+ */
+#define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \
+                   vendorName, productName, useProtocol, useTransport, \
+                   initFunction, flags) \
+{ USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \
+  .driver_info = (flags)|(USB_US_TYPE_STOR<<24) }
+
+#define COMPLIANT_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \
+                   vendorName, productName, useProtocol, useTransport, \
+                   initFunction, flags) \
+{ USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \
+  .driver_info = (flags) }
+
+#define USUAL_DEV(useProto, useTrans, useType) \
+{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, useProto, useTrans), \
+  .driver_info = ((useType)<<24) }
+
+struct usb_device_id usb_storage_usb_ids[] = {
+#      include "unusual_devs.h"
+       { }             /* Terminating entry */
+};
+EXPORT_SYMBOL_GPL(usb_storage_usb_ids);
+
+MODULE_DEVICE_TABLE(usb, usb_storage_usb_ids);
+
+#undef UNUSUAL_DEV
+#undef COMPLIANT_DEV
+#undef USUAL_DEV
+
+
+/*
+ * The table of devices to ignore
+ */
+struct ignore_entry {
+       u16     vid, pid, bcdmin, bcdmax;
+};
+
+#define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \
+                   vendorName, productName, useProtocol, useTransport, \
+                   initFunction, flags) \
+{                                      \
+       .vid    = id_vendor,            \
+       .pid    = id_product,           \
+       .bcdmin = bcdDeviceMin,         \
+       .bcdmax = bcdDeviceMax,         \
+}
+
+static struct ignore_entry ignore_ids[] = {
+#      include "unusual_alauda.h"
+#      include "unusual_cypress.h"
+#      include "unusual_datafab.h"
+#      include "unusual_freecom.h"
+#      include "unusual_isd200.h"
+#      include "unusual_jumpshot.h"
+#      include "unusual_karma.h"
+#      include "unusual_onetouch.h"
+#      include "unusual_sddr09.h"
+#      include "unusual_sddr55.h"
+#      include "unusual_usbat.h"
+       { }             /* Terminating entry */
+};
+
+#undef UNUSUAL_DEV
+
+
+/* Return an error if a device is in the ignore_ids list */
+int usb_usual_ignore_device(struct usb_interface *intf)
+{
+       struct usb_device *udev;
+       unsigned vid, pid, bcd;
+       struct ignore_entry *p;
+
+       udev = interface_to_usbdev(intf);
+       vid = le16_to_cpu(udev->descriptor.idVendor);
+       pid = le16_to_cpu(udev->descriptor.idProduct);
+       bcd = le16_to_cpu(udev->descriptor.bcdDevice);
+
+       for (p = ignore_ids; p->vid; ++p) {
+               if (p->vid == vid && p->pid == pid &&
+                               p->bcdmin <= bcd && p->bcdmax >= bcd)
+                       return -ENXIO;
+       }
+       return 0;
+}
+EXPORT_SYMBOL_GPL(usb_usual_ignore_device);
index be76084c8d7e6a8f8429e389c9a5149e01d1db6d..60ba631e99c22c07568e23daa6340d0563598f1e 100644 (file)
@@ -410,7 +410,9 @@ static int skel_probe(struct usb_interface *interface, const struct usb_device_i
        }
 
        /* let the user know what node this device is now attached to */
-       info("USB Skeleton device now attached to USBSkel-%d", interface->minor);
+       dev_info(&interface->dev,
+                "USB Skeleton device now attached to USBSkel-%d",
+                interface->minor);
        return 0;
 
 error:
@@ -441,7 +443,7 @@ static void skel_disconnect(struct usb_interface *interface)
        /* decrement our usage count */
        kref_put(&dev->kref, skel_delete);
 
-       info("USB Skeleton #%d now disconnected", minor);
+       dev_info(&interface->dev, "USB Skeleton #%d now disconnected", minor);
 }
 
 static void skel_draw_down(struct usb_skel *dev)
index 1335cbe1191db8c7e9f84df77ef72bdf46c3065c..25eae405f62252bd9cffef3c4dba28ab100ad1de 100644 (file)
@@ -638,8 +638,7 @@ static void cbaf_disconnect(struct usb_interface *iface)
        usb_put_intf(iface);
        kfree(cbaf->buffer);
        /* paranoia: clean up crypto keys */
-       memset(cbaf, 0, sizeof(*cbaf));
-       kfree(cbaf);
+       kzfree(cbaf);
 }
 
 static struct usb_device_id cbaf_id_table[] = {
index 8e18141bb2e08d550351f3f8b1b0b91b6f2409db..f0aac0cf315a5cdabcadfa2831a52377ff030b14 100644 (file)
@@ -889,6 +889,8 @@ static void wusb_dev_add_ncb(struct usb_device *usb_dev)
        if (usb_dev->wusb == 0 || usb_dev->devnum == 1)
                return;         /* skip non wusb and wusb RHs */
 
+       usb_set_device_state(usb_dev, USB_STATE_UNAUTHENTICATED);
+
        wusbhc = wusbhc_get_by_usb_dev(usb_dev);
        if (wusbhc == NULL)
                goto error_nodev;
index f4aa28eca70d445af8c7fb9493b120c6d0f670d0..8118db7f1d8ddd230b8f5e6c2dcc116d2eb64d89 100644 (file)
@@ -312,6 +312,7 @@ int wusb_dev_update_address(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev)
        result = wusb_set_dev_addr(wusbhc, wusb_dev, 0);
        if (result < 0)
                goto error_addr0;
+       usb_set_device_state(usb_dev, USB_STATE_DEFAULT);
        usb_ep0_reinit(usb_dev);
 
        /* Set new (authenticated) address. */
@@ -327,6 +328,7 @@ int wusb_dev_update_address(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev)
        result = wusb_set_dev_addr(wusbhc, wusb_dev, new_address);
        if (result < 0)
                goto error_addr;
+       usb_set_device_state(usb_dev, USB_STATE_ADDRESS);
        usb_ep0_reinit(usb_dev);
        usb_dev->authenticated = 1;
 error_addr:
index 88079fd602350bf8fed46f9c12f8b73063a1a2aa..c6b2ab41b9080a748ce23e6b2e210ae40428e609 100644 (file)
@@ -643,186 +643,6 @@ static inline int usb_make_path(struct usb_device *dev, char *buf, size_t size)
 
 /*-------------------------------------------------------------------------*/
 
-/**
- * usb_endpoint_num - get the endpoint's number
- * @epd: endpoint to be checked
- *
- * Returns @epd's number: 0 to 15.
- */
-static inline int usb_endpoint_num(const struct usb_endpoint_descriptor *epd)
-{
-       return epd->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
-}
-
-/**
- * usb_endpoint_type - get the endpoint's transfer type
- * @epd: endpoint to be checked
- *
- * Returns one of USB_ENDPOINT_XFER_{CONTROL, ISOC, BULK, INT} according
- * to @epd's transfer type.
- */
-static inline int usb_endpoint_type(const struct usb_endpoint_descriptor *epd)
-{
-       return epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
-}
-
-/**
- * usb_endpoint_dir_in - check if the endpoint has IN direction
- * @epd: endpoint to be checked
- *
- * Returns true if the endpoint is of type IN, otherwise it returns false.
- */
-static inline int usb_endpoint_dir_in(const struct usb_endpoint_descriptor *epd)
-{
-       return ((epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN);
-}
-
-/**
- * usb_endpoint_dir_out - check if the endpoint has OUT direction
- * @epd: endpoint to be checked
- *
- * Returns true if the endpoint is of type OUT, otherwise it returns false.
- */
-static inline int usb_endpoint_dir_out(
-                               const struct usb_endpoint_descriptor *epd)
-{
-       return ((epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT);
-}
-
-/**
- * usb_endpoint_xfer_bulk - check if the endpoint has bulk transfer type
- * @epd: endpoint to be checked
- *
- * Returns true if the endpoint is of type bulk, otherwise it returns false.
- */
-static inline int usb_endpoint_xfer_bulk(
-                               const struct usb_endpoint_descriptor *epd)
-{
-       return ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
-               USB_ENDPOINT_XFER_BULK);
-}
-
-/**
- * usb_endpoint_xfer_control - check if the endpoint has control transfer type
- * @epd: endpoint to be checked
- *
- * Returns true if the endpoint is of type control, otherwise it returns false.
- */
-static inline int usb_endpoint_xfer_control(
-                               const struct usb_endpoint_descriptor *epd)
-{
-       return ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
-               USB_ENDPOINT_XFER_CONTROL);
-}
-
-/**
- * usb_endpoint_xfer_int - check if the endpoint has interrupt transfer type
- * @epd: endpoint to be checked
- *
- * Returns true if the endpoint is of type interrupt, otherwise it returns
- * false.
- */
-static inline int usb_endpoint_xfer_int(
-                               const struct usb_endpoint_descriptor *epd)
-{
-       return ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
-               USB_ENDPOINT_XFER_INT);
-}
-
-/**
- * usb_endpoint_xfer_isoc - check if the endpoint has isochronous transfer type
- * @epd: endpoint to be checked
- *
- * Returns true if the endpoint is of type isochronous, otherwise it returns
- * false.
- */
-static inline int usb_endpoint_xfer_isoc(
-                               const struct usb_endpoint_descriptor *epd)
-{
-       return ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
-               USB_ENDPOINT_XFER_ISOC);
-}
-
-/**
- * usb_endpoint_is_bulk_in - check if the endpoint is bulk IN
- * @epd: endpoint to be checked
- *
- * Returns true if the endpoint has bulk transfer type and IN direction,
- * otherwise it returns false.
- */
-static inline int usb_endpoint_is_bulk_in(
-                               const struct usb_endpoint_descriptor *epd)
-{
-       return (usb_endpoint_xfer_bulk(epd) && usb_endpoint_dir_in(epd));
-}
-
-/**
- * usb_endpoint_is_bulk_out - check if the endpoint is bulk OUT
- * @epd: endpoint to be checked
- *
- * Returns true if the endpoint has bulk transfer type and OUT direction,
- * otherwise it returns false.
- */
-static inline int usb_endpoint_is_bulk_out(
-                               const struct usb_endpoint_descriptor *epd)
-{
-       return (usb_endpoint_xfer_bulk(epd) && usb_endpoint_dir_out(epd));
-}
-
-/**
- * usb_endpoint_is_int_in - check if the endpoint is interrupt IN
- * @epd: endpoint to be checked
- *
- * Returns true if the endpoint has interrupt transfer type and IN direction,
- * otherwise it returns false.
- */
-static inline int usb_endpoint_is_int_in(
-                               const struct usb_endpoint_descriptor *epd)
-{
-       return (usb_endpoint_xfer_int(epd) && usb_endpoint_dir_in(epd));
-}
-
-/**
- * usb_endpoint_is_int_out - check if the endpoint is interrupt OUT
- * @epd: endpoint to be checked
- *
- * Returns true if the endpoint has interrupt transfer type and OUT direction,
- * otherwise it returns false.
- */
-static inline int usb_endpoint_is_int_out(
-                               const struct usb_endpoint_descriptor *epd)
-{
-       return (usb_endpoint_xfer_int(epd) && usb_endpoint_dir_out(epd));
-}
-
-/**
- * usb_endpoint_is_isoc_in - check if the endpoint is isochronous IN
- * @epd: endpoint to be checked
- *
- * Returns true if the endpoint has isochronous transfer type and IN direction,
- * otherwise it returns false.
- */
-static inline int usb_endpoint_is_isoc_in(
-                               const struct usb_endpoint_descriptor *epd)
-{
-       return (usb_endpoint_xfer_isoc(epd) && usb_endpoint_dir_in(epd));
-}
-
-/**
- * usb_endpoint_is_isoc_out - check if the endpoint is isochronous OUT
- * @epd: endpoint to be checked
- *
- * Returns true if the endpoint has isochronous transfer type and OUT direction,
- * otherwise it returns false.
- */
-static inline int usb_endpoint_is_isoc_out(
-                               const struct usb_endpoint_descriptor *epd)
-{
-       return (usb_endpoint_xfer_isoc(epd) && usb_endpoint_dir_out(epd));
-}
-
-/*-------------------------------------------------------------------------*/
-
 #define USB_DEVICE_ID_MATCH_DEVICE \
                (USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_PRODUCT)
 #define USB_DEVICE_ID_MATCH_DEV_RANGE \
@@ -1357,8 +1177,8 @@ struct urb {
        unsigned int transfer_flags;    /* (in) URB_SHORT_NOT_OK | ...*/
        void *transfer_buffer;          /* (in) associated data buffer */
        dma_addr_t transfer_dma;        /* (in) dma addr for transfer_buffer */
-       int transfer_buffer_length;     /* (in) data buffer length */
-       int actual_length;              /* (return) actual transfer length */
+       u32 transfer_buffer_length;     /* (in) data buffer length */
+       u32 actual_length;              /* (return) actual transfer length */
        unsigned char *setup_packet;    /* (in) setup packet (control only) */
        dma_addr_t setup_dma;           /* (in) dma addr for setup_packet */
        int start_frame;                /* (modify) start frame (ISO) */
index 9b42baed39009c75c8e3932a8c9be3cfbb0984f0..b145119a90da509b493c3b8d62dfd4e9bb53231e 100644 (file)
 #define USB_REQ_LOOPBACK_DATA_READ     0x16
 #define USB_REQ_SET_INTERFACE_DS       0x17
 
-/* The Link Power Mangement (LPM) ECN defines USB_REQ_TEST_AND_SET command,
+/* The Link Power Management (LPM) ECN defines USB_REQ_TEST_AND_SET command,
  * used by hubs to put ports into a new L1 suspend state, except that it
  * forgot to define its number ...
  */
@@ -353,6 +353,185 @@ struct usb_endpoint_descriptor {
 #define USB_ENDPOINT_XFER_INT          3
 #define USB_ENDPOINT_MAX_ADJUSTABLE    0x80
 
+/*-------------------------------------------------------------------------*/
+
+/**
+ * usb_endpoint_num - get the endpoint's number
+ * @epd: endpoint to be checked
+ *
+ * Returns @epd's number: 0 to 15.
+ */
+static inline int usb_endpoint_num(const struct usb_endpoint_descriptor *epd)
+{
+       return epd->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
+}
+
+/**
+ * usb_endpoint_type - get the endpoint's transfer type
+ * @epd: endpoint to be checked
+ *
+ * Returns one of USB_ENDPOINT_XFER_{CONTROL, ISOC, BULK, INT} according
+ * to @epd's transfer type.
+ */
+static inline int usb_endpoint_type(const struct usb_endpoint_descriptor *epd)
+{
+       return epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
+}
+
+/**
+ * usb_endpoint_dir_in - check if the endpoint has IN direction
+ * @epd: endpoint to be checked
+ *
+ * Returns true if the endpoint is of type IN, otherwise it returns false.
+ */
+static inline int usb_endpoint_dir_in(const struct usb_endpoint_descriptor *epd)
+{
+       return ((epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN);
+}
+
+/**
+ * usb_endpoint_dir_out - check if the endpoint has OUT direction
+ * @epd: endpoint to be checked
+ *
+ * Returns true if the endpoint is of type OUT, otherwise it returns false.
+ */
+static inline int usb_endpoint_dir_out(
+                               const struct usb_endpoint_descriptor *epd)
+{
+       return ((epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT);
+}
+
+/**
+ * usb_endpoint_xfer_bulk - check if the endpoint has bulk transfer type
+ * @epd: endpoint to be checked
+ *
+ * Returns true if the endpoint is of type bulk, otherwise it returns false.
+ */
+static inline int usb_endpoint_xfer_bulk(
+                               const struct usb_endpoint_descriptor *epd)
+{
+       return ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
+               USB_ENDPOINT_XFER_BULK);
+}
+
+/**
+ * usb_endpoint_xfer_control - check if the endpoint has control transfer type
+ * @epd: endpoint to be checked
+ *
+ * Returns true if the endpoint is of type control, otherwise it returns false.
+ */
+static inline int usb_endpoint_xfer_control(
+                               const struct usb_endpoint_descriptor *epd)
+{
+       return ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
+               USB_ENDPOINT_XFER_CONTROL);
+}
+
+/**
+ * usb_endpoint_xfer_int - check if the endpoint has interrupt transfer type
+ * @epd: endpoint to be checked
+ *
+ * Returns true if the endpoint is of type interrupt, otherwise it returns
+ * false.
+ */
+static inline int usb_endpoint_xfer_int(
+                               const struct usb_endpoint_descriptor *epd)
+{
+       return ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
+               USB_ENDPOINT_XFER_INT);
+}
+
+/**
+ * usb_endpoint_xfer_isoc - check if the endpoint has isochronous transfer type
+ * @epd: endpoint to be checked
+ *
+ * Returns true if the endpoint is of type isochronous, otherwise it returns
+ * false.
+ */
+static inline int usb_endpoint_xfer_isoc(
+                               const struct usb_endpoint_descriptor *epd)
+{
+       return ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
+               USB_ENDPOINT_XFER_ISOC);
+}
+
+/**
+ * usb_endpoint_is_bulk_in - check if the endpoint is bulk IN
+ * @epd: endpoint to be checked
+ *
+ * Returns true if the endpoint has bulk transfer type and IN direction,
+ * otherwise it returns false.
+ */
+static inline int usb_endpoint_is_bulk_in(
+                               const struct usb_endpoint_descriptor *epd)
+{
+       return (usb_endpoint_xfer_bulk(epd) && usb_endpoint_dir_in(epd));
+}
+
+/**
+ * usb_endpoint_is_bulk_out - check if the endpoint is bulk OUT
+ * @epd: endpoint to be checked
+ *
+ * Returns true if the endpoint has bulk transfer type and OUT direction,
+ * otherwise it returns false.
+ */
+static inline int usb_endpoint_is_bulk_out(
+                               const struct usb_endpoint_descriptor *epd)
+{
+       return (usb_endpoint_xfer_bulk(epd) && usb_endpoint_dir_out(epd));
+}
+
+/**
+ * usb_endpoint_is_int_in - check if the endpoint is interrupt IN
+ * @epd: endpoint to be checked
+ *
+ * Returns true if the endpoint has interrupt transfer type and IN direction,
+ * otherwise it returns false.
+ */
+static inline int usb_endpoint_is_int_in(
+                               const struct usb_endpoint_descriptor *epd)
+{
+       return (usb_endpoint_xfer_int(epd) && usb_endpoint_dir_in(epd));
+}
+
+/**
+ * usb_endpoint_is_int_out - check if the endpoint is interrupt OUT
+ * @epd: endpoint to be checked
+ *
+ * Returns true if the endpoint has interrupt transfer type and OUT direction,
+ * otherwise it returns false.
+ */
+static inline int usb_endpoint_is_int_out(
+                               const struct usb_endpoint_descriptor *epd)
+{
+       return (usb_endpoint_xfer_int(epd) && usb_endpoint_dir_out(epd));
+}
+
+/**
+ * usb_endpoint_is_isoc_in - check if the endpoint is isochronous IN
+ * @epd: endpoint to be checked
+ *
+ * Returns true if the endpoint has isochronous transfer type and IN direction,
+ * otherwise it returns false.
+ */
+static inline int usb_endpoint_is_isoc_in(
+                               const struct usb_endpoint_descriptor *epd)
+{
+       return (usb_endpoint_xfer_isoc(epd) && usb_endpoint_dir_in(epd));
+}
+
+/**
+ * usb_endpoint_is_isoc_out - check if the endpoint is isochronous OUT
+ * @epd: endpoint to be checked
+ *
+ * Returns true if the endpoint has isochronous transfer type and OUT direction,
+ * otherwise it returns false.
+ */
+static inline int usb_endpoint_is_isoc_out(
+                               const struct usb_endpoint_descriptor *epd)
+{
+       return (usb_endpoint_xfer_isoc(epd) && usb_endpoint_dir_out(epd));
+}
 
 /*-------------------------------------------------------------------------*/
 
@@ -584,8 +763,8 @@ enum usb_device_state {
        /* chapter 9 and authentication (wireless) device states */
        USB_STATE_ATTACHED,
        USB_STATE_POWERED,                      /* wired */
-       USB_STATE_UNAUTHENTICATED,              /* auth */
        USB_STATE_RECONNECTING,                 /* auth */
+       USB_STATE_UNAUTHENTICATED,              /* auth */
        USB_STATE_DEFAULT,                      /* limited function */
        USB_STATE_ADDRESS,
        USB_STATE_CONFIGURED,                   /* most functions */
index 935c380ffe47ed82f2a8be443df52d686d551e0c..acd7b0f06c8aa3941ddd5746ac9dbc1ebc701782 100644 (file)
@@ -244,6 +244,10 @@ int usb_add_config(struct usb_composite_dev *,
  *     value; it should return zero on successful initialization.
  * @unbind: Reverses @bind(); called as a side effect of unregistering
  *     this driver.
+ * @suspend: Notifies when the host stops sending USB traffic,
+ *     after function notifications
+ * @resume: Notifies configuration when the host restarts USB traffic,
+ *     before function notifications
  *
  * Devices default to reporting self powered operation.  Devices which rely
  * on bus powered operation should report this in their @bind() method.
@@ -268,6 +272,10 @@ struct usb_composite_driver {
 
        int                     (*bind)(struct usb_composite_dev *);
        int                     (*unbind)(struct usb_composite_dev *);
+
+       /* global suspend hooks */
+       void                    (*suspend)(struct usb_composite_dev *);
+       void                    (*resume)(struct usb_composite_dev *);
 };
 
 extern int usb_composite_register(struct usb_composite_driver *);
index 0460a746480ccf338e4f1a714099968e86e52b49..bbf45d500b6dd547535bd2c6523ac84a0438e110 100644 (file)
@@ -598,6 +598,7 @@ static inline int usb_gadget_clear_selfpowered(struct usb_gadget *gadget)
 /**
  * usb_gadget_vbus_connect - Notify controller that VBUS is powered
  * @gadget:The device which now has VBUS power.
+ * Context: can sleep
  *
  * This call is used by a driver for an external transceiver (or GPIO)
  * that detects a VBUS power session starting.  Common responses include
@@ -636,6 +637,7 @@ static inline int usb_gadget_vbus_draw(struct usb_gadget *gadget, unsigned mA)
 /**
  * usb_gadget_vbus_disconnect - notify controller about VBUS session end
  * @gadget:the device whose VBUS supply is being described
+ * Context: can sleep
  *
  * This call is used by a driver for an external transceiver (or GPIO)
  * that detects a VBUS power session ending.  Common responses include
@@ -792,19 +794,20 @@ struct usb_gadget_driver {
 /**
  * usb_gadget_register_driver - register a gadget driver
  * @driver:the driver being registered
+ * Context: can sleep
  *
  * 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 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);
 
 /**
  * usb_gadget_unregister_driver - unregister a gadget driver
  * @driver:the driver being unregistered
+ * Context: can sleep
  *
  * Call this in your gadget driver's module cleanup function,
  * to tell the underlying usb controller that your driver is
@@ -813,7 +816,6 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver);
  * to unbind() and clean up any device state, before this procedure
  * 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);
 
index 94df4fe6c6c0feb1b6a559a8719a8b7195a5d551..1aaa826396a1462555925b871f22f95ff8870299 100644 (file)
@@ -80,12 +80,17 @@ struct otg_transceiver {
 
 /* for board-specific init logic */
 extern int otg_set_transceiver(struct otg_transceiver *);
+#ifdef CONFIG_NOP_USB_XCEIV
+extern void usb_nop_xceiv_register(void);
+extern void usb_nop_xceiv_unregister(void);
+#endif
 
 
 /* for usb host and peripheral controller drivers */
 extern struct otg_transceiver *otg_get_transceiver(void);
 extern void otg_put_transceiver(struct otg_transceiver *);
 
+/* Context: can sleep */
 static inline int
 otg_start_hnp(struct otg_transceiver *otg)
 {
@@ -102,6 +107,8 @@ otg_set_host(struct otg_transceiver *otg, struct usb_bus *host)
 
 
 /* for usb peripheral controller drivers */
+
+/* Context: can sleep */
 static inline int
 otg_set_peripheral(struct otg_transceiver *otg, struct usb_gadget *periph)
 {
@@ -114,6 +121,7 @@ otg_set_power(struct otg_transceiver *otg, unsigned mA)
        return otg->set_power(otg, mA);
 }
 
+/* Context: can sleep */
 static inline int
 otg_set_suspend(struct otg_transceiver *otg, int suspend)
 {
index 7f6c603db654d077f4cd8ee8351c97e8f9957815..2526f3bbd273e522e1ff77b2ba404c87d9a5a56a 100644 (file)
@@ -16,4 +16,7 @@
 /* device can't handle Set-Interface requests */
 #define USB_QUIRK_NO_SET_INTF          0x00000004
 
+/* device can't handle its Configuration or Interface strings */
+#define USB_QUIRK_CONFIG_INTF_STRINGS  0x00000008
+
 #endif /* __LINUX_USB_QUIRKS_H */
index 0b8617a9176d3de30ed506cffca9a8aa544d59b0..b95842542590df07a4618af175cef8cdf6a6aa0d 100644 (file)
@@ -130,7 +130,8 @@ struct usb_serial {
        struct usb_device               *dev;
        struct usb_serial_driver        *type;
        struct usb_interface            *interface;
-       unsigned char                   disconnected;
+       unsigned char                   disconnected:1;
+       unsigned char                   suspending:1;
        unsigned char                   minor;
        unsigned char                   num_ports;
        unsigned char                   num_port_pointers;
index 1eea1ab68dc4849a37ccf3ca5a83d86f3e01690a..3d15fb9bc116fbba8f03612b9af2fae6b34ba8bf 100644 (file)
@@ -96,39 +96,26 @@ enum { US_DO_ALL_FLAGS };
 #define US_PR_CBI      0x00            /* Control/Bulk/Interrupt */
 #define US_PR_CB       0x01            /* Control/Bulk w/o interrupt */
 #define US_PR_BULK     0x50            /* bulk only */
-#ifdef CONFIG_USB_STORAGE_USBAT
+
 #define US_PR_USBAT    0x80            /* SCM-ATAPI bridge */
-#endif
-#ifdef CONFIG_USB_STORAGE_SDDR09
 #define US_PR_EUSB_SDDR09      0x81    /* SCM-SCSI bridge for SDDR-09 */
-#endif
-#ifdef CONFIG_USB_STORAGE_SDDR55
 #define US_PR_SDDR55   0x82            /* SDDR-55 (made up) */
-#endif
 #define US_PR_DPCM_USB  0xf0           /* Combination CB/SDDR09 */
-#ifdef CONFIG_USB_STORAGE_FREECOM
 #define US_PR_FREECOM   0xf1           /* Freecom */
-#endif
-#ifdef CONFIG_USB_STORAGE_DATAFAB
 #define US_PR_DATAFAB   0xf2           /* Datafab chipsets */
-#endif
-#ifdef CONFIG_USB_STORAGE_JUMPSHOT
 #define US_PR_JUMPSHOT  0xf3           /* Lexar Jumpshot */
-#endif
-#ifdef CONFIG_USB_STORAGE_ALAUDA
 #define US_PR_ALAUDA    0xf4           /* Alauda chipsets */
-#endif
-#ifdef CONFIG_USB_STORAGE_KARMA
 #define US_PR_KARMA     0xf5           /* Rio Karma */
-#endif
 
 #define US_PR_DEVICE   0xff            /* Use device's value */
 
 /*
  */
+extern int usb_usual_ignore_device(struct usb_interface *intf);
+extern struct usb_device_id usb_storage_usb_ids[];
+
 #ifdef CONFIG_USB_LIBUSUAL
 
-extern struct usb_device_id storage_usb_ids[];
 extern void usb_usual_set_present(int type);
 extern void usb_usual_clear_present(int type);
 extern int usb_usual_check_type(const struct usb_device_id *, int type);