Merge branch 'bkl-removal' of git://git.lwn.net/linux-2.6
[safe/jmp/linux-2.6] / drivers / usb / gadget / file_storage.c
index 037a7f1..5c030b0 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * file_storage.c -- File-backed USB Storage Gadget, for USB development
  *
- * Copyright (C) 2003-2005 Alan Stern
+ * Copyright (C) 2003-2008 Alan Stern
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
 
 /*
  * The File-backed Storage Gadget acts as a USB Mass Storage device,
- * appearing to the host as a disk drive.  In addition to providing an
- * example of a genuinely useful gadget driver for a USB device, it also
- * illustrates a technique of double-buffering for increased throughput.
- * Last but not least, it gives an easy way to probe the behavior of the
- * Mass Storage drivers in a USB host.
+ * appearing to the host as a disk drive or as a CD-ROM drive.  In addition
+ * to providing an example of a genuinely useful gadget driver for a USB
+ * device, it also illustrates a technique of double-buffering for increased
+ * throughput.  Last but not least, it gives an easy way to probe the
+ * behavior of the Mass Storage drivers in a USB host.
  *
  * 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.  The gadget will indicate that
- * it has removable media if the optional "removable" module parameter is set.
+ * setting the optional "ro" module parameter.  (For CD-ROM emulation,
+ * access is always read-only.)  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
  * The default number of LUNs is taken from the number of "file" elements;
  * it is 1 if "file" is not given.  If "removable" is not set then a backing
  * file must be specified for each LUN.  If it is set, then an unspecified
- * or empty backing filename means the LUN's medium is not loaded.
+ * or empty backing filename means the LUN's medium is not loaded.  Ideally
+ * each LUN would be settable independently as a disk drive or a CD-ROM
+ * drive, but currently all LUNs have to be the same type.  The CD-ROM
+ * emulation includes a single data track and no audio tracks; hence there
+ * need be only one backing file per LUN.  Note also that the CD-ROM block
+ * length is set to 512 rather than the more common value 2048.
  *
  * Requirements are modest; only a bulk-in and a bulk-out endpoint are
  * needed (an interrupt-out endpoint is also needed for CBI).  The memory
  * 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...]
  *     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
+ *     cdrom                   Default false, boolean for whether to emulate
+ *                                     a CD-ROM drive
  *     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;
  *     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", "ro",
- * "removable", and "luns" options are available; default values are used
- * for everything else.
+ * "removable", "luns", "stall", and "cdrom" 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 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.
+ * setting are not allowed when the medium is loaded or if CD-ROM emulation
+ * is being used.
  *
  * 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>.
  */
 
 
  */
 
 
-#undef DEBUG
-#undef VERBOSE
-#undef DUMP_MSGS
-
-#include <linux/config.h>
+/* #define VERBOSE_DEBUG */
+/* #define DUMP_MSGS */
 
-#include <asm/system.h>
-#include <asm/uaccess.h>
 
-#include <linux/bitops.h>
 #include <linux/blkdev.h>
-#include <linux/compiler.h>
 #include <linux/completion.h>
 #include <linux/dcache.h>
 #include <linux/delay.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/moduleparam.h>
-#include <linux/pagemap.h>
 #include <linux/rwsem.h>
-#include <linux/sched.h>
-#include <linux/signal.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/string.h>
-#include <linux/suspend.h>
+#include <linux/freezer.h>
 #include <linux/utsname.h>
-#include <linux/wait.h>
 
-#include <linux/usb_ch9.h>
-#include <linux/usb_gadget.h>
+#include <linux/usb/ch9.h>
+#include <linux/usb/gadget.h>
 
 #include "gadget_chips.h"
 
 
+
+/*
+ * Kbuild is not very cooperative with respect to linking separately
+ * compiled library objects into one module.  So for now we won't use
+ * separate compilation ... ensuring init/exit sections work to shrink
+ * the runtime footprint, and giving us at least some parts of what
+ * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
+ */
+#include "usbstring.c"
+#include "config.c"
+#include "epautoconf.c"
+
 /*-------------------------------------------------------------------------*/
 
 #define DRIVER_DESC            "File-backed Storage Gadget"
 #define DRIVER_NAME            "g_file_storage"
-#define DRIVER_VERSION         "20 October 2004"
+#define DRIVER_VERSION         "20 November 2008"
 
 static const char longname[] = DRIVER_DESC;
 static const char shortname[] = DRIVER_NAME;
@@ -275,56 +296,43 @@ MODULE_LICENSE("Dual BSD/GPL");
 
 /*-------------------------------------------------------------------------*/
 
-#define xprintk(f,level,fmt,args...) \
-       dev_printk(level , &(f)->gadget->dev , fmt , ## args)
-#define yprintk(l,level,fmt,args...) \
-       dev_printk(level , &(l)->dev , fmt , ## args)
-
-#ifdef DEBUG
-#define DBG(fsg,fmt,args...) \
-       xprintk(fsg , KERN_DEBUG , fmt , ## args)
 #define LDBG(lun,fmt,args...) \
-       yprintk(lun , KERN_DEBUG , fmt , ## args)
-#define MDBG(fmt,args...) \
-       printk(KERN_DEBUG DRIVER_NAME ": " fmt , ## args)
-#else
-#define DBG(fsg,fmt,args...) \
-       do { } while (0)
-#define LDBG(lun,fmt,args...) \
-       do { } while (0)
+       dev_dbg(&(lun)->dev , fmt , ## args)
 #define MDBG(fmt,args...) \
-       do { } while (0)
-#undef VERBOSE
+       pr_debug(DRIVER_NAME ": " fmt , ## args)
+
+#ifndef DEBUG
+#undef VERBOSE_DEBUG
 #undef DUMP_MSGS
-#endif /* DEBUG */
+#endif /* !DEBUG */
 
-#ifdef VERBOSE
-#define VDBG   DBG
+#ifdef VERBOSE_DEBUG
 #define VLDBG  LDBG
 #else
-#define VDBG(fsg,fmt,args...) \
-       do { } while (0)
 #define VLDBG(lun,fmt,args...) \
        do { } while (0)
-#endif /* VERBOSE */
+#endif /* VERBOSE_DEBUG */
 
-#define ERROR(fsg,fmt,args...) \
-       xprintk(fsg , KERN_ERR , fmt , ## args)
 #define LERROR(lun,fmt,args...) \
-       yprintk(lun , KERN_ERR , fmt , ## args)
-
-#define WARN(fsg,fmt,args...) \
-       xprintk(fsg , KERN_WARNING , fmt , ## args)
+       dev_err(&(lun)->dev , fmt , ## args)
 #define LWARN(lun,fmt,args...) \
-       yprintk(lun , KERN_WARNING , fmt , ## args)
-
-#define INFO(fsg,fmt,args...) \
-       xprintk(fsg , KERN_INFO , fmt , ## args)
+       dev_warn(&(lun)->dev , fmt , ## args)
 #define LINFO(lun,fmt,args...) \
-       yprintk(lun , KERN_INFO , fmt , ## args)
+       dev_info(&(lun)->dev , fmt , ## args)
 
 #define MINFO(fmt,args...) \
-       printk(KERN_INFO DRIVER_NAME ": " fmt , ## args)
+       pr_info(DRIVER_NAME ": " fmt , ## args)
+
+#define DBG(d, fmt, args...) \
+       dev_dbg(&(d)->gadget->dev , fmt , ## args)
+#define VDBG(d, fmt, args...) \
+       dev_vdbg(&(d)->gadget->dev , fmt , ## args)
+#define ERROR(d, fmt, args...) \
+       dev_err(&(d)->gadget->dev , fmt , ## args)
+#define WARNING(d, fmt, args...) \
+       dev_warn(&(d)->gadget->dev , fmt , ## args)
+#define INFO(d, fmt, args...) \
+       dev_info(&(d)->gadget->dev , fmt , ## args)
 
 
 /*-------------------------------------------------------------------------*/
@@ -333,23 +341,23 @@ 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 {
-       int             num_filenames;
-       int             num_ros;
+       char            *file[MAX_LUNS];
+       int             ro[MAX_LUNS];
+       unsigned int    num_filenames;
+       unsigned int    num_ros;
        unsigned int    nluns;
 
+       int             removable;
+       int             can_stall;
+       int             cdrom;
+
        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;
@@ -360,18 +368,20 @@ static struct {
        .transport_parm         = "BBB",
        .protocol_parm          = "SCSI",
        .removable              = 0,
+       .can_stall              = 1,
+       .cdrom                  = 0,
        .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);
@@ -380,6 +390,12 @@ MODULE_PARM_DESC(luns, "number of LUNs");
 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");
+
+module_param_named(cdrom, mod_data.cdrom, bool, S_IRUGO);
+MODULE_PARM_DESC(cdrom, "true to emulate cdrom instead of disk");
+
 
 /* In the non-TEST version, only the module parameters listed above
  * are available. */
@@ -404,14 +420,15 @@ 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 */
 
 
 /*-------------------------------------------------------------------------*/
 
+/* SCSI device types */
+#define TYPE_DISK      0x00
+#define TYPE_CDROM     0x05
+
 /* USB protocol value = the transport method */
 #define USB_PR_CBI     0x00            // Control/Bulk/Interrupt
 #define USB_PR_CB      0x01            // Control/Bulk w/o interrupt
@@ -488,6 +505,8 @@ struct interrupt_data {
 #define SC_READ_12                     0xa8
 #define SC_READ_CAPACITY               0x25
 #define SC_READ_FORMAT_CAPACITIES      0x23
+#define SC_READ_HEADER                 0x44
+#define SC_READ_TOC                    0x43
 #define SC_RELEASE                     0x17
 #define SC_REQUEST_SENSE               0x03
 #define SC_RESERVE                     0x16
@@ -553,6 +572,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;
@@ -563,7 +583,7 @@ struct lun {
 
 #define backing_file_is_open(curlun)   ((curlun)->filp != NULL)
 
-static inline struct lun *dev_to_lun(struct device *dev)
+static struct lun *dev_to_lun(struct device *dev)
 {
        return container_of(dev, struct lun, dev);
 }
@@ -584,8 +604,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
@@ -594,9 +613,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 {
@@ -629,13 +648,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;
@@ -654,7 +676,7 @@ struct fsg_dev {
 
        unsigned long           atomic_bitflags;
 #define REGISTERED             0
-#define CLEAR_BULK_HALTS       1
+#define IGNORE_BULK_OUT                1
 #define SUSPENDED              2
 
        struct usb_ep           *bulk_in;
@@ -665,12 +687,9 @@ 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;
 
        int                     cmnd_size;
        u8                      cmnd[MAX_COMMAND_SIZE];
@@ -693,18 +712,17 @@ struct fsg_dev {
        unsigned int            nluns;
        struct lun              *luns;
        struct lun              *curlun;
-       struct completion       lun_released;
 };
 
 typedef void (*fsg_routine_t)(struct fsg_dev *);
 
-static int inline exception_in_progress(struct fsg_dev *fsg)
+static int exception_in_progress(struct fsg_dev *fsg)
 {
        return (fsg->state > FSG_STATE_IDLE);
 }
 
 /* Make bulk-out requests be divisible by the maxpacket size */
-static void inline set_bulk_out_req_length(struct fsg_dev *fsg,
+static void set_bulk_out_req_length(struct fsg_dev *fsg,
                struct fsg_buffhd *bh, unsigned int length)
 {
        unsigned int    rem;
@@ -730,50 +748,36 @@ static void       close_all_backing_files(struct fsg_dev *fsg);
 static void dump_msg(struct fsg_dev *fsg, const char *label,
                const u8 *buf, unsigned int length)
 {
-       unsigned int    start, num, i;
-       char            line[52], *p;
-
-       if (length >= 512)
-               return;
-       DBG(fsg, "%s, length %u:\n", label, length);
-
-       start = 0;
-       while (length > 0) {
-               num = min(length, 16u);
-               p = line;
-               for (i = 0; i < num; ++i) {
-                       if (i == 8)
-                               *p++ = ' ';
-                       sprintf(p, " %02x", buf[i]);
-                       p += 3;
-               }
-               *p = 0;
-               printk(KERN_DEBUG "%6x: %s\n", start, line);
-               buf += num;
-               start += num;
-               length -= num;
+       if (length < 512) {
+               DBG(fsg, "%s, length %u:\n", label, length);
+               print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET,
+                               16, 1, buf, length, 0);
        }
 }
 
-static void inline dump_cdb(struct fsg_dev *fsg)
+static void dump_cdb(struct fsg_dev *fsg)
 {}
 
 #else
 
-static void inline dump_msg(struct fsg_dev *fsg, const char *label,
+static void dump_msg(struct fsg_dev *fsg, const char *label,
                const u8 *buf, unsigned int length)
 {}
 
-static void inline dump_cdb(struct fsg_dev *fsg)
-{
-       int     i;
-       char    cmdbuf[3*MAX_COMMAND_SIZE + 1];
+#ifdef VERBOSE_DEBUG
 
-       for (i = 0; i < fsg->cmnd_size; ++i)
-               sprintf(cmdbuf + i*3, " %02x", fsg->cmnd[i]);
-       VDBG(fsg, "SCSI CDB: %s\n", cmdbuf);
+static void dump_cdb(struct fsg_dev *fsg)
+{
+       print_hex_dump(KERN_DEBUG, "SCSI CDB: ", DUMP_PREFIX_NONE,
+                       16, 1, fsg->cmnd, fsg->cmnd_size, 0);
 }
 
+#else
+
+static void dump_cdb(struct fsg_dev *fsg)
+{}
+
+#endif /* VERBOSE_DEBUG */
 #endif /* DUMP_MSGS */
 
 
@@ -796,29 +800,29 @@ static int fsg_set_halt(struct fsg_dev *fsg, struct usb_ep *ep)
 
 /* Routines for unaligned data access */
 
-static u16 inline get_be16(u8 *buf)
+static u16 get_be16(u8 *buf)
 {
        return ((u16) buf[0] << 8) | ((u16) buf[1]);
 }
 
-static u32 inline get_be32(u8 *buf)
+static u32 get_be32(u8 *buf)
 {
        return ((u32) buf[0] << 24) | ((u32) buf[1] << 16) |
                        ((u32) buf[2] << 8) | ((u32) buf[3]);
 }
 
-static void inline put_be16(u8 *buf, u16 val)
+static void put_be16(u8 *buf, u16 val)
 {
        buf[0] = val >> 8;
        buf[1] = val;
 }
 
-static void inline put_be32(u8 *buf, u32 val)
+static void 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;
 }
 
 
@@ -843,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,
@@ -867,7 +871,7 @@ config_desc = {
        .bConfigurationValue =  CONFIG_VALUE,
        .iConfiguration =       STRING_CONFIG,
        .bmAttributes =         USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
-       .bMaxPower =            1,      // self-powered
+       .bMaxPower =            CONFIG_USB_GADGET_VBUS_DRAW / 2,
 };
 
 static struct usb_otg_descriptor
@@ -922,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
 };
 
@@ -937,8 +941,6 @@ static const struct usb_descriptor_header *fs_function[] = {
 #define FS_FUNCTION_PRE_EP_ENTRIES     2
 
 
-#ifdef CONFIG_USB_GADGET_DUALSPEED
-
 /*
  * USB 2.0 devices need to expose both high speed and full speed
  * descriptors, unless they only run at full speed.
@@ -952,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,
@@ -965,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
@@ -975,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
 };
 
@@ -986,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
 };
 
@@ -1001,14 +1003,14 @@ static const struct usb_descriptor_header *hs_function[] = {
 #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))
-
-#else
-
-/* If there's no high speed support, always use the full-speed descriptor. */
-#define ep_desc(g,fs,hs)       fs
-
-#endif /* !CONFIG_USB_GADGET_DUALSPEED */
+static struct usb_endpoint_descriptor *
+ep_desc(struct usb_gadget *g, struct usb_endpoint_descriptor *fs,
+               struct usb_endpoint_descriptor *hs)
+{
+       if (gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH)
+               return hs;
+       return fs;
+}
 
 
 /* The CBI specification limits the serial string to 12 uppercase hexadecimal
@@ -1040,26 +1042,22 @@ static struct usb_gadget_strings        stringtab = {
 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;
 
        if (index > 0)
                return -EINVAL;
 
-#ifdef CONFIG_USB_GADGET_DUALSPEED
-       if (type == USB_DT_OTHER_SPEED_CONFIG)
+       if (gadget_is_dualspeed(gadget) && type == USB_DT_OTHER_SPEED_CONFIG)
                speed = (USB_SPEED_FULL + USB_SPEED_HIGH) - speed;
-       if (speed == USB_SPEED_HIGH)
+       if (gadget_is_dualspeed(gadget) && speed == USB_SPEED_HIGH)
                function = hs_function;
        else
-#endif
                function = fs_function;
 
        /* for now, don't advertise srp-only devices */
-       if (!gadget->is_otg)
+       if (!gadget_is_otg(gadget))
                function++;
 
        len = usb_gadget_config_buf(&config_desc, buf, EP0_BUFSIZE, function);
@@ -1072,18 +1070,19 @@ static int populate_config_buf(struct usb_gadget *gadget,
 
 /* 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
@@ -1092,9 +1091,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);
 }
@@ -1124,7 +1123,7 @@ static int ep0_queue(struct fsg_dev *fsg)
        if (rc != 0 && rc != -ESHUTDOWN) {
 
                /* We can't do much more than wait for a reset */
-               WARN(fsg, "error in submission: %s --> %d\n",
+               WARNING(fsg, "error in submission: %s --> %d\n",
                                fsg->ep0->name, rc);
        }
        return rc;
@@ -1132,12 +1131,12 @@ static int ep0_queue(struct fsg_dev *fsg)
 
 static void ep0_complete(struct usb_ep *ep, struct usb_request *req)
 {
-       struct fsg_dev          *fsg = (struct fsg_dev *) ep->driver_data;
+       struct fsg_dev          *fsg = ep->driver_data;
 
        if (req->actual > 0)
                dump_msg(fsg, fsg->ep0req_name, req->buf, req->actual);
        if (req->status || req->actual != req->length)
-               DBG(fsg, "%s --> %d, %u/%u\n", __FUNCTION__,
+               DBG(fsg, "%s --> %d, %u/%u\n", __func__,
                                req->status, req->actual, req->length);
        if (req->status == -ECONNRESET)         // Request was cancelled
                usb_ep_fifo_flush(ep);
@@ -1154,63 +1153,66 @@ static void ep0_complete(struct usb_ep *ep, struct usb_request *req)
 
 static void bulk_in_complete(struct usb_ep *ep, struct usb_request *req)
 {
-       struct fsg_dev          *fsg = (struct fsg_dev *) ep->driver_data;
-       struct fsg_buffhd       *bh = (struct fsg_buffhd *) req->context;
+       struct fsg_dev          *fsg = ep->driver_data;
+       struct fsg_buffhd       *bh = req->context;
 
        if (req->status || req->actual != req->length)
-               DBG(fsg, "%s --> %d, %u/%u\n", __FUNCTION__,
+               DBG(fsg, "%s --> %d, %u/%u\n", __func__,
                                req->status, req->actual, req->length);
        if (req->status == -ECONNRESET)         // Request was cancelled
                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)
 {
-       struct fsg_dev          *fsg = (struct fsg_dev *) ep->driver_data;
-       struct fsg_buffhd       *bh = (struct fsg_buffhd *) req->context;
+       struct fsg_dev          *fsg = ep->driver_data;
+       struct fsg_buffhd       *bh = req->context;
 
        dump_msg(fsg, "bulk-out", req->buf, req->actual);
        if (req->status || req->actual != bh->bulk_out_intended_length)
-               DBG(fsg, "%s --> %d, %u/%u\n", __FUNCTION__,
+               DBG(fsg, "%s --> %d, %u/%u\n", __func__,
                                req->status, req->actual,
                                bh->bulk_out_intended_length);
        if (req->status == -ECONNRESET)         // Request was cancelled
                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)
 {
-       struct fsg_dev          *fsg = (struct fsg_dev *) ep->driver_data;
-       struct fsg_buffhd       *bh = (struct fsg_buffhd *) req->context;
+       struct fsg_dev          *fsg = ep->driver_data;
+       struct fsg_buffhd       *bh = req->context;
 
        if (req->status || req->actual != req->length)
-               DBG(fsg, "%s --> %d, %u/%u\n", __FUNCTION__,
+               DBG(fsg, "%s --> %d, %u/%u\n", __func__,
                                req->status, req->actual, req->length);
        if (req->status == -ECONNRESET)         // Request was cancelled
                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);
+       spin_unlock(&fsg->lock);
 }
 
 #else
@@ -1257,12 +1259,12 @@ static void received_cbi_adsc(struct fsg_dev *fsg, struct fsg_buffhd *bh)
 
        /* Save the command for later */
        if (fsg->cbbuf_cmnd_size)
-               WARN(fsg, "CB[I] overwriting previous command\n");
+               WARNING(fsg, "CB[I] overwriting previous command\n");
        fsg->cbbuf_cmnd_size = req->actual;
        memcpy(fsg->cbbuf_cmnd, req->buf, fsg->cbbuf_cmnd_size);
 
-       spin_unlock(&fsg->lock);
        wakeup_thread(fsg);
+       spin_unlock(&fsg->lock);
 }
 
 #else
@@ -1276,8 +1278,9 @@ static int class_setup_req(struct fsg_dev *fsg,
 {
        struct usb_request      *req = fsg->ep0req;
        int                     value = -EOPNOTSUPP;
-       u16                     w_index = ctrl->wIndex;
-       u16                     w_length = ctrl->wLength;
+       u16                     w_index = le16_to_cpu(ctrl->wIndex);
+       u16                     w_value = le16_to_cpu(ctrl->wValue);
+       u16                     w_length = le16_to_cpu(ctrl->wLength);
 
        if (!fsg->config)
                return value;
@@ -1290,7 +1293,7 @@ static int class_setup_req(struct fsg_dev *fsg,
                        if (ctrl->bRequestType != (USB_DIR_OUT |
                                        USB_TYPE_CLASS | USB_RECIP_INTERFACE))
                                break;
-                       if (w_index != 0) {
+                       if (w_index != 0 || w_value != 0) {
                                value = -EDOM;
                                break;
                        }
@@ -1306,13 +1309,13 @@ static int class_setup_req(struct fsg_dev *fsg,
                        if (ctrl->bRequestType != (USB_DIR_IN |
                                        USB_TYPE_CLASS | USB_RECIP_INTERFACE))
                                break;
-                       if (w_index != 0) {
+                       if (w_index != 0 || w_value != 0) {
                                value = -EDOM;
                                break;
                        }
                        VDBG(fsg, "get max LUN\n");
                        *(u8 *) req->buf = fsg->nluns - 1;
-                       value = min(w_length, (u16) 1);
+                       value = 1;
                        break;
                }
        }
@@ -1325,7 +1328,7 @@ static int class_setup_req(struct fsg_dev *fsg,
                        if (ctrl->bRequestType != (USB_DIR_OUT |
                                        USB_TYPE_CLASS | USB_RECIP_INTERFACE))
                                break;
-                       if (w_index != 0) {
+                       if (w_index != 0 || w_value != 0) {
                                value = -EDOM;
                                break;
                        }
@@ -1344,7 +1347,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, w_index, w_length);
+                       le16_to_cpu(ctrl->wValue), w_index, w_length);
        return value;
 }
 
@@ -1358,9 +1361,8 @@ static int standard_setup_req(struct fsg_dev *fsg,
 {
        struct usb_request      *req = fsg->ep0req;
        int                     value = -EOPNOTSUPP;
-       u16                     w_index = ctrl->wIndex;
-       u16                     w_value = ctrl->wValue;
-       u16                     w_length = ctrl->wLength;
+       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. */
@@ -1374,35 +1376,29 @@ static int standard_setup_req(struct fsg_dev *fsg,
 
                case USB_DT_DEVICE:
                        VDBG(fsg, "get device descriptor\n");
-                       value = min(w_length, (u16) sizeof device_desc);
+                       value = sizeof device_desc;
                        memcpy(req->buf, &device_desc, value);
                        break;
-#ifdef CONFIG_USB_GADGET_DUALSPEED
                case USB_DT_DEVICE_QUALIFIER:
                        VDBG(fsg, "get device qualifier\n");
-                       if (!fsg->gadget->is_dualspeed)
+                       if (!gadget_is_dualspeed(fsg->gadget))
                                break;
-                       value = min(w_length, (u16) sizeof dev_qualifier);
+                       value = sizeof dev_qualifier;
                        memcpy(req->buf, &dev_qualifier, value);
                        break;
 
                case USB_DT_OTHER_SPEED_CONFIG:
                        VDBG(fsg, "get other-speed config descriptor\n");
-                       if (!fsg->gadget->is_dualspeed)
+                       if (!gadget_is_dualspeed(fsg->gadget))
                                break;
                        goto get_config;
-#endif
                case USB_DT_CONFIG:
                        VDBG(fsg, "get configuration descriptor\n");
-#ifdef CONFIG_USB_GADGET_DUALSPEED
-               get_config:
-#endif
+get_config:
                        value = populate_config_buf(fsg->gadget,
                                        req->buf,
                                        w_value >> 8,
                                        w_value & 0xff);
-                       if (value >= 0)
-                               value = min(w_length, (u16) value);
                        break;
 
                case USB_DT_STRING:
@@ -1411,8 +1407,6 @@ static int standard_setup_req(struct fsg_dev *fsg,
                        /* wIndex == language code */
                        value = usb_gadget_get_string(&stringtab,
                                        w_value & 0xff, req->buf);
-                       if (value >= 0)
-                               value = min(w_length, (u16) value);
                        break;
                }
                break;
@@ -1438,7 +1432,7 @@ static int standard_setup_req(struct fsg_dev *fsg,
                        break;
                VDBG(fsg, "get configuration\n");
                *(u8 *) req->buf = fsg->config;
-               value = min(w_length, (u16) 1);
+               value = 1;
                break;
 
        case USB_REQ_SET_INTERFACE:
@@ -1466,14 +1460,14 @@ static int standard_setup_req(struct fsg_dev *fsg,
                }
                VDBG(fsg, "get interface\n");
                *(u8 *) req->buf = 0;
-               value = min(w_length, (u16) 1);
+               value = 1;
                break;
 
        default:
                VDBG(fsg,
                        "unknown control req %02x.%02x v%04x i%04x l%u\n",
                        ctrl->bRequestType, ctrl->bRequest,
-                       w_value, w_index, w_length);
+                       w_value, w_index, le16_to_cpu(ctrl->wLength));
        }
 
        return value;
@@ -1485,6 +1479,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;
@@ -1498,9 +1493,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);
@@ -1518,8 +1513,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;
 
@@ -1527,8 +1522,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;
@@ -1540,7 +1538,7 @@ static void start_transfer(struct fsg_dev *fsg, struct usb_ep *ep,
                 * submissions if DMA is enabled. */
                if (rc != -ESHUTDOWN && !(rc == -EOPNOTSUPP &&
                                                req->length == 0))
-                       WARN(fsg, "error in submission: %s --> %d\n",
+                       WARNING(fsg, "error in submission: %s --> %d\n",
                                        ep->name, rc);
        }
 }
@@ -1548,15 +1546,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;
-       if (current->flags & PF_FREEZE)
-               refrigerator(PF_FREEZE);
-       return (rc ? -EINTR : 0);
+       return rc;
 }
 
 
@@ -1621,7 +1627,8 @@ static int do_read(struct fsg_dev *fsg)
                /* Wait for the next buffer to become available */
                bh = fsg->next_buffhd_to_fill;
                while (bh->state != BUF_STATE_EMPTY) {
-                       if ((rc = sleep_thread(fsg)) != 0)
+                       rc = sleep_thread(fsg);
+                       if (rc)
                                return rc;
                }
 
@@ -1631,6 +1638,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;
@@ -1666,6 +1674,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;
                }
 
@@ -1702,7 +1711,9 @@ static int do_write(struct fsg_dev *fsg)
                curlun->sense_data = SS_WRITE_PROTECTED;
                return -EINVAL;
        }
+       spin_lock(&curlun->filp->f_lock);
        curlun->filp->f_flags &= ~O_SYNC;       // Default is not to wait
+       spin_unlock(&curlun->filp->f_lock);
 
        /* Get the starting Logical Block Address and check that it's
         * not too big */
@@ -1719,8 +1730,11 @@ static int do_write(struct fsg_dev *fsg)
                        curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
                        return -EINVAL;
                }
-               if (fsg->cmnd[1] & 0x08)        // FUA
+               if (fsg->cmnd[1] & 0x08) {      // FUA
+                       spin_lock(&curlun->filp->f_lock);
                        curlun->filp->f_flags |= O_SYNC;
+                       spin_unlock(&curlun->filp->f_lock);
+               }
        }
        if (lba >= curlun->num_sectors) {
                curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
@@ -1760,6 +1774,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);
@@ -1782,6 +1797,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;
@@ -1793,6 +1809,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;
 
@@ -1800,6 +1817,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;
                        }
 
@@ -1841,6 +1859,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;
                        }
 
@@ -1853,7 +1872,8 @@ static int do_write(struct fsg_dev *fsg)
                }
 
                /* Wait for something to happen */
-               if ((rc = sleep_thread(fsg)) != 0)
+               rc = sleep_thread(fsg);
+               if (rc)
                        return rc;
        }
 
@@ -1868,28 +1888,10 @@ static int do_write(struct fsg_dev *fsg)
 static int fsync_sub(struct lun *curlun)
 {
        struct file     *filp = curlun->filp;
-       struct inode    *inode;
-       int             rc, err;
 
        if (curlun->ro || !filp)
                return 0;
-       if (!filp->f_op->fsync)
-               return -EINVAL;
-
-       inode = filp->f_dentry->d_inode;
-       down(&inode->i_sem);
-       current->flags |= PF_SYNCWRITE;
-       rc = filemap_fdatawrite(inode->i_mapping);
-       err = filp->f_op->fsync(filp, filp->f_dentry, 1);
-       if (!rc)
-               rc = err;
-       err = filemap_fdatawait(inode->i_mapping);
-       if (!rc)
-               rc = err;
-       current->flags &= ~PF_SYNCWRITE;
-       up(&inode->i_sem);
-       VLDBG(curlun, "fdatasync -> %d\n", rc);
-       return rc;
+       return vfs_fsync(filp, filp->f_path.dentry, 1);
 }
 
 static void fsync_all(struct fsg_dev *fsg)
@@ -1919,10 +1921,10 @@ 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);
+       rc = invalidate_mapping_pages(inode->i_mapping, 0, -1);
        VLDBG(curlun, "invalidate_inode_pages -> %ld\n", rc);
 }
 
@@ -1985,6 +1987,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;
                }
 
@@ -2011,6 +2014,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;
@@ -2027,23 +2031,28 @@ static int do_inquiry(struct fsg_dev *fsg, struct fsg_buffhd *bh)
        u8      *buf = (u8 *) bh->buf;
 
        static char vendor_id[] = "Linux   ";
-       static char product_id[] = "File-Stor Gadget";
+       static char product_disk_id[] = "File-Stor Gadget";
+       static char product_cdrom_id[] = "File-CD Gadget  ";
 
        if (!fsg->curlun) {             // Unsupported LUNs are okay
                fsg->bad_lun_okay = 1;
                memset(buf, 0, 36);
                buf[0] = 0x7f;          // Unsupported, no device-type
+               buf[4] = 31;            // Additional length
                return 36;
        }
 
-       memset(buf, 0, 8);      // Non-removable, direct-access device
+       memset(buf, 0, 8);
+       buf[0] = (mod_data.cdrom ? TYPE_CDROM : TYPE_DISK);
        if (mod_data.removable)
                buf[1] = 0x80;
        buf[2] = 2;             // ANSI SCSI level 2
        buf[3] = 2;             // SCSI-2 INQUIRY data format
        buf[4] = 31;            // Additional length
                                // No special options
-       sprintf(buf + 8, "%-8s%-16s%04x", vendor_id, product_id,
+       sprintf(buf + 8, "%-8s%-16s%04x", vendor_id,
+                       (mod_data.cdrom ? product_cdrom_id :
+                               product_disk_id),
                        mod_data.release);
        return 36;
 }
@@ -2054,6 +2063,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):
@@ -2081,15 +2091,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
@@ -2118,6 +2131,75 @@ static int do_read_capacity(struct fsg_dev *fsg, struct fsg_buffhd *bh)
 }
 
 
+static void store_cdrom_address(u8 *dest, int msf, u32 addr)
+{
+       if (msf) {
+               /* Convert to Minutes-Seconds-Frames */
+               addr >>= 2;             /* Convert to 2048-byte frames */
+               addr += 2*75;           /* Lead-in occupies 2 seconds */
+               dest[3] = addr % 75;    /* Frames */
+               addr /= 75;
+               dest[2] = addr % 60;    /* Seconds */
+               addr /= 60;
+               dest[1] = addr;         /* Minutes */
+               dest[0] = 0;            /* Reserved */
+       } else {
+               /* Absolute sector */
+               put_be32(dest, addr);
+       }
+}
+
+static int do_read_header(struct fsg_dev *fsg, struct fsg_buffhd *bh)
+{
+       struct lun      *curlun = fsg->curlun;
+       int             msf = fsg->cmnd[1] & 0x02;
+       u32             lba = get_be32(&fsg->cmnd[2]);
+       u8              *buf = (u8 *) bh->buf;
+
+       if ((fsg->cmnd[1] & ~0x02) != 0) {              /* Mask away MSF */
+               curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
+               return -EINVAL;
+       }
+       if (lba >= curlun->num_sectors) {
+               curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
+               return -EINVAL;
+       }
+
+       memset(buf, 0, 8);
+       buf[0] = 0x01;          /* 2048 bytes of user data, rest is EC */
+       store_cdrom_address(&buf[4], msf, lba);
+       return 8;
+}
+
+
+static int do_read_toc(struct fsg_dev *fsg, struct fsg_buffhd *bh)
+{
+       struct lun      *curlun = fsg->curlun;
+       int             msf = fsg->cmnd[1] & 0x02;
+       int             start_track = fsg->cmnd[6];
+       u8              *buf = (u8 *) bh->buf;
+
+       if ((fsg->cmnd[1] & ~0x02) != 0 ||              /* Mask away MSF */
+                       start_track > 1) {
+               curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
+               return -EINVAL;
+       }
+
+       memset(buf, 0, 20);
+       buf[1] = (20-2);                /* TOC data length */
+       buf[2] = 1;                     /* First track number */
+       buf[3] = 1;                     /* Last track number */
+       buf[5] = 0x16;                  /* Data track, copying allowed */
+       buf[6] = 0x01;                  /* Only track is number 1 */
+       store_cdrom_address(&buf[8], msf, 0);
+
+       buf[13] = 0x16;                 /* Lead-out track is data */
+       buf[14] = 0xAA;                 /* Lead-out track number */
+       store_cdrom_address(&buf[16], msf, curlun->num_sectors);
+       return 20;
+}
+
+
 static int do_mode_sense(struct fsg_dev *fsg, struct fsg_buffhd *bh)
 {
        struct lun      *curlun = fsg->curlun;
@@ -2307,7 +2389,7 @@ static int halt_bulk_in_endpoint(struct fsg_dev *fsg)
                VDBG(fsg, "delayed bulk-in endpoint halt\n");
        while (rc != 0) {
                if (rc != -EAGAIN) {
-                       WARN(fsg, "usb_ep_set_halt -> %d\n", rc);
+                       WARNING(fsg, "usb_ep_set_halt -> %d\n", rc);
                        rc = 0;
                        break;
                }
@@ -2320,6 +2402,29 @@ static int halt_bulk_in_endpoint(struct fsg_dev *fsg)
        return rc;
 }
 
+static int wedge_bulk_in_endpoint(struct fsg_dev *fsg)
+{
+       int     rc;
+
+       DBG(fsg, "bulk-in set wedge\n");
+       rc = usb_ep_set_wedge(fsg->bulk_in);
+       if (rc == -EAGAIN)
+               VDBG(fsg, "delayed bulk-in endpoint wedge\n");
+       while (rc != 0) {
+               if (rc != -EAGAIN) {
+                       WARNING(fsg, "usb_ep_set_wedge -> %d\n", rc);
+                       rc = 0;
+                       break;
+               }
+
+               /* Wait for a short time and then try again */
+               if (msleep_interruptible(100) != 0)
+                       return -EINTR;
+               rc = usb_ep_set_wedge(fsg->bulk_in);
+       }
+       return rc;
+}
+
 static int pad_with_zeros(struct fsg_dev *fsg)
 {
        struct fsg_buffhd       *bh = fsg->next_buffhd_to_fill;
@@ -2333,7 +2438,8 @@ static int pad_with_zeros(struct fsg_dev *fsg)
 
                /* Wait for the next buffer to be free */
                while (bh->state != BUF_STATE_EMPTY) {
-                       if ((rc = sleep_thread(fsg)) != 0)
+                       rc = sleep_thread(fsg);
+                       if (rc)
                                return rc;
                }
 
@@ -2361,6 +2467,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;
 
@@ -2383,6 +2490,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;
@@ -2391,7 +2499,8 @@ static int throw_away_data(struct fsg_dev *fsg)
                }
 
                /* Otherwise wait for something to happen */
-               if ((rc = sleep_thread(fsg)) != 0)
+               rc = sleep_thread(fsg);
+               if (rc)
                        return rc;
        }
        return 0;
@@ -2513,7 +2622,8 @@ static int send_status(struct fsg_dev *fsg)
        /* Wait for the next buffer to become available */
        bh = fsg->next_buffhd_to_fill;
        while (bh->state != BUF_STATE_EMPTY) {
-               if ((rc = sleep_thread(fsg)) != 0)
+               rc = sleep_thread(fsg);
+               if (rc)
                        return rc;
        }
 
@@ -2538,10 +2648,10 @@ static int send_status(struct fsg_dev *fsg)
        }
 
        if (transport_is_bbb()) {
-               struct bulk_cs_wrap     *csw = (struct bulk_cs_wrap *) bh->buf;
+               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;
@@ -2557,8 +2667,7 @@ static int send_status(struct fsg_dev *fsg)
                return 0;
 
        } else {                        // USB_PR_CBI
-               struct interrupt_data   *buf = (struct interrupt_data *)
-                                               bh->buf;
+               struct interrupt_data   *buf = bh->buf;
 
                /* Store and send the Interrupt data.  UFI sends the ASC
                 * and ASCQ bytes.  Everything else sends a Type (which
@@ -2574,7 +2683,6 @@ static int send_status(struct fsg_dev *fsg)
 
                fsg->intr_buffhd = bh;          // Point to the right buffhd
                fsg->intreq->buf = bh->inreq->buf;
-               fsg->intreq->dma = bh->inreq->dma;
                fsg->intreq->context = bh;
                start_transfer(fsg, fsg->intr_in, fsg->intreq,
                                &fsg->intreq_busy, &bh->state);
@@ -2651,17 +2759,30 @@ static int check_command(struct fsg_dev *fsg, int cmnd_size,
        /* Verify the length of the command itself */
        if (cmnd_size != fsg->cmnd_size) {
 
-               /* Special case workaround: MS-Windows issues REQUEST SENSE
-                * with cbw->Length == 12 (it should be 6). */
-               if (fsg->cmnd[0] == SC_REQUEST_SENSE && fsg->cmnd_size == 12)
+               /* Special case workaround: There are plenty of buggy SCSI
+                * implementations. Many have issues with cbw->Length
+                * field passing a wrong command size. For those cases we
+                * always try to work around the problem by using the length
+                * sent by the host side provided it is at least as large
+                * as the correct command length.
+                * Examples of such cases would be MS-Windows, which issues
+                * REQUEST SENSE with cbw->Length == 12 where it should
+                * be 6, and xbox360 issuing INQUIRY, TEST UNIT READY and
+                * REQUEST SENSE with cbw->Length == 10 where it should
+                * be 6 as well.
+                */
+               if (cmnd_size <= fsg->cmnd_size) {
+                       DBG(fsg, "%s is buggy! Expected length %d "
+                                       "but we got %d\n", name,
+                                       cmnd_size, fsg->cmnd_size);
                        cmnd_size = fsg->cmnd_size;
-               else {
+               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, "
@@ -2676,6 +2797,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;
@@ -2734,9 +2856,10 @@ static int do_scsi_command(struct fsg_dev *fsg)
        /* Wait for the next buffer to become available for data or status */
        bh = fsg->next_buffhd_to_drain = fsg->next_buffhd_to_fill;
        while (bh->state != BUF_STATE_EMPTY) {
-               if ((rc = sleep_thread(fsg)) != 0)
+               rc = sleep_thread(fsg);
+               if (rc)
                        return rc;
-               }
+       }
        fsg->phase_error = 0;
        fsg->short_packet_received = 0;
 
@@ -2824,6 +2947,26 @@ static int do_scsi_command(struct fsg_dev *fsg)
                        reply = do_read_capacity(fsg, bh);
                break;
 
+       case SC_READ_HEADER:
+               if (!mod_data.cdrom)
+                       goto unknown_cmnd;
+               fsg->data_size_from_cmnd = get_be16(&fsg->cmnd[7]);
+               if ((reply = check_command(fsg, 10, DATA_DIR_TO_HOST,
+                               (3<<7) | (0x1f<<1), 1,
+                               "READ HEADER")) == 0)
+                       reply = do_read_header(fsg, bh);
+               break;
+
+       case SC_READ_TOC:
+               if (!mod_data.cdrom)
+                       goto unknown_cmnd;
+               fsg->data_size_from_cmnd = get_be16(&fsg->cmnd[7]);
+               if ((reply = check_command(fsg, 10, DATA_DIR_TO_HOST,
+                               (7<<6) | (1<<1), 1,
+                               "READ TOC")) == 0)
+                       reply = do_read_toc(fsg, bh);
+               break;
+
        case SC_READ_FORMAT_CAPACITIES:
                fsg->data_size_from_cmnd = get_be16(&fsg->cmnd[7]);
                if ((reply = check_command(fsg, 10, DATA_DIR_TO_HOST,
@@ -2909,6 +3052,7 @@ static int do_scsi_command(struct fsg_dev *fsg)
                // Fall through
 
        default:
+ unknown_cmnd:
                fsg->data_size_from_cmnd = 0;
                sprintf(unknown, "Unknown x%02x", fsg->cmnd[0]);
                if ((reply = check_command(fsg, fsg->cmnd_size,
@@ -2942,33 +3086,37 @@ static int do_scsi_command(struct fsg_dev *fsg)
 static int received_cbw(struct fsg_dev *fsg, struct fsg_buffhd *bh)
 {
        struct usb_request      *req = bh->outreq;
-       struct bulk_cb_wrap     *cbw = (struct bulk_cb_wrap *) req->buf;
+       struct bulk_cb_wrap     *cbw = req->buf;
 
-       /* Was this a real packet? */
-       if (req->status)
+       /* Was this a real packet?  Should it be ignored? */
+       if (req->status || test_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags))
                return -EINVAL;
 
        /* 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,
                                le32_to_cpu(cbw->Signature));
 
-               /* The Bulk-only spec says we MUST stall the bulk pipes!
-                * If we want to avoid stalls, set a flag so that we will
-                * clear the endpoint halts at the next reset. */
-               if (!mod_data.can_stall)
-                       set_bit(CLEAR_BULK_HALTS, &fsg->atomic_bitflags);
-               fsg_set_halt(fsg, fsg->bulk_out);
-               halt_bulk_in_endpoint(fsg);
+               /* The Bulk-only spec says we MUST stall the IN endpoint
+                * (6.6.1), so it's unavoidable.  It also says we must
+                * retain this state until the next reset, but there's
+                * no way to tell the controller driver it should ignore
+                * Clear-Feature(HALT) requests.
+                *
+                * We aren't required to halt the OUT endpoint; instead
+                * we can simply accept and discard any data received
+                * until the next reset. */
+               wedge_bulk_in_endpoint(fsg);
+               set_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags);
                return -EINVAL;
        }
 
        /* Is the CBW meaningful? */
        if (cbw->Lun >= MAX_LUNS || cbw->Flags & ~USB_BULK_IN_FLAG ||
-                       cbw->Length < 6 || cbw->Length > MAX_COMMAND_SIZE) {
+                       cbw->Length <= 0 || cbw->Length > MAX_COMMAND_SIZE) {
                DBG(fsg, "non-meaningful CBW: lun = %u, flags = 0x%x, "
                                "cmdlen %u\n",
                                cbw->Lun, cbw->Flags, cbw->Length);
@@ -3008,12 +3156,14 @@ static int get_next_command(struct fsg_dev *fsg)
                /* Wait for the next buffer to become available */
                bh = fsg->next_buffhd_to_fill;
                while (bh->state != BUF_STATE_EMPTY) {
-                       if ((rc = sleep_thread(fsg)) != 0)
+                       rc = sleep_thread(fsg);
+                       if (rc)
                                return rc;
-                       }
+               }
 
                /* 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);
 
@@ -3023,9 +3173,11 @@ static int get_next_command(struct fsg_dev *fsg)
 
                /* Wait for the CBW to arrive */
                while (bh->state != BUF_STATE_FULL) {
-                       if ((rc = sleep_thread(fsg)) != 0)
+                       rc = sleep_thread(fsg);
+                       if (rc)
                                return rc;
-                       }
+               }
+               smp_rmb();
                rc = received_cbw(fsg, bh);
                bh->state = BUF_STATE_EMPTY;
 
@@ -3033,9 +3185,10 @@ static int get_next_command(struct fsg_dev *fsg)
 
                /* Wait for the next command to arrive */
                while (fsg->cbbuf_cmnd_size == 0) {
-                       if ((rc = sleep_thread(fsg)) != 0)
+                       rc = sleep_thread(fsg);
+                       if (rc)
                                return rc;
-                       }
+               }
 
                /* Is the previous status interrupt request still busy?
                 * The host is allowed to skip reading the status,
@@ -3143,6 +3296,7 @@ reset:
                goto reset;
        fsg->bulk_out_enabled = 1;
        fsg->bulk_out_maxpacket = le16_to_cpu(d->wMaxPacketSize);
+       clear_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags);
 
        if (transport_is_cbi()) {
                d = ep_desc(fsg->gadget, &fs_intr_in_desc, &hs_intr_in_desc);
@@ -3160,7 +3314,6 @@ reset:
                if ((rc = alloc_request(fsg, fsg->bulk_out, &bh->outreq)) != 0)
                        goto reset;
                bh->inreq->buf = bh->outreq->buf = bh->buf;
-               bh->inreq->dma = bh->outreq->dma = bh->dma;
                bh->inreq->context = bh->outreq->context = bh;
                bh->inreq->complete = bulk_in_complete;
                bh->outreq->complete = bulk_out_complete;
@@ -3236,8 +3389,7 @@ static void handle_exception(struct fsg_dev *fsg)
        /* Clear the existing signals.  Anything but SIGUSR1 is converted
         * into a high-priority EXIT exception. */
        for (;;) {
-               sig = dequeue_signal_lock(current, &fsg->thread_signal_mask,
-                               &info);
+               sig = dequeue_signal_lock(current, &current->blocked, &info);
                if (!sig)
                        break;
                if (sig != SIGUSR1) {
@@ -3303,6 +3455,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;
        }
@@ -3325,11 +3478,8 @@ static void handle_exception(struct fsg_dev *fsg)
                /* In case we were forced against our will to halt a
                 * bulk endpoint, clear the halt now.  (The SuperH UDC
                 * requires this.) */
-               if (test_and_clear_bit(CLEAR_BULK_HALTS,
-                               &fsg->atomic_bitflags)) {
+               if (test_and_clear_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags))
                        usb_ep_clear_halt(fsg->bulk_in);
-                       usb_ep_clear_halt(fsg->bulk_out);
-               }
 
                if (transport_is_bbb()) {
                        if (fsg->ep0_req_tag == exception_req_tag)
@@ -3385,28 +3535,23 @@ static void handle_exception(struct fsg_dev *fsg)
 
 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");
+       struct fsg_dev          *fsg = fsg_;
 
        /* 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) |
-                       sigmask(SIGTERM) | sigmask(SIGKILL) |
-                       sigmask(SIGUSR1));
-       sigprocmask(SIG_SETMASK, &fsg->thread_signal_mask, NULL);
+       allow_signal(SIGINT);
+       allow_signal(SIGTERM);
+       allow_signal(SIGKILL);
+       allow_signal(SIGUSR1);
+
+       /* Allow the thread to be frozen */
+       set_freezable();
 
        /* Arrange for userspace references to be interpreted as kernel
         * pointers.  That way we can pass a kernel pointer to a routine
         * 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)) {
@@ -3444,8 +3589,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. */
@@ -3472,6 +3618,7 @@ static int open_backing_file(struct lun *curlun, const char *filename)
        struct inode                    *inode = NULL;
        loff_t                          size;
        loff_t                          num_sectors;
+       loff_t                          min_sectors;
 
        /* R/W if we can, R/O if we must */
        ro = curlun->ro;
@@ -3490,8 +3637,8 @@ static int open_backing_file(struct lun *curlun, const char *filename)
        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,8 +3662,19 @@ static int open_backing_file(struct lun *curlun, const char *filename)
                rc = (int) size;
                goto out;
        }
-       num_sectors = size >> 9;        // File size in 512-byte sectors
-       if (num_sectors == 0) {
+       num_sectors = size >> 9;        // File size in 512-byte blocks
+       min_sectors = 1;
+       if (mod_data.cdrom) {
+               num_sectors &= ~3;      // Reduce to a multiple of 2048
+               min_sectors = 300*4;    // Smallest track is 300 frames
+               if (num_sectors >= 256*60*75*4) {
+                       num_sectors = (256*60*75 - 1) * 4;
+                       LINFO(curlun, "file too big: %s\n", filename);
+                       LINFO(curlun, "using only first %d blocks\n",
+                                       (int) num_sectors);
+               }
+       }
+       if (num_sectors < min_sectors) {
                LINFO(curlun, "file too small: %s\n", filename);
                rc = -ETOOSMALL;
                goto out;
@@ -3561,17 +3719,17 @@ static ssize_t show_ro(struct device *dev, struct device_attribute *attr, char *
        return sprintf(buf, "%d\n", curlun->ro);
 }
 
-static ssize_t show_file(struct device *dev, struct device_attribute *attr, 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);
+       struct fsg_dev  *fsg = dev_get_drvdata(dev);
        char            *p;
        ssize_t         rc;
 
        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,
-                               buf, PAGE_SIZE - 1);
+               p = d_path(&curlun->filp->f_path, buf, PAGE_SIZE - 1);
                if (IS_ERR(p))
                        rc = PTR_ERR(p);
                else {
@@ -3589,11 +3747,12 @@ static ssize_t show_file(struct device *dev, struct device_attribute *attr, char
 }
 
 
-static ssize_t store_ro(struct device *dev, struct device_attribute *attr, 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);
-       struct fsg_dev  *fsg = (struct fsg_dev *) dev_get_drvdata(dev);
+       struct fsg_dev  *fsg = dev_get_drvdata(dev);
        int             i;
 
        if (sscanf(buf, "%d", &i) != 1)
@@ -3613,10 +3772,11 @@ static ssize_t store_ro(struct device *dev, struct device_attribute *attr, const
        return rc;
 }
 
-static ssize_t store_file(struct device *dev, struct device_attribute *attr, 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);
+       struct fsg_dev  *fsg = dev_get_drvdata(dev);
        int             rc = 0;
 
        if (curlun->prevent_medium_removal && backing_file_is_open(curlun)) {
@@ -3654,14 +3814,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);
+       struct fsg_dev  *fsg = 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;
@@ -3672,14 +3840,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;
                }
        }
@@ -3694,19 +3860,12 @@ static void fsg_unbind(struct usb_gadget *gadget)
        }
 
        /* Free the data buffers */
-       for (i = 0; i < NUM_BUFFERS; ++i) {
-               struct fsg_buffhd       *bh = &fsg->buffhds[i];
-
-               if (bh->buf)
-                       usb_ep_free_buffer(fsg->bulk_in, bh->buf, bh->dma,
-                                       mod_data.buflen);
-       }
+       for (i = 0; i < NUM_BUFFERS; ++i)
+               kfree(fsg->buffhds[i].buf);
 
        /* Free the request and buffer for endpoint 0 */
        if (req) {
-               if (req->buf)
-                       usb_ep_free_buffer(fsg->ep0, req->buf,
-                                       req->dma, EP0_BUFSIZE);
+               kfree(req->buf);
                usb_ep_free_request(fsg->ep0, req);
        }
 
@@ -3717,6 +3876,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;
@@ -3724,39 +3884,23 @@ static int __init check_parameters(struct fsg_dev *fsg)
        mod_data.protocol_type = USB_SC_SCSI;
        mod_data.protocol_name = "Transparent SCSI";
 
-       if (gadget_is_sh(fsg->gadget))
+       /* Some peripheral controllers are known not to be able to
+        * halt bulk endpoints correctly.  If one of them is present,
+        * disable stalls.
+        */
+       if (gadget_is_sh(fsg->gadget) || gadget_is_at91(fsg->gadget))
                mod_data.can_stall = 0;
 
        if (mod_data.release == 0xffff) {       // Parameter wasn't set
-               if (gadget_is_net2280(fsg->gadget))
-                       mod_data.release = 0x0301;
-               else if (gadget_is_dummy(fsg->gadget))
-                       mod_data.release = 0x0302;
-               else if (gadget_is_pxa(fsg->gadget))
-                       mod_data.release = 0x0303;
-               else if (gadget_is_sh(fsg->gadget))
-                       mod_data.release = 0x0304;
-
                /* The sa1100 controller is not supported */
-
-               else if (gadget_is_goku(fsg->gadget))
-                       mod_data.release = 0x0306;
-               else if (gadget_is_mq11xx(fsg->gadget))
-                       mod_data.release = 0x0307;
-               else if (gadget_is_omap(fsg->gadget))
-                       mod_data.release = 0x0308;
-               else if (gadget_is_lh7a40x(fsg->gadget))
-                       mod_data.release = 0x0309;
-               else if (gadget_is_n9604(fsg->gadget))
-                       mod_data.release = 0x0310;
-               else if (gadget_is_pxa27x(fsg->gadget))
-                       mod_data.release = 0x0311;
-               else if (gadget_is_s3c2410(gadget))
-                       mod_data.release = 0x0312;
-               else if (gadget_is_at91(fsg->gadget))
-                       mod_data.release = 0x0313;
+               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",
+                       WARNING(fsg, "controller '%s' not recognized\n",
                                fsg->gadget->name);
                        mod_data.release = 0x0399;
                }
@@ -3837,15 +3981,18 @@ static int __init fsg_bind(struct usb_gadget *gadget)
                goto out;
 
        if (mod_data.removable) {       // Enable the store_xxx attributes
-               dev_attr_ro.attr.mode = dev_attr_file.attr.mode = 0644;
-               dev_attr_ro.store = store_ro;
+               dev_attr_file.attr.mode = 0644;
                dev_attr_file.store = store_file;
+               if (!mod_data.cdrom) {
+                       dev_attr_ro.attr.mode = 0644;
+                       dev_attr_ro.store = store_ro;
+               }
        }
 
        /* Find out how many LUNs there should be */
        i = mod_data.nluns;
        if (i == 0)
-               i = max(mod_data.num_filenames, 1);
+               i = max(mod_data.num_filenames, 1u);
        if (i > MAX_LUNS) {
                ERROR(fsg, "invalid number of LUNs: %d\n", i);
                rc = -EINVAL;
@@ -3854,34 +4001,42 @@ static int __init fsg_bind(struct usb_gadget *gadget)
 
        /* Create the LUNs, open their backing files, and register the
         * LUN devices in sysfs. */
-       fsg->luns = kmalloc(i * sizeof(struct lun), GFP_KERNEL);
+       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];
+               if (mod_data.cdrom)
+                       curlun->ro = 1;
+               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);
+               dev_set_name(&curlun->dev,"%s-lun%d",
+                            dev_name(&gadget->dev), i);
 
-               if ((rc = device_register(&curlun->dev)) != 0)
+               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);
+                       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 (file[i] && *file[i]) {
-                       if ((rc = open_backing_file(curlun, file[i])) != 0)
+               if (mod_data.file[i] && *mod_data.file[i]) {
+                       if ((rc = open_backing_file(curlun,
+                                       mod_data.file[i])) != 0)
                                goto out;
                } else if (!mod_data.removable) {
                        ERROR(fsg, "no file given for LUN%d\n", i);
@@ -3924,31 +4079,31 @@ static int __init fsg_bind(struct usb_gadget *gadget)
        intf_desc.bInterfaceProtocol = mod_data.transport_type;
        fs_function[i + FS_FUNCTION_PRE_EP_ENTRIES] = NULL;
 
-#ifdef CONFIG_USB_GADGET_DUALSPEED
-       hs_function[i + HS_FUNCTION_PRE_EP_ENTRIES] = NULL;
+       if (gadget_is_dualspeed(gadget)) {
+               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;
+               /* Assume ep0 uses the same maxpacket value for both speeds */
+               dev_qualifier.bMaxPacketSize0 = fsg->ep0->maxpacket;
 
-       /* Assume that all endpoint addresses are the same for both speeds */
-       hs_bulk_in_desc.bEndpointAddress = fs_bulk_in_desc.bEndpointAddress;
-       hs_bulk_out_desc.bEndpointAddress = fs_bulk_out_desc.bEndpointAddress;
-       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;
+               /* Assume endpoint addresses are the same for both speeds */
+               hs_bulk_in_desc.bEndpointAddress =
+                               fs_bulk_in_desc.bEndpointAddress;
+               hs_bulk_out_desc.bEndpointAddress =
+                               fs_bulk_out_desc.bEndpointAddress;
+               hs_intr_in_desc.bEndpointAddress =
+                               fs_intr_in_desc.bEndpointAddress;
        }
 
+       if (gadget_is_otg(gadget))
+               otg_desc.bmAttributes |= USB_OTG_HNP;
+
        rc = -ENOMEM;
 
        /* Allocate the request and buffer for endpoint 0 */
        fsg->ep0req = req = usb_ep_alloc_request(fsg->ep0, GFP_KERNEL);
        if (!req)
                goto out;
-       req->buf = usb_ep_alloc_buffer(fsg->ep0, EP0_BUFSIZE,
-                       &req->dma, GFP_KERNEL);
+       req->buf = kmalloc(EP0_BUFSIZE, GFP_KERNEL);
        if (!req->buf)
                goto out;
        req->complete = ep0_complete;
@@ -3957,8 +4112,10 @@ static int __init fsg_bind(struct usb_gadget *gadget)
        for (i = 0; i < NUM_BUFFERS; ++i) {
                struct fsg_buffhd       *bh = &fsg->buffhds[i];
 
-               bh->buf = usb_ep_alloc_buffer(fsg->bulk_in, mod_data.buflen,
-                               &bh->dma, GFP_KERNEL);
+               /* Allocate for the bulk-in endpoint.  We assume that
+                * the buffer will also work with the bulk-out (and
+                * interrupt-in) endpoint. */
+               bh->buf = kmalloc(mod_data.buflen, GFP_KERNEL);
                if (!bh->buf)
                        goto out;
                bh->next = bh + 1;
@@ -3969,7 +4126,7 @@ static int __init fsg_bind(struct usb_gadget *gadget)
        usb_gadget_set_selfpowered(gadget);
 
        snprintf(manufacturer, sizeof manufacturer, "%s %s with %s",
-                       system_utsname.sysname, system_utsname.release,
+                       init_utsname()->sysname, init_utsname()->release,
                        gadget->name);
 
        /* On a real device, serial[] would be loaded from permanent
@@ -3982,10 +4139,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);
@@ -3996,9 +4155,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,
-                                       pathbuf, PATH_MAX);
+                               p = d_path(&curlun->filp->f_path,
+                                          pathbuf, PATH_MAX);
                                if (IS_ERR(p))
                                        p = NULL;
                        }
@@ -4014,10 +4172,15 @@ static int __init fsg_bind(struct usb_gadget *gadget)
                        mod_data.protocol_name, mod_data.protocol_type);
        DBG(fsg, "VendorID=x%04x, ProductID=x%04x, Release=x%04x\n",
                        mod_data.vendor, mod_data.product, mod_data.release);
-       DBG(fsg, "removable=%d, stall=%d, buflen=%u\n",
+       DBG(fsg, "removable=%d, stall=%d, cdrom=%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);
+                       mod_data.cdrom, mod_data.buflen);
+       DBG(fsg, "I/O thread pid: %d\n", task_pid_nr(fsg->thread_task));
+
+       set_bit(REGISTERED, &fsg->atomic_bitflags);
+
+       /* Tell the thread to start working */
+       wake_up_process(fsg->thread_task);
        return 0;
 
 autoconf_fail:
@@ -4028,6 +4191,7 @@ out:
        fsg->state = FSG_STATE_TERMINATED;      // The thread is dead
        fsg_unbind(gadget);
        close_all_backing_files(fsg);
+       complete(&fsg->thread_notifier);
        return rc;
 }
 
@@ -4069,6 +4233,7 @@ static struct usb_gadget_driver           fsg_driver = {
 
        .driver         = {
                .name           = (char *) shortname,
+               .owner          = THIS_MODULE,
                // .release = ...
                // .suspend = ...
                // .resume = ...
@@ -4080,13 +4245,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;
@@ -4094,13 +4258,6 @@ 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;
@@ -4109,15 +4266,9 @@ static int __init fsg_init(void)
        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);
-
-       /* 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);
 
@@ -4134,6 +4285,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);