fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / drivers / usb / gadget / file_storage.c
index 9b97891..72f2ae9 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * file_storage.c -- File-backed USB Storage Gadget, for USB development
  *
- * Copyright (C) 2003, 2004 Alan Stern
+ * Copyright (C) 2003-2005 Alan Stern
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  *
  * Backing storage is provided by a regular file or a block device, specified
  * by the "file" module parameter.  Access can be limited to read-only by
- * setting the optional "ro" module parameter.
+ * setting the optional "ro" module parameter.  The gadget will indicate that
+ * it has removable media if the optional "removable" module parameter is set.
  *
  * The gadget supports the Control-Bulk (CB), Control-Bulk-Interrupt (CBI),
  * and Bulk-Only (also known as Bulk-Bulk-Bulk or BBB) transports, selected
  * by the optional "transport" module parameter.  It also supports the
  * following protocols: RBC (0x01), ATAPI or SFF-8020i (0x02), QIC-157 (0c03),
  * UFI (0x04), SFF-8070i (0x05), and transparent SCSI (0x06), selected by
- * the optional "protocol" module parameter.  For testing purposes the
- * gadget will indicate that it has removable media if the optional
- * "removable" module parameter is set.  In addition, the default Vendor ID,
- * Product ID, and release number can be overridden.
+ * the optional "protocol" module parameter.  In addition, the default
+ * Vendor ID, Product ID, and release number can be overridden.
  *
  * There is support for multiple logical units (LUNs), each of which has
  * its own backing file.  The number of LUNs can be set using the optional
  * requirement amounts to two 16K buffers, size configurable by a parameter.
  * Support is included for both full-speed and high-speed operation.
  *
+ * Note that the driver is slightly non-portable in that it assumes a
+ * single memory/DMA buffer will be useable for bulk-in, bulk-out, and
+ * interrupt-in endpoints.  With most device controllers this isn't an
+ * issue, but there may be some with hardware restrictions that prevent
+ * a buffer from being used by more than one endpoint.
+ *
  * Module options:
  *
  *     file=filename[,filename...]
  *                                     the files or block devices used for
  *                                     backing storage
  *     ro=b[,b...]             Default false, booleans for read-only access
+ *     removable               Default false, boolean for removable media
  *     luns=N                  Default N = number of filenames, number of
  *                                     LUNs to support
+ *     stall                   Default determined according to the type of
+ *                                     USB device controller (usually true),
+ *                                     boolean to permit the driver to halt
+ *                                     bulk endpoints
  *     transport=XXX           Default BBB, transport name (CB, CBI, or BBB)
  *     protocol=YYY            Default SCSI, protocol name (RBC, 8020 or
  *                                     ATAPI, QIC, UFI, 8070, or SCSI;
  *                                     also 1 - 6)
- *     removable               Default false, boolean for removable media
  *     vendor=0xVVVV           Default 0x0525 (NetChip), USB Vendor ID
  *     product=0xPPPP          Default 0xa4a5 (FSG), USB Product ID
  *     release=0xRRRR          Override the USB release number (bcdDevice)
  *     buflen=N                Default N=16384, buffer size used (will be
  *                                     rounded down to a multiple of
  *                                     PAGE_CACHE_SIZE)
- *     stall                   Default determined according to the type of
- *                                     USB device controller (usually true),
- *                                     boolean to permit the driver to halt
- *                                     bulk endpoints
  *
- * If CONFIG_USB_FILE_STORAGE_TEST is not set, only the "file" and "ro"
- * options are available; default values are used for everything else.
+ * If CONFIG_USB_FILE_STORAGE_TEST is not set, only the "file", "ro",
+ * "removable", "luns", and "stall" options are available; default values
+ * are used for everything else.
  *
  * The pathnames of the backing files and the ro settings are available in
  * the attribute files "file" and "ro" in the lun<n> subdirectory of the
- * gadget's sysfs directory.  If CONFIG_USB_FILE_STORAGE_TEST and the
- * "removable" option are both set, writing to these files will simulate
- * ejecting/loading the medium (writing an empty line means eject) and
- * adjusting a write-enable tab.  Changes to the ro setting are not allowed
- * when the medium is loaded.
+ * gadget's sysfs directory.  If the "removable" option is set, writing to
+ * these files will simulate ejecting/loading the medium (writing an empty
+ * line means eject) and adjusting a write-enable tab.  Changes to the ro
+ * setting are not allowed when the medium is loaded.
  *
  * This gadget driver is heavily based on "Gadget Zero" by David Brownell.
+ * The driver's SCSI command interface was based on the "Information
+ * technology - Small Computer System Interface - 2" document from
+ * X3T9.2 Project 375D, Revision 10L, 7-SEP-93, available at
+ * <http://www.t10.org/ftp/t10/drafts/s2/s2-r10l.pdf>.  The single exception
+ * is opcode 0x23 (READ FORMAT CAPACITIES), which was based on the
+ * "Universal Serial Bus Mass Storage Class UFI Command Specification"
+ * document, Revision 1.0, December 14, 1998, available at
+ * <http://www.usb.org/developers/devclass_docs/usbmass-ufi10.pdf>.
  */
 
 
  * Bulk-only specification requires a stall.  In such cases the driver
  * will halt the endpoint and set a flag indicating that it should clear
  * the halt in software during the next device reset.  Hopefully this
- * will permit everything to work correctly.
+ * will permit everything to work correctly.  Furthermore, although the
+ * specification allows the bulk-out endpoint to halt when the host sends
+ * too much data, implementing this would cause an unavoidable race.
+ * The driver will always use the "no-stall" approach for OUT transfers.
  *
  * One subtle point concerns sending status-stage responses for ep0
  * requests.  Some of these requests, such as device reset, can involve
 #undef VERBOSE
 #undef DUMP_MSGS
 
-#include <linux/config.h>
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
 #include <linux/compiler.h>
 #include <linux/completion.h>
 #include <linux/dcache.h>
+#include <linux/delay.h>
 #include <linux/device.h>
 #include <linux/fcntl.h>
 #include <linux/file.h>
 #include <linux/fs.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
+#include <linux/kref.h>
+#include <linux/kthread.h>
 #include <linux/limits.h>
 #include <linux/list.h>
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/string.h>
-#include <linux/uts.h>
-#include <linux/version.h>
-#include <linux/wait.h>
+#include <linux/freezer.h>
+#include <linux/utsname.h>
 
 #include <linux/usb_ch9.h>
 #include <linux/usb_gadget.h>
 
 #define DRIVER_DESC            "File-backed Storage Gadget"
 #define DRIVER_NAME            "g_file_storage"
-#define DRIVER_VERSION         "21 March 2004"
+#define DRIVER_VERSION         "28 November 2005"
 
 static const char longname[] = DRIVER_DESC;
 static const char shortname[] = DRIVER_NAME;
@@ -330,23 +347,22 @@ MODULE_LICENSE("Dual BSD/GPL");
 
 #define MAX_LUNS       8
 
-       /* Arggh!  There should be a module_param_array_named macro! */
-static char            *file[MAX_LUNS] = {NULL, };
-static int             ro[MAX_LUNS] = {0, };
-
 static struct {
+       char            *file[MAX_LUNS];
+       int             ro[MAX_LUNS];
        int             num_filenames;
        int             num_ros;
        unsigned int    nluns;
 
+       int             removable;
+       int             can_stall;
+
        char            *transport_parm;
        char            *protocol_parm;
-       int             removable;
        unsigned short  vendor;
        unsigned short  product;
        unsigned short  release;
        unsigned int    buflen;
-       int             can_stall;
 
        int             transport_type;
        char            *transport_name;
@@ -357,28 +373,35 @@ static struct {
        .transport_parm         = "BBB",
        .protocol_parm          = "SCSI",
        .removable              = 0,
+       .can_stall              = 1,
        .vendor                 = DRIVER_VENDOR_ID,
        .product                = DRIVER_PRODUCT_ID,
        .release                = 0xffff,       // Use controller chip type
        .buflen                 = 16384,
-       .can_stall              = 1,
        };
 
 
-module_param_array(file, charp, mod_data.num_filenames, S_IRUGO);
+module_param_array_named(file, mod_data.file, charp, &mod_data.num_filenames,
+               S_IRUGO);
 MODULE_PARM_DESC(file, "names of backing files or devices");
 
-module_param_array(ro, bool, mod_data.num_ros, S_IRUGO);
+module_param_array_named(ro, mod_data.ro, bool, &mod_data.num_ros, S_IRUGO);
 MODULE_PARM_DESC(ro, "true to force read-only");
 
+module_param_named(luns, mod_data.nluns, uint, S_IRUGO);
+MODULE_PARM_DESC(luns, "number of LUNs");
 
-/* In the non-TEST version, only the file and ro module parameters
+module_param_named(removable, mod_data.removable, bool, S_IRUGO);
+MODULE_PARM_DESC(removable, "true to simulate removable media");
+
+module_param_named(stall, mod_data.can_stall, bool, S_IRUGO);
+MODULE_PARM_DESC(stall, "false to prevent bulk stalls");
+
+
+/* In the non-TEST version, only the module parameters listed above
  * are available. */
 #ifdef CONFIG_USB_FILE_STORAGE_TEST
 
-module_param_named(luns, mod_data.nluns, uint, S_IRUGO);
-MODULE_PARM_DESC(luns, "number of LUNs");
-
 module_param_named(transport, mod_data.transport_parm, charp, S_IRUGO);
 MODULE_PARM_DESC(transport, "type of transport (BBB, CBI, or CB)");
 
@@ -386,9 +409,6 @@ module_param_named(protocol, mod_data.protocol_parm, charp, S_IRUGO);
 MODULE_PARM_DESC(protocol, "type of protocol (RBC, 8020, QIC, UFI, "
                "8070, or SCSI)");
 
-module_param_named(removable, mod_data.removable, bool, S_IRUGO);
-MODULE_PARM_DESC(removable, "true to simulate removable media");
-
 module_param_named(vendor, mod_data.vendor, ushort, S_IRUGO);
 MODULE_PARM_DESC(vendor, "USB Vendor ID");
 
@@ -401,9 +421,6 @@ MODULE_PARM_DESC(release, "USB release number");
 module_param_named(buflen, mod_data.buflen, uint, S_IRUGO);
 MODULE_PARM_DESC(buflen, "I/O buffer size");
 
-module_param_named(stall, mod_data.can_stall, bool, S_IRUGO);
-MODULE_PARM_DESC(stall, "false to prevent bulk stalls");
-
 #endif /* CONFIG_USB_FILE_STORAGE_TEST */
 
 
@@ -426,9 +443,9 @@ MODULE_PARM_DESC(stall, "false to prevent bulk stalls");
 
 /* Command Block Wrapper */
 struct bulk_cb_wrap {
-       u32     Signature;              // Contains 'USBC'
+       __le32  Signature;              // Contains 'USBC'
        u32     Tag;                    // Unique per command id
-       u32     DataTransferLength;     // Size of the data
+       __le32  DataTransferLength;     // Size of the data
        u8      Flags;                  // Direction in bit 7
        u8      Lun;                    // LUN (normally 0)
        u8      Length;                 // Of the CDB, <= MAX_COMMAND_SIZE
@@ -441,9 +458,9 @@ struct bulk_cb_wrap {
 
 /* Command Status Wrapper */
 struct bulk_cs_wrap {
-       u32     Signature;              // Should = 'USBS'
+       __le32  Signature;              // Should = 'USBS'
        u32     Tag;                    // Same as original command
-       u32     Residue;                // Amount not transferred
+       __le32  Residue;                // Amount not transferred
        u8      Status;                 // See below
 };
 
@@ -525,11 +542,6 @@ struct interrupt_data {
  * parts of the driver that aren't used in the non-TEST version.  Even gcc
  * can recognize when a test of a constant expression yields a dead code
  * path.
- *
- * Also, in the non-TEST version, open_backing_file() is only used during
- * initialization and the sysfs attribute store_xxx routines aren't used
- * at all.  We will define NORMALLY_INIT to mark them as __init so they
- * don't occupy kernel code space unnecessarily.
  */
 
 #ifdef CONFIG_USB_FILE_STORAGE_TEST
@@ -537,16 +549,12 @@ struct interrupt_data {
 #define transport_is_bbb()     (mod_data.transport_type == USB_PR_BULK)
 #define transport_is_cbi()     (mod_data.transport_type == USB_PR_CBI)
 #define protocol_is_scsi()     (mod_data.protocol_type == USB_SC_SCSI)
-#define backing_file_is_open(curlun)   ((curlun)->filp != NULL)
-#define NORMALLY_INIT
 
 #else
 
 #define transport_is_bbb()     1
 #define transport_is_cbi()     0
 #define protocol_is_scsi()     1
-#define backing_file_is_open(curlun)   1
-#define NORMALLY_INIT          __init
 
 #endif /* CONFIG_USB_FILE_STORAGE_TEST */
 
@@ -559,6 +567,7 @@ struct lun {
        unsigned int    ro : 1;
        unsigned int    prevent_medium_removal : 1;
        unsigned int    registered : 1;
+       unsigned int    info_valid : 1;
 
        u32             sense_data;
        u32             sense_data_info;
@@ -567,6 +576,8 @@ struct lun {
        struct device   dev;
 };
 
+#define backing_file_is_open(curlun)   ((curlun)->filp != NULL)
+
 static inline struct lun *dev_to_lun(struct device *dev)
 {
        return container_of(dev, struct lun, dev);
@@ -589,7 +600,7 @@ enum fsg_buffer_state {
 struct fsg_buffhd {
        void                            *buf;
        dma_addr_t                      dma;
-       volatile enum fsg_buffer_state  state;
+       enum fsg_buffer_state           state;
        struct fsg_buffhd               *next;
 
        /* The NetChip 2280 is faster, and handles some protocol faults
@@ -598,9 +609,9 @@ struct fsg_buffhd {
        unsigned int                    bulk_out_intended_length;
 
        struct usb_request              *inreq;
-       volatile int                    inreq_busy;
+       int                             inreq_busy;
        struct usb_request              *outreq;
-       volatile int                    outreq_busy;
+       int                             outreq_busy;
 };
 
 enum fsg_state {
@@ -633,13 +644,16 @@ struct fsg_dev {
        /* filesem protects: backing files in use */
        struct rw_semaphore     filesem;
 
+       /* reference counting: wait until all LUNs are released */
+       struct kref             ref;
+
        struct usb_ep           *ep0;           // Handy copy of gadget->ep0
        struct usb_request      *ep0req;        // For control responses
-       volatile unsigned int   ep0_req_tag;
+       unsigned int            ep0_req_tag;
        const char              *ep0req_name;
 
        struct usb_request      *intreq;        // For interrupt responses
-       volatile int            intreq_busy;
+       int                     intreq_busy;
        struct fsg_buffhd       *intr_buffhd;
 
        unsigned int            bulk_out_maxpacket;
@@ -659,6 +673,7 @@ struct fsg_dev {
        unsigned long           atomic_bitflags;
 #define REGISTERED             0
 #define CLEAR_BULK_HALTS       1
+#define SUSPENDED              2
 
        struct usb_ep           *bulk_in;
        struct usb_ep           *bulk_out;
@@ -668,10 +683,8 @@ struct fsg_dev {
        struct fsg_buffhd       *next_buffhd_to_drain;
        struct fsg_buffhd       buffhds[NUM_BUFFERS];
 
-       wait_queue_head_t       thread_wqh;
        int                     thread_wakeup_needed;
        struct completion       thread_notifier;
-       int                     thread_pid;
        struct task_struct      *thread_task;
        sigset_t                thread_signal_mask;
 
@@ -696,7 +709,6 @@ struct fsg_dev {
        unsigned int            nluns;
        struct lun              *luns;
        struct lun              *curlun;
-       struct completion       lun_released;
 };
 
 typedef void (*fsg_routine_t)(struct fsg_dev *);
@@ -821,7 +833,7 @@ static void inline put_be32(u8 *buf, u32 val)
        buf[0] = val >> 24;
        buf[1] = val >> 16;
        buf[2] = val >> 8;
-       buf[3] = val;
+       buf[3] = val & 0xff;
 }
 
 
@@ -835,6 +847,8 @@ static void inline put_be32(u8 *buf, u32 val)
 #define STRING_MANUFACTURER    1
 #define STRING_PRODUCT         2
 #define STRING_SERIAL          3
+#define STRING_CONFIG          4
+#define STRING_INTERFACE       5
 
 /* There is only one configuration. */
 #define        CONFIG_VALUE            1
@@ -866,10 +880,19 @@ config_desc = {
        /* wTotalLength computed by usb_gadget_config_buf() */
        .bNumInterfaces =       1,
        .bConfigurationValue =  CONFIG_VALUE,
+       .iConfiguration =       STRING_CONFIG,
        .bmAttributes =         USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
        .bMaxPower =            1,      // self-powered
 };
 
+static struct usb_otg_descriptor
+otg_desc = {
+       .bLength =              sizeof(otg_desc),
+       .bDescriptorType =      USB_DT_OTG,
+
+       .bmAttributes =         USB_OTG_SRP,
+};
+
 /* There is only one interface. */
 
 static struct usb_interface_descriptor
@@ -881,6 +904,7 @@ intf_desc = {
        .bInterfaceClass =      USB_CLASS_MASS_STORAGE,
        .bInterfaceSubClass =   USB_SC_SCSI,    // Adjusted during fsg_bind()
        .bInterfaceProtocol =   USB_PR_BULK,    // Adjusted during fsg_bind()
+       .iInterface =           STRING_INTERFACE,
 };
 
 /* Three full-speed endpoint descriptors: bulk-in, bulk-out,
@@ -918,12 +942,14 @@ fs_intr_in_desc = {
 };
 
 static const struct usb_descriptor_header *fs_function[] = {
+       (struct usb_descriptor_header *) &otg_desc,
        (struct usb_descriptor_header *) &intf_desc,
        (struct usb_descriptor_header *) &fs_bulk_in_desc,
        (struct usb_descriptor_header *) &fs_bulk_out_desc,
        (struct usb_descriptor_header *) &fs_intr_in_desc,
        NULL,
 };
+#define FS_FUNCTION_PRE_EP_ENTRIES     2
 
 
 #ifdef CONFIG_USB_GADGET_DUALSPEED
@@ -980,12 +1006,14 @@ hs_intr_in_desc = {
 };
 
 static const struct usb_descriptor_header *hs_function[] = {
+       (struct usb_descriptor_header *) &otg_desc,
        (struct usb_descriptor_header *) &intf_desc,
        (struct usb_descriptor_header *) &hs_bulk_in_desc,
        (struct usb_descriptor_header *) &hs_bulk_out_desc,
        (struct usb_descriptor_header *) &hs_intr_in_desc,
        NULL,
 };
+#define HS_FUNCTION_PRE_EP_ENTRIES     2
 
 /* Maxpacket and other transfer characteristics vary by speed. */
 #define ep_desc(g,fs,hs)       (((g)->speed==USB_SPEED_HIGH) ? (hs) : (fs))
@@ -1000,7 +1028,7 @@ static const struct usb_descriptor_header *hs_function[] = {
 
 /* The CBI specification limits the serial string to 12 uppercase hexadecimal
  * characters. */
-static char                            manufacturer[40];
+static char                            manufacturer[64];
 static char                            serial[13];
 
 /* Static strings, in UTF-8 (for simplicity we use only ASCII characters) */
@@ -1008,6 +1036,8 @@ static struct usb_string          strings[] = {
        {STRING_MANUFACTURER,   manufacturer},
        {STRING_PRODUCT,        longname},
        {STRING_SERIAL,         serial},
+       {STRING_CONFIG,         "Self-powered"},
+       {STRING_INTERFACE,      "Mass Storage"},
        {}
 };
 
@@ -1022,9 +1052,12 @@ static struct usb_gadget_strings stringtab = {
  * and with code managing interfaces and their altsettings.  They must
  * also handle different speeds and other-speed requests.
  */
-static int populate_config_buf(enum usb_device_speed speed,
+static int populate_config_buf(struct usb_gadget *gadget,
                u8 *buf, u8 type, unsigned index)
 {
+#ifdef CONFIG_USB_GADGET_DUALSPEED
+       enum usb_device_speed                   speed = gadget->speed;
+#endif
        int                                     len;
        const struct usb_descriptor_header      **function;
 
@@ -1040,9 +1073,11 @@ static int populate_config_buf(enum usb_device_speed speed,
 #endif
                function = fs_function;
 
+       /* for now, don't advertise srp-only devices */
+       if (!gadget->is_otg)
+               function++;
+
        len = usb_gadget_config_buf(&config_desc, buf, EP0_BUFSIZE, function);
-       if (len < 0)
-               return len;
        ((struct usb_config_descriptor *) buf)->bDescriptorType = type;
        return len;
 }
@@ -1052,18 +1087,19 @@ static int populate_config_buf(enum usb_device_speed speed,
 
 /* These routines may be called in process context or in_irq */
 
+/* Caller must hold fsg->lock */
 static void wakeup_thread(struct fsg_dev *fsg)
 {
        /* Tell the main thread that something has happened */
        fsg->thread_wakeup_needed = 1;
-       wake_up_all(&fsg->thread_wqh);
+       if (fsg->thread_task)
+               wake_up_process(fsg->thread_task);
 }
 
 
 static void raise_exception(struct fsg_dev *fsg, enum fsg_state new_state)
 {
        unsigned long           flags;
-       struct task_struct      *thread_task;
 
        /* Do nothing if a higher-priority exception is already in progress.
         * If a lower-or-equal priority exception is in progress, preempt it
@@ -1072,9 +1108,9 @@ static void raise_exception(struct fsg_dev *fsg, enum fsg_state new_state)
        if (fsg->state <= new_state) {
                fsg->exception_req_tag = fsg->ep0_req_tag;
                fsg->state = new_state;
-               thread_task = fsg->thread_task;
-               if (thread_task)
-                       send_sig_info(SIGUSR1, SEND_SIG_FORCED, thread_task);
+               if (fsg->thread_task)
+                       send_sig_info(SIGUSR1, SEND_SIG_FORCED,
+                                       fsg->thread_task);
        }
        spin_unlock_irqrestore(&fsg->lock, flags);
 }
@@ -1144,11 +1180,12 @@ static void bulk_in_complete(struct usb_ep *ep, struct usb_request *req)
                usb_ep_fifo_flush(ep);
 
        /* Hold the lock while we update the request and buffer states */
+       smp_wmb();
        spin_lock(&fsg->lock);
        bh->inreq_busy = 0;
        bh->state = BUF_STATE_EMPTY;
-       spin_unlock(&fsg->lock);
        wakeup_thread(fsg);
+       spin_unlock(&fsg->lock);
 }
 
 static void bulk_out_complete(struct usb_ep *ep, struct usb_request *req)
@@ -1165,16 +1202,18 @@ static void bulk_out_complete(struct usb_ep *ep, struct usb_request *req)
                usb_ep_fifo_flush(ep);
 
        /* Hold the lock while we update the request and buffer states */
+       smp_wmb();
        spin_lock(&fsg->lock);
        bh->outreq_busy = 0;
        bh->state = BUF_STATE_FULL;
-       spin_unlock(&fsg->lock);
        wakeup_thread(fsg);
+       spin_unlock(&fsg->lock);
 }
 
+
+#ifdef CONFIG_USB_FILE_STORAGE_TEST
 static void intr_in_complete(struct usb_ep *ep, struct usb_request *req)
 {
-#ifdef CONFIG_USB_FILE_STORAGE_TEST
        struct fsg_dev          *fsg = (struct fsg_dev *) ep->driver_data;
        struct fsg_buffhd       *bh = (struct fsg_buffhd *) req->context;
 
@@ -1185,22 +1224,27 @@ static void intr_in_complete(struct usb_ep *ep, struct usb_request *req)
                usb_ep_fifo_flush(ep);
 
        /* Hold the lock while we update the request and buffer states */
+       smp_wmb();
        spin_lock(&fsg->lock);
        fsg->intreq_busy = 0;
        bh->state = BUF_STATE_EMPTY;
-       spin_unlock(&fsg->lock);
        wakeup_thread(fsg);
-#endif /* CONFIG_USB_FILE_STORAGE_TEST */
+       spin_unlock(&fsg->lock);
 }
 
+#else
+static void intr_in_complete(struct usb_ep *ep, struct usb_request *req)
+{}
+#endif /* CONFIG_USB_FILE_STORAGE_TEST */
+
 
 /*-------------------------------------------------------------------------*/
 
 /* Ep0 class-specific handlers.  These always run in_irq. */
 
+#ifdef CONFIG_USB_FILE_STORAGE_TEST
 static void received_cbi_adsc(struct fsg_dev *fsg, struct fsg_buffhd *bh)
 {
-#ifdef CONFIG_USB_FILE_STORAGE_TEST
        struct usb_request      *req = fsg->ep0req;
        static u8               cbi_reset_cmnd[6] = {
                        SC_SEND_DIAGNOSTIC, 4, 0xff, 0xff, 0xff, 0xff};
@@ -1236,17 +1280,23 @@ static void received_cbi_adsc(struct fsg_dev *fsg, struct fsg_buffhd *bh)
        fsg->cbbuf_cmnd_size = req->actual;
        memcpy(fsg->cbbuf_cmnd, req->buf, fsg->cbbuf_cmnd_size);
 
-       spin_unlock(&fsg->lock);
        wakeup_thread(fsg);
-#endif /* CONFIG_USB_FILE_STORAGE_TEST */
+       spin_unlock(&fsg->lock);
 }
 
+#else
+static void received_cbi_adsc(struct fsg_dev *fsg, struct fsg_buffhd *bh)
+{}
+#endif /* CONFIG_USB_FILE_STORAGE_TEST */
+
 
 static int class_setup_req(struct fsg_dev *fsg,
                const struct usb_ctrlrequest *ctrl)
 {
        struct usb_request      *req = fsg->ep0req;
        int                     value = -EOPNOTSUPP;
+       u16                     w_index = le16_to_cpu(ctrl->wIndex);
+       u16                     w_length = le16_to_cpu(ctrl->wLength);
 
        if (!fsg->config)
                return value;
@@ -1259,7 +1309,7 @@ static int class_setup_req(struct fsg_dev *fsg,
                        if (ctrl->bRequestType != (USB_DIR_OUT |
                                        USB_TYPE_CLASS | USB_RECIP_INTERFACE))
                                break;
-                       if (ctrl->wIndex != 0) {
+                       if (w_index != 0) {
                                value = -EDOM;
                                break;
                        }
@@ -1275,13 +1325,13 @@ static int class_setup_req(struct fsg_dev *fsg,
                        if (ctrl->bRequestType != (USB_DIR_IN |
                                        USB_TYPE_CLASS | USB_RECIP_INTERFACE))
                                break;
-                       if (ctrl->wIndex != 0) {
+                       if (w_index != 0) {
                                value = -EDOM;
                                break;
                        }
                        VDBG(fsg, "get max LUN\n");
                        *(u8 *) req->buf = fsg->nluns - 1;
-                       value = min(ctrl->wLength, (u16) 1);
+                       value = 1;
                        break;
                }
        }
@@ -1294,15 +1344,15 @@ static int class_setup_req(struct fsg_dev *fsg,
                        if (ctrl->bRequestType != (USB_DIR_OUT |
                                        USB_TYPE_CLASS | USB_RECIP_INTERFACE))
                                break;
-                       if (ctrl->wIndex != 0) {
+                       if (w_index != 0) {
                                value = -EDOM;
                                break;
                        }
-                       if (ctrl->wLength > MAX_COMMAND_SIZE) {
+                       if (w_length > MAX_COMMAND_SIZE) {
                                value = -EOVERFLOW;
                                break;
                        }
-                       value = ctrl->wLength;
+                       value = w_length;
                        fsg->ep0req->context = received_cbi_adsc;
                        break;
                }
@@ -1313,7 +1363,7 @@ static int class_setup_req(struct fsg_dev *fsg,
                        "unknown class-specific control req "
                        "%02x.%02x v%04x i%04x l%u\n",
                        ctrl->bRequestType, ctrl->bRequest,
-                       ctrl->wValue, ctrl->wIndex, ctrl->wLength);
+                       le16_to_cpu(ctrl->wValue), w_index, w_length);
        return value;
 }
 
@@ -1327,6 +1377,8 @@ static int standard_setup_req(struct fsg_dev *fsg,
 {
        struct usb_request      *req = fsg->ep0req;
        int                     value = -EOPNOTSUPP;
+       u16                     w_index = le16_to_cpu(ctrl->wIndex);
+       u16                     w_value = le16_to_cpu(ctrl->wValue);
 
        /* Usually this just stores reply data in the pre-allocated ep0 buffer,
         * but config change events will also reconfigure hardware. */
@@ -1336,11 +1388,11 @@ static int standard_setup_req(struct fsg_dev *fsg,
                if (ctrl->bRequestType != (USB_DIR_IN | USB_TYPE_STANDARD |
                                USB_RECIP_DEVICE))
                        break;
-               switch (ctrl->wValue >> 8) {
+               switch (w_value >> 8) {
 
                case USB_DT_DEVICE:
                        VDBG(fsg, "get device descriptor\n");
-                       value = min(ctrl->wLength, (u16) sizeof device_desc);
+                       value = sizeof device_desc;
                        memcpy(req->buf, &device_desc, value);
                        break;
 #ifdef CONFIG_USB_GADGET_DUALSPEED
@@ -1348,7 +1400,7 @@ static int standard_setup_req(struct fsg_dev *fsg,
                        VDBG(fsg, "get device qualifier\n");
                        if (!fsg->gadget->is_dualspeed)
                                break;
-                       value = min(ctrl->wLength, (u16) sizeof dev_qualifier);
+                       value = sizeof dev_qualifier;
                        memcpy(req->buf, &dev_qualifier, value);
                        break;
 
@@ -1363,12 +1415,10 @@ static int standard_setup_req(struct fsg_dev *fsg,
 #ifdef CONFIG_USB_GADGET_DUALSPEED
                get_config:
 #endif
-                       value = populate_config_buf(fsg->gadget->speed,
+                       value = populate_config_buf(fsg->gadget,
                                        req->buf,
-                                       ctrl->wValue >> 8,
-                                       ctrl->wValue & 0xff);
-                       if (value >= 0)
-                               value = min(ctrl->wLength, (u16) value);
+                                       w_value >> 8,
+                                       w_value & 0xff);
                        break;
 
                case USB_DT_STRING:
@@ -1376,9 +1426,7 @@ static int standard_setup_req(struct fsg_dev *fsg,
 
                        /* wIndex == language code */
                        value = usb_gadget_get_string(&stringtab,
-                                       ctrl->wValue & 0xff, req->buf);
-                       if (value >= 0)
-                               value = min(ctrl->wLength, (u16) value);
+                                       w_value & 0xff, req->buf);
                        break;
                }
                break;
@@ -1389,8 +1437,8 @@ static int standard_setup_req(struct fsg_dev *fsg,
                                USB_RECIP_DEVICE))
                        break;
                VDBG(fsg, "set configuration\n");
-               if (ctrl->wValue == CONFIG_VALUE || ctrl->wValue == 0) {
-                       fsg->new_config = ctrl->wValue;
+               if (w_value == CONFIG_VALUE || w_value == 0) {
+                       fsg->new_config = w_value;
 
                        /* Raise an exception to wipe out previous transaction
                         * state (queued bufs, etc) and set the new config. */
@@ -1404,14 +1452,14 @@ static int standard_setup_req(struct fsg_dev *fsg,
                        break;
                VDBG(fsg, "get configuration\n");
                *(u8 *) req->buf = fsg->config;
-               value = min(ctrl->wLength, (u16) 1);
+               value = 1;
                break;
 
        case USB_REQ_SET_INTERFACE:
                if (ctrl->bRequestType != (USB_DIR_OUT| USB_TYPE_STANDARD |
                                USB_RECIP_INTERFACE))
                        break;
-               if (fsg->config && ctrl->wIndex == 0) {
+               if (fsg->config && w_index == 0) {
 
                        /* Raise an exception to wipe out previous transaction
                         * state (queued bufs, etc) and install the new
@@ -1426,20 +1474,20 @@ static int standard_setup_req(struct fsg_dev *fsg,
                        break;
                if (!fsg->config)
                        break;
-               if (ctrl->wIndex != 0) {
+               if (w_index != 0) {
                        value = -EDOM;
                        break;
                }
                VDBG(fsg, "get interface\n");
                *(u8 *) req->buf = 0;
-               value = min(ctrl->wLength, (u16) 1);
+               value = 1;
                break;
 
        default:
                VDBG(fsg,
                        "unknown control req %02x.%02x v%04x i%04x l%u\n",
                        ctrl->bRequestType, ctrl->bRequest,
-                       ctrl->wValue, ctrl->wIndex, ctrl->wLength);
+                       w_value, w_index, le16_to_cpu(ctrl->wLength));
        }
 
        return value;
@@ -1451,6 +1499,7 @@ static int fsg_setup(struct usb_gadget *gadget,
 {
        struct fsg_dev          *fsg = get_gadget_data(gadget);
        int                     rc;
+       int                     w_length = le16_to_cpu(ctrl->wLength);
 
        ++fsg->ep0_req_tag;             // Record arrival of a new request
        fsg->ep0req->context = NULL;
@@ -1464,9 +1513,9 @@ static int fsg_setup(struct usb_gadget *gadget,
 
        /* Respond with data/status or defer until later? */
        if (rc >= 0 && rc != DELAYED_STATUS) {
+               rc = min(rc, w_length);
                fsg->ep0req->length = rc;
-               fsg->ep0req->zero = rc < ctrl->wLength
-                               && (rc % gadget->ep0->maxpacket) == 0;
+               fsg->ep0req->zero = rc < w_length;
                fsg->ep0req_name = (ctrl->bRequestType & USB_DIR_IN ?
                                "ep0-in" : "ep0-out");
                rc = ep0_queue(fsg);
@@ -1484,8 +1533,8 @@ static int fsg_setup(struct usb_gadget *gadget,
 
 /* Use this for bulk or interrupt transfers, not ep0 */
 static void start_transfer(struct fsg_dev *fsg, struct usb_ep *ep,
-               struct usb_request *req, volatile int *pbusy,
-               volatile enum fsg_buffer_state *state)
+               struct usb_request *req, int *pbusy,
+               enum fsg_buffer_state *state)
 {
        int     rc;
 
@@ -1493,8 +1542,11 @@ static void start_transfer(struct fsg_dev *fsg, struct usb_ep *ep,
                dump_msg(fsg, "bulk-in", req->buf, req->length);
        else if (ep == fsg->intr_in)
                dump_msg(fsg, "intr-in", req->buf, req->length);
+
+       spin_lock_irq(&fsg->lock);
        *pbusy = 1;
        *state = BUF_STATE_BUSY;
+       spin_unlock_irq(&fsg->lock);
        rc = usb_ep_queue(ep, req, GFP_KERNEL);
        if (rc != 0) {
                *pbusy = 0;
@@ -1514,13 +1566,23 @@ static void start_transfer(struct fsg_dev *fsg, struct usb_ep *ep,
 
 static int sleep_thread(struct fsg_dev *fsg)
 {
-       int     rc;
+       int     rc = 0;
 
        /* Wait until a signal arrives or we are woken up */
-       rc = wait_event_interruptible(fsg->thread_wqh,
-                       fsg->thread_wakeup_needed);
+       for (;;) {
+               try_to_freeze();
+               set_current_state(TASK_INTERRUPTIBLE);
+               if (signal_pending(current)) {
+                       rc = -EINTR;
+                       break;
+               }
+               if (fsg->thread_wakeup_needed)
+                       break;
+               schedule();
+       }
+       __set_current_state(TASK_RUNNING);
        fsg->thread_wakeup_needed = 0;
-       return (rc ? -EINTR : 0);
+       return rc;
 }
 
 
@@ -1595,6 +1657,7 @@ static int do_read(struct fsg_dev *fsg)
                        curlun->sense_data =
                                        SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
                        curlun->sense_data_info = file_offset >> 9;
+                       curlun->info_valid = 1;
                        bh->inreq->length = 0;
                        bh->state = BUF_STATE_FULL;
                        break;
@@ -1630,6 +1693,7 @@ static int do_read(struct fsg_dev *fsg)
                if (nread < amount) {
                        curlun->sense_data = SS_UNRECOVERED_READ_ERROR;
                        curlun->sense_data_info = file_offset >> 9;
+                       curlun->info_valid = 1;
                        break;
                }
 
@@ -1724,6 +1788,7 @@ static int do_write(struct fsg_dev *fsg)
                                curlun->sense_data =
                                        SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
                                curlun->sense_data_info = usb_offset >> 9;
+                               curlun->info_valid = 1;
                                continue;
                        }
                        amount -= (amount & 511);
@@ -1746,6 +1811,7 @@ static int do_write(struct fsg_dev *fsg)
                         * the bulk-out maxpacket size */
                        bh->outreq->length = bh->bulk_out_intended_length =
                                        amount;
+                       bh->outreq->short_not_ok = 1;
                        start_transfer(fsg, fsg->bulk_out, bh->outreq,
                                        &bh->outreq_busy, &bh->state);
                        fsg->next_buffhd_to_fill = bh->next;
@@ -1757,6 +1823,7 @@ static int do_write(struct fsg_dev *fsg)
                if (bh->state == BUF_STATE_EMPTY && !get_some_more)
                        break;                  // We stopped early
                if (bh->state == BUF_STATE_FULL) {
+                       smp_rmb();
                        fsg->next_buffhd_to_drain = bh->next;
                        bh->state = BUF_STATE_EMPTY;
 
@@ -1764,6 +1831,7 @@ static int do_write(struct fsg_dev *fsg)
                        if (bh->outreq->status != 0) {
                                curlun->sense_data = SS_COMMUNICATION_FAILURE;
                                curlun->sense_data_info = file_offset >> 9;
+                               curlun->info_valid = 1;
                                break;
                        }
 
@@ -1805,6 +1873,7 @@ static int do_write(struct fsg_dev *fsg)
                        if (nwritten < amount) {
                                curlun->sense_data = SS_WRITE_ERROR;
                                curlun->sense_data_info = file_offset >> 9;
+                               curlun->info_valid = 1;
                                break;
                        }
 
@@ -1840,18 +1909,16 @@ static int fsync_sub(struct lun *curlun)
        if (!filp->f_op->fsync)
                return -EINVAL;
 
-       inode = filp->f_dentry->d_inode;
-       down(&inode->i_sem);
-       current->flags |= PF_SYNCWRITE;
+       inode = filp->f_path.dentry->d_inode;
+       mutex_lock(&inode->i_mutex);
        rc = filemap_fdatawrite(inode->i_mapping);
-       err = filp->f_op->fsync(filp, filp->f_dentry, 1);
+       err = filp->f_op->fsync(filp, filp->f_path.dentry, 1);
        if (!rc)
                rc = err;
        err = filemap_fdatawait(inode->i_mapping);
        if (!rc)
                rc = err;
-       current->flags &= ~PF_SYNCWRITE;
-       up(&inode->i_sem);
+       mutex_unlock(&inode->i_mutex);
        VLDBG(curlun, "fdatasync -> %d\n", rc);
        return rc;
 }
@@ -1883,7 +1950,7 @@ static int do_synchronize_cache(struct fsg_dev *fsg)
 static void invalidate_sub(struct lun *curlun)
 {
        struct file     *filp = curlun->filp;
-       struct inode    *inode = filp->f_dentry->d_inode;
+       struct inode    *inode = filp->f_path.dentry->d_inode;
        unsigned long   rc;
 
        rc = invalidate_inode_pages(inode->i_mapping);
@@ -1949,6 +2016,7 @@ static int do_verify(struct fsg_dev *fsg)
                        curlun->sense_data =
                                        SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
                        curlun->sense_data_info = file_offset >> 9;
+                       curlun->info_valid = 1;
                        break;
                }
 
@@ -1975,6 +2043,7 @@ static int do_verify(struct fsg_dev *fsg)
                if (nread == 0) {
                        curlun->sense_data = SS_UNRECOVERED_READ_ERROR;
                        curlun->sense_data_info = file_offset >> 9;
+                       curlun->info_valid = 1;
                        break;
                }
                file_offset += nread;
@@ -2018,6 +2087,7 @@ static int do_request_sense(struct fsg_dev *fsg, struct fsg_buffhd *bh)
        struct lun      *curlun = fsg->curlun;
        u8              *buf = (u8 *) bh->buf;
        u32             sd, sdinfo;
+       int             valid;
 
        /*
         * From the SCSI-2 spec., section 7.9 (Unit attention condition):
@@ -2045,15 +2115,18 @@ static int do_request_sense(struct fsg_dev *fsg, struct fsg_buffhd *bh)
                fsg->bad_lun_okay = 1;
                sd = SS_LOGICAL_UNIT_NOT_SUPPORTED;
                sdinfo = 0;
+               valid = 0;
        } else {
                sd = curlun->sense_data;
                sdinfo = curlun->sense_data_info;
+               valid = curlun->info_valid << 7;
                curlun->sense_data = SS_NO_SENSE;
                curlun->sense_data_info = 0;
+               curlun->info_valid = 0;
        }
 
        memset(buf, 0, 18);
-       buf[0] = 0x80 | 0x70;                   // Valid, current error
+       buf[0] = valid | 0x70;                  // Valid, current error
        buf[2] = SK(sd);
        put_be32(&buf[3], sdinfo);              // Sense information
        buf[7] = 18 - 8;                        // Additional sense length
@@ -2277,8 +2350,7 @@ static int halt_bulk_in_endpoint(struct fsg_dev *fsg)
                }
 
                /* Wait for a short time and then try again */
-               set_current_state(TASK_INTERRUPTIBLE);
-               if (schedule_timeout(HZ / 10) != 0)
+               if (msleep_interruptible(100) != 0)
                        return -EINTR;
                rc = usb_ep_set_halt(fsg->bulk_in);
        }
@@ -2326,6 +2398,7 @@ static int throw_away_data(struct fsg_dev *fsg)
 
                /* Throw away the data in a filled buffer */
                if (bh->state == BUF_STATE_FULL) {
+                       smp_rmb();
                        bh->state = BUF_STATE_EMPTY;
                        fsg->next_buffhd_to_drain = bh->next;
 
@@ -2348,6 +2421,7 @@ static int throw_away_data(struct fsg_dev *fsg)
                         * the bulk-out maxpacket size */
                        bh->outreq->length = bh->bulk_out_intended_length =
                                        amount;
+                       bh->outreq->short_not_ok = 1;
                        start_transfer(fsg, fsg->bulk_out, bh->outreq,
                                        &bh->outreq_busy, &bh->state);
                        fsg->next_buffhd_to_fill = bh->next;
@@ -2443,14 +2517,19 @@ static int finish_reply(struct fsg_dev *fsg)
                        rc = -EINTR;
                }
 
-               /* We haven't processed all the incoming data.  If we are
-                * allowed to stall, halt the bulk-out endpoint and cancel
-                * any outstanding requests. */
+               /* We haven't processed all the incoming data.  Even though
+                * we may be allowed to stall, doing so would cause a race.
+                * The controller may already have ACK'ed all the remaining
+                * bulk-out packets, in which case the host wouldn't see a
+                * STALL.  Not realizing the endpoint was halted, it wouldn't
+                * clear the halt -- leading to problems later on. */
+#if 0
                else if (mod_data.can_stall) {
                        fsg_set_halt(fsg, fsg->bulk_out);
                        raise_exception(fsg, FSG_STATE_ABORT_BULK_OUT);
                        rc = -EINTR;
                }
+#endif
 
                /* We can't stall.  Read in the excess data and throw it
                 * all away. */
@@ -2513,7 +2592,7 @@ static int send_status(struct fsg_dev *fsg)
 
        } else if (mod_data.transport_type == USB_PR_CB) {
 
-               /* Control-Bulk transport has no status stage! */
+               /* Control-Bulk transport has no status phase! */
                return 0;
 
        } else {                        // USB_PR_CBI
@@ -2603,8 +2682,10 @@ static int check_command(struct fsg_dev *fsg, int cmnd_size,
        fsg->residue = fsg->usb_amount_left = fsg->data_size;
 
        /* Conflicting data directions is a phase error */
-       if (fsg->data_dir != data_dir && fsg->data_size_from_cmnd > 0)
-               goto phase_error;
+       if (fsg->data_dir != data_dir && fsg->data_size_from_cmnd > 0) {
+               fsg->phase_error = 1;
+               return -EINVAL;
+       }
 
        /* Verify the length of the command itself */
        if (cmnd_size != fsg->cmnd_size) {
@@ -2613,11 +2694,13 @@ static int check_command(struct fsg_dev *fsg, int cmnd_size,
                 * with cbw->Length == 12 (it should be 6). */
                if (fsg->cmnd[0] == SC_REQUEST_SENSE && fsg->cmnd_size == 12)
                        cmnd_size = fsg->cmnd_size;
-               else
-                       goto phase_error;
+               else {
+                       fsg->phase_error = 1;
+                       return -EINVAL;
+               }
        }
 
-       /* Check that the LUN values are oonsistent */
+       /* Check that the LUN values are consistent */
        if (transport_is_bbb()) {
                if (fsg->lun != lun)
                        DBG(fsg, "using LUN %d from CBW, "
@@ -2632,6 +2715,7 @@ static int check_command(struct fsg_dev *fsg, int cmnd_size,
                if (fsg->cmnd[0] != SC_REQUEST_SENSE) {
                        curlun->sense_data = SS_NO_SENSE;
                        curlun->sense_data_info = 0;
+                       curlun->info_valid = 0;
                }
        } else {
                fsg->curlun = curlun = NULL;
@@ -2674,10 +2758,6 @@ static int check_command(struct fsg_dev *fsg, int cmnd_size,
        }
 
        return 0;
-
-phase_error:
-       fsg->phase_error = 1;
-       return -EINVAL;
 }
 
 
@@ -2974,6 +3054,7 @@ static int get_next_command(struct fsg_dev *fsg)
 
                /* Queue a request to read a Bulk-only CBW */
                set_bulk_out_req_length(fsg, bh, USB_BULK_CB_WRAP_LEN);
+               bh->outreq->short_not_ok = 1;
                start_transfer(fsg, fsg->bulk_out, bh->outreq,
                                &bh->outreq_busy, &bh->state);
 
@@ -2986,6 +3067,7 @@ static int get_next_command(struct fsg_dev *fsg)
                        if ((rc = sleep_thread(fsg)) != 0)
                                return rc;
                        }
+               smp_rmb();
                rc = received_cbw(fsg, bh);
                bh->state = BUF_STATE_EMPTY;
 
@@ -3102,7 +3184,7 @@ reset:
        if ((rc = enable_endpoint(fsg, fsg->bulk_out, d)) != 0)
                goto reset;
        fsg->bulk_out_enabled = 1;
-       fsg->bulk_out_maxpacket = d->wMaxPacketSize;
+       fsg->bulk_out_maxpacket = le16_to_cpu(d->wMaxPacketSize);
 
        if (transport_is_cbi()) {
                d = ep_desc(fsg->gadget, &fs_intr_in_desc, &hs_intr_in_desc);
@@ -3263,6 +3345,7 @@ static void handle_exception(struct fsg_dev *fsg)
                        curlun->sense_data = curlun->unit_attention_data =
                                        SS_NO_SENSE;
                        curlun->sense_data_info = 0;
+                       curlun->info_valid = 0;
                }
                fsg->state = FSG_STATE_IDLE;
        }
@@ -3347,11 +3430,6 @@ static int fsg_main_thread(void *fsg_)
 {
        struct fsg_dev          *fsg = (struct fsg_dev *) fsg_;
 
-       fsg->thread_task = current;
-
-       /* Release all our userspace resources */
-       daemonize("file-storage-gadget");
-
        /* Allow the thread to be killed by a signal, but set the signal mask
         * to block everything but INT, TERM, KILL, and USR1. */
        siginitsetinv(&fsg->thread_signal_mask, sigmask(SIGINT) |
@@ -3364,9 +3442,6 @@ static int fsg_main_thread(void *fsg_)
         * that expects a __user pointer and it will work okay. */
        set_fs(get_ds());
 
-       /* Wait for the gadget registration to finish up */
-       wait_for_completion(&fsg->thread_notifier);
-
        /* The main loop */
        while (fsg->state != FSG_STATE_TERMINATED) {
                if (exception_in_progress(fsg) || signal_pending(current)) {
@@ -3404,8 +3479,9 @@ static int fsg_main_thread(void *fsg_)
                spin_unlock_irq(&fsg->lock);
                }
 
+       spin_lock_irq(&fsg->lock);
        fsg->thread_task = NULL;
-       flush_signals(current);
+       spin_unlock_irq(&fsg->lock);
 
        /* In case we are exiting because of a signal, unregister the
         * gadget driver and close the backing file. */
@@ -3424,8 +3500,7 @@ static int fsg_main_thread(void *fsg_)
 /* If the next two routines are called while the gadget is registered,
  * the caller must own fsg->filesem for writing. */
 
-static int NORMALLY_INIT open_backing_file(struct lun *curlun,
-               const char *filename)
+static int open_backing_file(struct lun *curlun, const char *filename)
 {
        int                             ro;
        struct file                     *filp = NULL;
@@ -3451,8 +3526,8 @@ static int NORMALLY_INIT open_backing_file(struct lun *curlun,
        if (!(filp->f_mode & FMODE_WRITE))
                ro = 1;
 
-       if (filp->f_dentry)
-               inode = filp->f_dentry->d_inode;
+       if (filp->f_path.dentry)
+               inode = filp->f_path.dentry->d_inode;
        if (inode && S_ISBLK(inode->i_mode)) {
                if (bdev_read_only(inode->i_bdev))
                        ro = 1;
@@ -3515,14 +3590,14 @@ static void close_all_backing_files(struct fsg_dev *fsg)
 }
 
 
-static ssize_t show_ro(struct device *dev, char *buf)
+static ssize_t show_ro(struct device *dev, struct device_attribute *attr, char *buf)
 {
        struct lun      *curlun = dev_to_lun(dev);
 
        return sprintf(buf, "%d\n", curlun->ro);
 }
 
-static ssize_t show_file(struct device *dev, char *buf)
+static ssize_t show_file(struct device *dev, struct device_attribute *attr, char *buf)
 {
        struct lun      *curlun = dev_to_lun(dev);
        struct fsg_dev  *fsg = (struct fsg_dev *) dev_get_drvdata(dev);
@@ -3531,7 +3606,7 @@ static ssize_t show_file(struct device *dev, char *buf)
 
        down_read(&fsg->filesem);
        if (backing_file_is_open(curlun)) {     // Get the complete pathname
-               p = d_path(curlun->filp->f_dentry, curlun->filp->f_vfsmnt,
+               p = d_path(curlun->filp->f_path.dentry, curlun->filp->f_path.mnt,
                                buf, PAGE_SIZE - 1);
                if (IS_ERR(p))
                        rc = PTR_ERR(p);
@@ -3550,8 +3625,7 @@ static ssize_t show_file(struct device *dev, char *buf)
 }
 
 
-ssize_t NORMALLY_INIT store_ro(struct device *dev, const char *buf,
-               size_t count)
+static ssize_t store_ro(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
        ssize_t         rc = count;
        struct lun      *curlun = dev_to_lun(dev);
@@ -3575,8 +3649,7 @@ ssize_t NORMALLY_INIT store_ro(struct device *dev, const char *buf,
        return rc;
 }
 
-ssize_t NORMALLY_INIT store_file(struct device *dev, const char *buf,
-               size_t count)
+static ssize_t store_file(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
        struct lun      *curlun = dev_to_lun(dev);
        struct fsg_dev  *fsg = (struct fsg_dev *) dev_get_drvdata(dev);
@@ -3617,14 +3690,22 @@ static DEVICE_ATTR(file, 0444, show_file, NULL);
 
 /*-------------------------------------------------------------------------*/
 
+static void fsg_release(struct kref *ref)
+{
+       struct fsg_dev  *fsg = container_of(ref, struct fsg_dev, ref);
+
+       kfree(fsg->luns);
+       kfree(fsg);
+}
+
 static void lun_release(struct device *dev)
 {
        struct fsg_dev  *fsg = (struct fsg_dev *) dev_get_drvdata(dev);
 
-       complete(&fsg->lun_released);
+       kref_put(&fsg->ref, fsg_release);
 }
 
-static void fsg_unbind(struct usb_gadget *gadget)
+static void /* __init_or_exit */ fsg_unbind(struct usb_gadget *gadget)
 {
        struct fsg_dev          *fsg = get_gadget_data(gadget);
        int                     i;
@@ -3635,14 +3716,12 @@ static void fsg_unbind(struct usb_gadget *gadget)
        clear_bit(REGISTERED, &fsg->atomic_bitflags);
 
        /* Unregister the sysfs attribute files and the LUNs */
-       init_completion(&fsg->lun_released);
        for (i = 0; i < fsg->nluns; ++i) {
                curlun = &fsg->luns[i];
                if (curlun->registered) {
                        device_remove_file(&curlun->dev, &dev_attr_ro);
                        device_remove_file(&curlun->dev, &dev_attr_file);
                        device_unregister(&curlun->dev);
-                       wait_for_completion(&fsg->lun_released);
                        curlun->registered = 0;
                }
        }
@@ -3680,6 +3759,7 @@ static void fsg_unbind(struct usb_gadget *gadget)
 static int __init check_parameters(struct fsg_dev *fsg)
 {
        int     prot;
+       int     gcnum;
 
        /* Store the default values */
        mod_data.transport_type = USB_PR_BULK;
@@ -3691,27 +3771,17 @@ static int __init check_parameters(struct fsg_dev *fsg)
                mod_data.can_stall = 0;
 
        if (mod_data.release == 0xffff) {       // Parameter wasn't set
-               if (gadget_is_net2280(fsg->gadget))
-                       mod_data.release = __constant_cpu_to_le16(0x0301);
-               else if (gadget_is_dummy(fsg->gadget))
-                       mod_data.release = __constant_cpu_to_le16(0x0302);
-               else if (gadget_is_pxa(fsg->gadget))
-                       mod_data.release = __constant_cpu_to_le16(0x0303);
-               else if (gadget_is_sh(fsg->gadget))
-                       mod_data.release = __constant_cpu_to_le16(0x0304);
-
                /* The sa1100 controller is not supported */
-
-               else if (gadget_is_goku(fsg->gadget))
-                       mod_data.release = __constant_cpu_to_le16(0x0306);
-               else if (gadget_is_mq11xx(fsg->gadget))
-                       mod_data.release = __constant_cpu_to_le16(0x0307);
-               else if (gadget_is_omap(fsg->gadget))
-                       mod_data.release = __constant_cpu_to_le16(0x0308);
+               if (gadget_is_sa1100(fsg->gadget))
+                       gcnum = -1;
+               else
+                       gcnum = usb_gadget_controller_number(fsg->gadget);
+               if (gcnum >= 0)
+                       mod_data.release = 0x0300 + gcnum;
                else {
                        WARN(fsg, "controller '%s' not recognized\n",
                                fsg->gadget->name);
-                       mod_data.release = __constant_cpu_to_le16(0x0399);
+                       mod_data.release = 0x0399;
                }
        }
 
@@ -3805,28 +3875,42 @@ static int __init fsg_bind(struct usb_gadget *gadget)
                goto out;
        }
 
-       /* Create the LUNs and open their backing files.  We can't register
-        * the LUN devices until the gadget itself is registered, which
-        * doesn't happen until after fsg_bind() returns. */
-       fsg->luns = kmalloc(i * sizeof(struct lun), GFP_KERNEL);
+       /* Create the LUNs, open their backing files, and register the
+        * LUN devices in sysfs. */
+       fsg->luns = kzalloc(i * sizeof(struct lun), GFP_KERNEL);
        if (!fsg->luns) {
                rc = -ENOMEM;
                goto out;
        }
-       memset(fsg->luns, 0, i * sizeof(struct lun));
        fsg->nluns = i;
 
        for (i = 0; i < fsg->nluns; ++i) {
                curlun = &fsg->luns[i];
-               curlun->ro = ro[i];
+               curlun->ro = mod_data.ro[i];
+               curlun->dev.release = lun_release;
                curlun->dev.parent = &gadget->dev;
                curlun->dev.driver = &fsg_driver.driver;
                dev_set_drvdata(&curlun->dev, fsg);
                snprintf(curlun->dev.bus_id, BUS_ID_SIZE,
                                "%s-lun%d", gadget->dev.bus_id, i);
 
-               if (file[i] && *file[i]) {
-                       if ((rc = open_backing_file(curlun, file[i])) != 0)
+               if ((rc = device_register(&curlun->dev)) != 0) {
+                       INFO(fsg, "failed to register LUN%d: %d\n", i, rc);
+                       goto out;
+               }
+               if ((rc = device_create_file(&curlun->dev,
+                                       &dev_attr_ro)) != 0 ||
+                               (rc = device_create_file(&curlun->dev,
+                                       &dev_attr_file)) != 0) {
+                       device_unregister(&curlun->dev);
+                       goto out;
+               }
+               curlun->registered = 1;
+               kref_get(&fsg->ref);
+
+               if (mod_data.file[i] && *mod_data.file[i]) {
+                       if ((rc = open_backing_file(curlun,
+                                       mod_data.file[i])) != 0)
                                goto out;
                } else if (!mod_data.removable) {
                        ERROR(fsg, "no file given for LUN%d\n", i);
@@ -3867,10 +3951,10 @@ static int __init fsg_bind(struct usb_gadget *gadget)
        intf_desc.bNumEndpoints = i;
        intf_desc.bInterfaceSubClass = mod_data.protocol_type;
        intf_desc.bInterfaceProtocol = mod_data.transport_type;
-       fs_function[i+1] = NULL;
+       fs_function[i + FS_FUNCTION_PRE_EP_ENTRIES] = NULL;
 
 #ifdef CONFIG_USB_GADGET_DUALSPEED
-       hs_function[i+1] = NULL;
+       hs_function[i + HS_FUNCTION_PRE_EP_ENTRIES] = NULL;
 
        /* Assume ep0 uses the same maxpacket value for both speeds */
        dev_qualifier.bMaxPacketSize0 = fsg->ep0->maxpacket;
@@ -3881,6 +3965,11 @@ static int __init fsg_bind(struct usb_gadget *gadget)
        hs_intr_in_desc.bEndpointAddress = fs_intr_in_desc.bEndpointAddress;
 #endif
 
+       if (gadget->is_otg) {
+               otg_desc.bmAttributes |= USB_OTG_HNP,
+               config_desc.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
+       }
+
        rc = -ENOMEM;
 
        /* Allocate the request and buffer for endpoint 0 */
@@ -3897,6 +3986,9 @@ static int __init fsg_bind(struct usb_gadget *gadget)
        for (i = 0; i < NUM_BUFFERS; ++i) {
                struct fsg_buffhd       *bh = &fsg->buffhds[i];
 
+               /* Allocate for the bulk-in endpoint.  We assume that
+                * the buffer will also work with the bulk-out (and
+                * interrupt-in) endpoint. */
                bh->buf = usb_ep_alloc_buffer(fsg->bulk_in, mod_data.buflen,
                                &bh->dma, GFP_KERNEL);
                if (!bh->buf)
@@ -3908,8 +4000,8 @@ static int __init fsg_bind(struct usb_gadget *gadget)
        /* This should reflect the actual gadget power source */
        usb_gadget_set_selfpowered(gadget);
 
-       snprintf(manufacturer, sizeof manufacturer,
-                       UTS_SYSNAME " " UTS_RELEASE " with %s",
+       snprintf(manufacturer, sizeof manufacturer, "%s %s with %s",
+                       init_utsname()->sysname, init_utsname()->release,
                        gadget->name);
 
        /* On a real device, serial[] would be loaded from permanent
@@ -3922,10 +4014,12 @@ static int __init fsg_bind(struct usb_gadget *gadget)
                sprintf(&serial[i], "%02X", c);
        }
 
-       if ((rc = kernel_thread(fsg_main_thread, fsg, (CLONE_VM | CLONE_FS |
-                       CLONE_FILES))) < 0)
+       fsg->thread_task = kthread_create(fsg_main_thread, fsg,
+                       "file-storage-gadget");
+       if (IS_ERR(fsg->thread_task)) {
+               rc = PTR_ERR(fsg->thread_task);
                goto out;
-       fsg->thread_pid = rc;
+       }
 
        INFO(fsg, DRIVER_DESC ", version: " DRIVER_VERSION "\n");
        INFO(fsg, "Number of LUNs=%d\n", fsg->nluns);
@@ -3936,8 +4030,8 @@ static int __init fsg_bind(struct usb_gadget *gadget)
                if (backing_file_is_open(curlun)) {
                        p = NULL;
                        if (pathbuf) {
-                               p = d_path(curlun->filp->f_dentry,
-                                       curlun->filp->f_vfsmnt,
+                               p = d_path(curlun->filp->f_path.dentry,
+                                       curlun->filp->f_path.mnt,
                                        pathbuf, PATH_MAX);
                                if (IS_ERR(p))
                                        p = NULL;
@@ -3957,7 +4051,12 @@ static int __init fsg_bind(struct usb_gadget *gadget)
        DBG(fsg, "removable=%d, stall=%d, buflen=%u\n",
                        mod_data.removable, mod_data.can_stall,
                        mod_data.buflen);
-       DBG(fsg, "I/O thread pid: %d\n", fsg->thread_pid);
+       DBG(fsg, "I/O thread pid: %d\n", fsg->thread_task->pid);
+
+       set_bit(REGISTERED, &fsg->atomic_bitflags);
+
+       /* Tell the thread to start working */
+       wake_up_process(fsg->thread_task);
        return 0;
 
 autoconf_fail:
@@ -3972,6 +4071,25 @@ out:
 }
 
 
+/*-------------------------------------------------------------------------*/
+
+static void fsg_suspend(struct usb_gadget *gadget)
+{
+       struct fsg_dev          *fsg = get_gadget_data(gadget);
+
+       DBG(fsg, "suspend\n");
+       set_bit(SUSPENDED, &fsg->atomic_bitflags);
+}
+
+static void fsg_resume(struct usb_gadget *gadget)
+{
+       struct fsg_dev          *fsg = get_gadget_data(gadget);
+
+       DBG(fsg, "resume\n");
+       clear_bit(SUSPENDED, &fsg->atomic_bitflags);
+}
+
+
 /*-------------------------------------------------------------------------*/
 
 static struct usb_gadget_driver                fsg_driver = {
@@ -3985,9 +4103,12 @@ static struct usb_gadget_driver          fsg_driver = {
        .unbind         = fsg_unbind,
        .disconnect     = fsg_disconnect,
        .setup          = fsg_setup,
+       .suspend        = fsg_suspend,
+       .resume         = fsg_resume,
 
        .driver         = {
                .name           = (char *) shortname,
+               .owner          = THIS_MODULE,
                // .release = ...
                // .suspend = ...
                // .resume = ...
@@ -3999,13 +4120,12 @@ static int __init fsg_alloc(void)
 {
        struct fsg_dev          *fsg;
 
-       fsg = kmalloc(sizeof *fsg, GFP_KERNEL);
+       fsg = kzalloc(sizeof *fsg, GFP_KERNEL);
        if (!fsg)
                return -ENOMEM;
-       memset(fsg, 0, sizeof *fsg);
        spin_lock_init(&fsg->lock);
        init_rwsem(&fsg->filesem);
-       init_waitqueue_head(&fsg->thread_wqh);
+       kref_init(&fsg->ref);
        init_completion(&fsg->thread_notifier);
 
        the_fsg = fsg;
@@ -4013,45 +4133,17 @@ static int __init fsg_alloc(void)
 }
 
 
-static void fsg_free(struct fsg_dev *fsg)
-{
-       kfree(fsg->luns);
-       kfree(fsg);
-}
-
-
 static int __init fsg_init(void)
 {
        int             rc;
        struct fsg_dev  *fsg;
-       int             i;
-       struct lun      *curlun;
 
        if ((rc = fsg_alloc()) != 0)
                return rc;
        fsg = the_fsg;
-       if ((rc = usb_gadget_register_driver(&fsg_driver)) != 0) {
-               fsg_free(fsg);
-               return rc;
-       }
-       set_bit(REGISTERED, &fsg->atomic_bitflags);
-
-       /* Register the LUN devices and their attribute files */
-       for (i = 0; i < fsg->nluns; ++i) {
-               curlun = &fsg->luns[i];
-               if ((rc = device_register(&curlun->dev)) != 0)
-                       INFO(fsg, "failed to register LUN%d: %d\n", i, rc);
-               else {
-                       curlun->registered = 1;
-                       curlun->dev.release = lun_release;
-                       device_create_file(&curlun->dev, &dev_attr_ro);
-                       device_create_file(&curlun->dev, &dev_attr_file);
-               }
-       }
-
-       /* Tell the thread to start working */
-       complete(&fsg->thread_notifier);
-       return 0;
+       if ((rc = usb_gadget_register_driver(&fsg_driver)) != 0)
+               kref_put(&fsg->ref, fsg_release);
+       return rc;
 }
 module_init(fsg_init);
 
@@ -4068,6 +4160,6 @@ static void __exit fsg_cleanup(void)
        wait_for_completion(&fsg->thread_notifier);
 
        close_all_backing_files(fsg);
-       fsg_free(fsg);
+       kref_put(&fsg->ref, fsg_release);
 }
 module_exit(fsg_cleanup);