USB: g_mass_storage: fixed module name in Kconfig
[safe/jmp/linux-2.6] / drivers / usb / gadget / file_storage.c
index eb28215..b49d86e 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...]
@@ -85,6 +97,8 @@
  *                                     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;
  *                                     PAGE_CACHE_SIZE)
  *
  * If CONFIG_USB_FILE_STORAGE_TEST is not set, only the "file", "ro",
- * "removable", "luns", and "stall" options are available; default values
- * are used for everything else.
+ * "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/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         "28 November 2005"
+#define DRIVER_VERSION         "20 November 2008"
+
+static       char fsg_string_manufacturer[64];
+static const char fsg_string_product[] = DRIVER_DESC;
+static       char fsg_string_serial[13];
+static const char fsg_string_config[] = "Self-powered";
+static const char fsg_string_interface[] = "Mass Storage";
+
+
+#include "storage_common.c"
 
-static const char longname[] = DRIVER_DESC;
-static const char shortname[] = DRIVER_NAME;
 
 MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_AUTHOR("Alan Stern");
 MODULE_LICENSE("Dual BSD/GPL");
 
-/* Thanks to NetChip Technologies for donating this product ID.
- *
- * DO NOT REUSE THESE IDs with any other driver!!  Ever!!
- * Instead:  allocate your own, using normal USB-IF procedures. */
-#define DRIVER_VENDOR_ID       0x0525  // NetChip
-#define DRIVER_PRODUCT_ID      0xa4a5  // Linux-USB File-backed Storage Gadget
-
-
 /*
  * This driver assumes self-powered hardware and has no way for users to
  * trigger remote wakeup.  It uses autoconfiguration to select endpoints
@@ -276,75 +295,19 @@ 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)
-#define MDBG(fmt,args...) \
-       do { } while (0)
-#undef VERBOSE
-#undef DUMP_MSGS
-#endif /* DEBUG */
-
-#ifdef VERBOSE
-#define VDBG   DBG
-#define VLDBG  LDBG
-#else
-#define VDBG(fsg,fmt,args...) \
-       do { } while (0)
-#define VLDBG(lun,fmt,args...) \
-       do { } while (0)
-#endif /* VERBOSE */
-
-#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)
-#define LWARN(lun,fmt,args...) \
-       yprintk(lun , KERN_WARNING , fmt , ## args)
-
-#define INFO(fsg,fmt,args...) \
-       xprintk(fsg , KERN_INFO , fmt , ## args)
-#define LINFO(lun,fmt,args...) \
-       yprintk(lun , KERN_INFO , fmt , ## args)
-
-#define MINFO(fmt,args...) \
-       printk(KERN_INFO DRIVER_NAME ": " fmt , ## args)
-
-
-/*-------------------------------------------------------------------------*/
 
 /* Encapsulate the module parameter settings */
 
-#define MAX_LUNS       8
-
-       /* Arggh!  There should be a module_param_array_named macro! */
-static char            *file[MAX_LUNS];
-static int             ro[MAX_LUNS];
-
 static struct {
-       int             num_filenames;
-       int             num_ros;
+       char            *file[FSG_MAX_LUNS];
+       int             ro[FSG_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;
@@ -363,17 +326,19 @@ static struct {
        .protocol_parm          = "SCSI",
        .removable              = 0,
        .can_stall              = 1,
-       .vendor                 = DRIVER_VENDOR_ID,
-       .product                = DRIVER_PRODUCT_ID,
+       .cdrom                  = 0,
+       .vendor                 = FSG_VENDOR_ID,
+       .product                = FSG_PRODUCT_ID,
        .release                = 0xffff,       // Use controller chip type
        .buflen                 = 16384,
        };
 
 
-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);
@@ -385,6 +350,9 @@ 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. */
@@ -412,119 +380,6 @@ MODULE_PARM_DESC(buflen, "I/O buffer size");
 #endif /* CONFIG_USB_FILE_STORAGE_TEST */
 
 
-/*-------------------------------------------------------------------------*/
-
-/* USB protocol value = the transport method */
-#define USB_PR_CBI     0x00            // Control/Bulk/Interrupt
-#define USB_PR_CB      0x01            // Control/Bulk w/o interrupt
-#define USB_PR_BULK    0x50            // Bulk-only
-
-/* USB subclass value = the protocol encapsulation */
-#define USB_SC_RBC     0x01            // Reduced Block Commands (flash)
-#define USB_SC_8020    0x02            // SFF-8020i, MMC-2, ATAPI (CD-ROM)
-#define USB_SC_QIC     0x03            // QIC-157 (tape)
-#define USB_SC_UFI     0x04            // UFI (floppy)
-#define USB_SC_8070    0x05            // SFF-8070i (removable)
-#define USB_SC_SCSI    0x06            // Transparent SCSI
-
-/* Bulk-only data structures */
-
-/* Command Block Wrapper */
-struct bulk_cb_wrap {
-       __le32  Signature;              // Contains 'USBC'
-       u32     Tag;                    // Unique per command id
-       __le32  DataTransferLength;     // Size of the data
-       u8      Flags;                  // Direction in bit 7
-       u8      Lun;                    // LUN (normally 0)
-       u8      Length;                 // Of the CDB, <= MAX_COMMAND_SIZE
-       u8      CDB[16];                // Command Data Block
-};
-
-#define USB_BULK_CB_WRAP_LEN   31
-#define USB_BULK_CB_SIG                0x43425355      // Spells out USBC
-#define USB_BULK_IN_FLAG       0x80
-
-/* Command Status Wrapper */
-struct bulk_cs_wrap {
-       __le32  Signature;              // Should = 'USBS'
-       u32     Tag;                    // Same as original command
-       __le32  Residue;                // Amount not transferred
-       u8      Status;                 // See below
-};
-
-#define USB_BULK_CS_WRAP_LEN   13
-#define USB_BULK_CS_SIG                0x53425355      // Spells out 'USBS'
-#define USB_STATUS_PASS                0
-#define USB_STATUS_FAIL                1
-#define USB_STATUS_PHASE_ERROR 2
-
-/* Bulk-only class specific requests */
-#define USB_BULK_RESET_REQUEST         0xff
-#define USB_BULK_GET_MAX_LUN_REQUEST   0xfe
-
-
-/* CBI Interrupt data structure */
-struct interrupt_data {
-       u8      bType;
-       u8      bValue;
-};
-
-#define CBI_INTERRUPT_DATA_LEN         2
-
-/* CBI Accept Device-Specific Command request */
-#define USB_CBI_ADSC_REQUEST           0x00
-
-
-#define MAX_COMMAND_SIZE       16      // Length of a SCSI Command Data Block
-
-/* SCSI commands that we recognize */
-#define SC_FORMAT_UNIT                 0x04
-#define SC_INQUIRY                     0x12
-#define SC_MODE_SELECT_6               0x15
-#define SC_MODE_SELECT_10              0x55
-#define SC_MODE_SENSE_6                        0x1a
-#define SC_MODE_SENSE_10               0x5a
-#define SC_PREVENT_ALLOW_MEDIUM_REMOVAL        0x1e
-#define SC_READ_6                      0x08
-#define SC_READ_10                     0x28
-#define SC_READ_12                     0xa8
-#define SC_READ_CAPACITY               0x25
-#define SC_READ_FORMAT_CAPACITIES      0x23
-#define SC_RELEASE                     0x17
-#define SC_REQUEST_SENSE               0x03
-#define SC_RESERVE                     0x16
-#define SC_SEND_DIAGNOSTIC             0x1d
-#define SC_START_STOP_UNIT             0x1b
-#define SC_SYNCHRONIZE_CACHE           0x35
-#define SC_TEST_UNIT_READY             0x00
-#define SC_VERIFY                      0x2f
-#define SC_WRITE_6                     0x0a
-#define SC_WRITE_10                    0x2a
-#define SC_WRITE_12                    0xaa
-
-/* SCSI Sense Key/Additional Sense Code/ASC Qualifier values */
-#define SS_NO_SENSE                            0
-#define SS_COMMUNICATION_FAILURE               0x040800
-#define SS_INVALID_COMMAND                     0x052000
-#define SS_INVALID_FIELD_IN_CDB                        0x052400
-#define SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE  0x052100
-#define SS_LOGICAL_UNIT_NOT_SUPPORTED          0x052500
-#define SS_MEDIUM_NOT_PRESENT                  0x023a00
-#define SS_MEDIUM_REMOVAL_PREVENTED            0x055302
-#define SS_NOT_READY_TO_READY_TRANSITION       0x062800
-#define SS_RESET_OCCURRED                      0x062900
-#define SS_SAVING_PARAMETERS_NOT_SUPPORTED     0x053900
-#define SS_UNRECOVERED_READ_ERROR              0x031100
-#define SS_WRITE_ERROR                         0x030c02
-#define SS_WRITE_PROTECTED                     0x072700
-
-#define SK(x)          ((u8) ((x) >> 16))      // Sense Key byte, etc.
-#define ASC(x)         ((u8) ((x) >> 8))
-#define ASCQ(x)                ((u8) (x))
-
-
-/*-------------------------------------------------------------------------*/
-
 /*
  * These definitions will permit the compiler to avoid generating code for
  * parts of the driver that aren't used in the non-TEST version.  Even gcc
@@ -547,81 +402,8 @@ struct interrupt_data {
 #endif /* CONFIG_USB_FILE_STORAGE_TEST */
 
 
-struct lun {
-       struct file     *filp;
-       loff_t          file_length;
-       loff_t          num_sectors;
-
-       unsigned int    ro : 1;
-       unsigned int    prevent_medium_removal : 1;
-       unsigned int    registered : 1;
-
-       u32             sense_data;
-       u32             sense_data_info;
-       u32             unit_attention_data;
-
-       struct device   dev;
-};
-
-#define backing_file_is_open(curlun)   ((curlun)->filp != NULL)
-
-static inline struct lun *dev_to_lun(struct device *dev)
-{
-       return container_of(dev, struct lun, dev);
-}
-
-
-/* Big enough to hold our biggest descriptor */
-#define EP0_BUFSIZE    256
-#define DELAYED_STATUS (EP0_BUFSIZE + 999)     // An impossibly large value
-
-/* Number of buffers we will use.  2 is enough for double-buffering */
-#define NUM_BUFFERS    2
-
-enum fsg_buffer_state {
-       BUF_STATE_EMPTY = 0,
-       BUF_STATE_FULL,
-       BUF_STATE_BUSY
-};
-
-struct fsg_buffhd {
-       void                            *buf;
-       dma_addr_t                      dma;
-       enum fsg_buffer_state           state;
-       struct fsg_buffhd               *next;
-
-       /* The NetChip 2280 is faster, and handles some protocol faults
-        * better, if we don't submit any short bulk-out read requests.
-        * So we will record the intended request length here. */
-       unsigned int                    bulk_out_intended_length;
-
-       struct usb_request              *inreq;
-       int                             inreq_busy;
-       struct usb_request              *outreq;
-       int                             outreq_busy;
-};
+/*-------------------------------------------------------------------------*/
 
-enum fsg_state {
-       FSG_STATE_COMMAND_PHASE = -10,          // This one isn't used anywhere
-       FSG_STATE_DATA_PHASE,
-       FSG_STATE_STATUS_PHASE,
-
-       FSG_STATE_IDLE = 0,
-       FSG_STATE_ABORT_BULK_OUT,
-       FSG_STATE_RESET,
-       FSG_STATE_INTERFACE_CHANGE,
-       FSG_STATE_CONFIG_CHANGE,
-       FSG_STATE_DISCONNECT,
-       FSG_STATE_EXIT,
-       FSG_STATE_TERMINATED
-};
-
-enum data_direction {
-       DATA_DIR_UNKNOWN = 0,
-       DATA_DIR_FROM_HOST,
-       DATA_DIR_TO_HOST,
-       DATA_DIR_NONE
-};
 
 struct fsg_dev {
        /* lock protects: state, all the req_busy's, and cbbuf_cmnd */
@@ -643,7 +425,7 @@ struct fsg_dev {
        int                     intreq_busy;
        struct fsg_buffhd       *intr_buffhd;
 
-       unsigned int            bulk_out_maxpacket;
+       unsigned int            bulk_out_maxpacket;
        enum fsg_state          state;          // For exception handling
        unsigned int            exception_req_tag;
 
@@ -659,7 +441,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;
@@ -668,12 +450,11 @@ struct fsg_dev {
 
        struct fsg_buffhd       *next_buffhd_to_fill;
        struct fsg_buffhd       *next_buffhd_to_drain;
-       struct fsg_buffhd       buffhds[NUM_BUFFERS];
+       struct fsg_buffhd       buffhds[FSG_NUM_BUFFERS];
 
        int                     thread_wakeup_needed;
        struct completion       thread_notifier;
        struct task_struct      *thread_task;
-       sigset_t                thread_signal_mask;
 
        int                     cmnd_size;
        u8                      cmnd[MAX_COMMAND_SIZE];
@@ -694,19 +475,19 @@ struct fsg_dev {
        u8                      cbbuf_cmnd[MAX_COMMAND_SIZE];
 
        unsigned int            nluns;
-       struct lun              *luns;
-       struct lun              *curlun;
+       struct fsg_lun          *luns;
+       struct fsg_lun          *curlun;
 };
 
 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;
@@ -721,64 +502,9 @@ static void inline set_bulk_out_req_length(struct fsg_dev *fsg,
 static struct fsg_dev                  *the_fsg;
 static struct usb_gadget_driver                fsg_driver;
 
-static void    close_backing_file(struct lun *curlun);
-static void    close_all_backing_files(struct fsg_dev *fsg);
-
 
 /*-------------------------------------------------------------------------*/
 
-#ifdef DUMP_MSGS
-
-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;
-       }
-}
-
-static void inline dump_cdb(struct fsg_dev *fsg)
-{}
-
-#else
-
-static void inline 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];
-
-       for (i = 0; i < fsg->cmnd_size; ++i)
-               sprintf(cmdbuf + i*3, " %02x", fsg->cmnd[i]);
-       VDBG(fsg, "SCSI CDB: %s\n", cmdbuf);
-}
-
-#endif /* DUMP_MSGS */
-
-
 static int fsg_set_halt(struct fsg_dev *fsg, struct usb_ep *ep)
 {
        const char      *name;
@@ -796,46 +522,11 @@ 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)
-{
-       return ((u16) buf[0] << 8) | ((u16) buf[1]);
-}
-
-static u32 inline 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)
-{
-       buf[0] = val >> 8;
-       buf[1] = val;
-}
-
-static void inline put_be32(u8 *buf, u32 val)
-{
-       buf[0] = val >> 24;
-       buf[1] = val >> 16;
-       buf[2] = val >> 8;
-       buf[3] = val & 0xff;
-}
-
-
-/*-------------------------------------------------------------------------*/
-
 /*
  * DESCRIPTORS ... most are static, but strings and (full) configuration
  * descriptors are built on demand.  Also the (static) config and interface
  * descriptors are adjusted during fsg_bind().
  */
-#define STRING_MANUFACTURER    1
-#define STRING_PRODUCT         2
-#define STRING_SERIAL          3
-#define STRING_CONFIG          4
-#define STRING_INTERFACE       5
 
 /* There is only one configuration. */
 #define        CONFIG_VALUE            1
@@ -845,17 +536,17 @@ 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(FSG_VENDOR_ID),
+       .idProduct =            cpu_to_le16(FSG_PRODUCT_ID),
+       .bcdDevice =            cpu_to_le16(0xffff),
 
-       .iManufacturer =        STRING_MANUFACTURER,
-       .iProduct =             STRING_PRODUCT,
-       .iSerialNumber =        STRING_SERIAL,
+       .iManufacturer =        FSG_STRING_MANUFACTURER,
+       .iProduct =             FSG_STRING_PRODUCT,
+       .iSerialNumber =        FSG_STRING_SERIAL,
        .bNumConfigurations =   1,
 };
 
@@ -867,171 +558,23 @@ config_desc = {
        /* wTotalLength computed by usb_gadget_config_buf() */
        .bNumInterfaces =       1,
        .bConfigurationValue =  CONFIG_VALUE,
-       .iConfiguration =       STRING_CONFIG,
+       .iConfiguration =       FSG_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
-otg_desc = {
-       .bLength =              sizeof(otg_desc),
-       .bDescriptorType =      USB_DT_OTG,
-
-       .bmAttributes =         USB_OTG_SRP,
-};
 
-/* There is only one interface. */
-
-static struct usb_interface_descriptor
-intf_desc = {
-       .bLength =              sizeof intf_desc,
-       .bDescriptorType =      USB_DT_INTERFACE,
-
-       .bNumEndpoints =        2,              // Adjusted during fsg_bind()
-       .bInterfaceClass =      USB_CLASS_MASS_STORAGE,
-       .bInterfaceSubClass =   USB_SC_SCSI,    // Adjusted during fsg_bind()
-       .bInterfaceProtocol =   USB_PR_BULK,    // Adjusted during fsg_bind()
-       .iInterface =           STRING_INTERFACE,
-};
-
-/* Three full-speed endpoint descriptors: bulk-in, bulk-out,
- * and interrupt-in. */
-
-static struct usb_endpoint_descriptor
-fs_bulk_in_desc = {
-       .bLength =              USB_DT_ENDPOINT_SIZE,
-       .bDescriptorType =      USB_DT_ENDPOINT,
-
-       .bEndpointAddress =     USB_DIR_IN,
-       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
-       /* wMaxPacketSize set by autoconfiguration */
-};
-
-static struct usb_endpoint_descriptor
-fs_bulk_out_desc = {
-       .bLength =              USB_DT_ENDPOINT_SIZE,
-       .bDescriptorType =      USB_DT_ENDPOINT,
-
-       .bEndpointAddress =     USB_DIR_OUT,
-       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
-       /* wMaxPacketSize set by autoconfiguration */
-};
-
-static struct usb_endpoint_descriptor
-fs_intr_in_desc = {
-       .bLength =              USB_DT_ENDPOINT_SIZE,
-       .bDescriptorType =      USB_DT_ENDPOINT,
-
-       .bEndpointAddress =     USB_DIR_IN,
-       .bmAttributes =         USB_ENDPOINT_XFER_INT,
-       .wMaxPacketSize =       __constant_cpu_to_le16(2),
-       .bInterval =            32,     // frames -> 32 ms
-};
-
-static const struct usb_descriptor_header *fs_function[] = {
-       (struct usb_descriptor_header *) &otg_desc,
-       (struct usb_descriptor_header *) &intf_desc,
-       (struct usb_descriptor_header *) &fs_bulk_in_desc,
-       (struct usb_descriptor_header *) &fs_bulk_out_desc,
-       (struct usb_descriptor_header *) &fs_intr_in_desc,
-       NULL,
-};
-#define FS_FUNCTION_PRE_EP_ENTRIES     2
-
-
-#ifdef CONFIG_USB_GADGET_DUALSPEED
-
-/*
- * USB 2.0 devices need to expose both high speed and full speed
- * descriptors, unless they only run at full speed.
- *
- * That means alternate endpoint descriptors (bigger packets)
- * and a "device qualifier" ... plus more construction options
- * for the config descriptor.
- */
 static struct usb_qualifier_descriptor
 dev_qualifier = {
        .bLength =              sizeof dev_qualifier,
        .bDescriptorType =      USB_DT_DEVICE_QUALIFIER,
 
-       .bcdUSB =               __constant_cpu_to_le16(0x0200),
+       .bcdUSB =               cpu_to_le16(0x0200),
        .bDeviceClass =         USB_CLASS_PER_INTERFACE,
 
        .bNumConfigurations =   1,
 };
 
-static struct usb_endpoint_descriptor
-hs_bulk_in_desc = {
-       .bLength =              USB_DT_ENDPOINT_SIZE,
-       .bDescriptorType =      USB_DT_ENDPOINT,
-
-       /* bEndpointAddress copied from fs_bulk_in_desc during fsg_bind() */
-       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
-       .wMaxPacketSize =       __constant_cpu_to_le16(512),
-};
-
-static struct usb_endpoint_descriptor
-hs_bulk_out_desc = {
-       .bLength =              USB_DT_ENDPOINT_SIZE,
-       .bDescriptorType =      USB_DT_ENDPOINT,
-
-       /* bEndpointAddress copied from fs_bulk_out_desc during fsg_bind() */
-       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
-       .wMaxPacketSize =       __constant_cpu_to_le16(512),
-       .bInterval =            1,      // NAK every 1 uframe
-};
-
-static struct usb_endpoint_descriptor
-hs_intr_in_desc = {
-       .bLength =              USB_DT_ENDPOINT_SIZE,
-       .bDescriptorType =      USB_DT_ENDPOINT,
-
-       /* bEndpointAddress copied from fs_intr_in_desc during fsg_bind() */
-       .bmAttributes =         USB_ENDPOINT_XFER_INT,
-       .wMaxPacketSize =       __constant_cpu_to_le16(2),
-       .bInterval =            9,      // 2**(9-1) = 256 uframes -> 32 ms
-};
-
-static const struct usb_descriptor_header *hs_function[] = {
-       (struct usb_descriptor_header *) &otg_desc,
-       (struct usb_descriptor_header *) &intf_desc,
-       (struct usb_descriptor_header *) &hs_bulk_in_desc,
-       (struct usb_descriptor_header *) &hs_bulk_out_desc,
-       (struct usb_descriptor_header *) &hs_intr_in_desc,
-       NULL,
-};
-#define HS_FUNCTION_PRE_EP_ENTRIES     2
-
-/* Maxpacket and other transfer characteristics vary by speed. */
-#define ep_desc(g,fs,hs)       (((g)->speed==USB_SPEED_HIGH) ? (hs) : (fs))
-
-#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 */
-
-
-/* The CBI specification limits the serial string to 12 uppercase hexadecimal
- * characters. */
-static char                            manufacturer[64];
-static char                            serial[13];
-
-/* Static strings, in UTF-8 (for simplicity we use only ASCII characters) */
-static struct usb_string               strings[] = {
-       {STRING_MANUFACTURER,   manufacturer},
-       {STRING_PRODUCT,        longname},
-       {STRING_SERIAL,         serial},
-       {STRING_CONFIG,         "Self-powered"},
-       {STRING_INTERFACE,      "Mass Storage"},
-       {}
-};
-
-static struct usb_gadget_strings       stringtab = {
-       .language       = 0x0409,               // en-us
-       .strings        = strings,
-};
 
 
 /*
@@ -1042,26 +585,21 @@ 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)
-               function = hs_function;
-       else
-#endif
-               function = fs_function;
+       function = gadget_is_dualspeed(gadget) && speed == USB_SPEED_HIGH
+               ? (const struct usb_descriptor_header **)fsg_hs_function
+               : (const struct usb_descriptor_header **)fsg_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);
@@ -1127,7 +665,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;
@@ -1135,12 +673,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);
@@ -1157,11 +695,11 @@ 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);
@@ -1177,12 +715,12 @@ static void bulk_in_complete(struct usb_ep *ep, struct usb_request *req)
 
 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
@@ -1201,11 +739,11 @@ static void bulk_out_complete(struct usb_ep *ep, struct usb_request *req)
 #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);
@@ -1263,7 +801,7 @@ 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);
 
@@ -1283,6 +821,7 @@ static int class_setup_req(struct fsg_dev *fsg,
        struct usb_request      *req = fsg->ep0req;
        int                     value = -EOPNOTSUPP;
        u16                     w_index = le16_to_cpu(ctrl->wIndex);
+       u16                     w_value = le16_to_cpu(ctrl->wValue);
        u16                     w_length = le16_to_cpu(ctrl->wLength);
 
        if (!fsg->config)
@@ -1296,7 +835,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;
                        }
@@ -1312,7 +851,7 @@ 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;
                        }
@@ -1331,7 +870,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;
                        }
@@ -1382,10 +921,9 @@ static int standard_setup_req(struct fsg_dev *fsg,
                        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 = sizeof dev_qualifier;
                        memcpy(req->buf, &dev_qualifier, value);
@@ -1393,15 +931,12 @@ static int standard_setup_req(struct fsg_dev *fsg,
 
                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,
@@ -1412,7 +947,7 @@ static int standard_setup_req(struct fsg_dev *fsg,
                        VDBG(fsg, "get string descriptor\n");
 
                        /* wIndex == language code */
-                       value = usb_gadget_get_string(&stringtab,
+                       value = usb_gadget_get_string(&fsg_stringtab,
                                        w_value & 0xff, req->buf);
                        break;
                }
@@ -1545,7 +1080,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);
        }
 }
@@ -1577,7 +1112,7 @@ static int sleep_thread(struct fsg_dev *fsg)
 
 static int do_read(struct fsg_dev *fsg)
 {
-       struct lun              *curlun = fsg->curlun;
+       struct fsg_lun          *curlun = fsg->curlun;
        u32                     lba;
        struct fsg_buffhd       *bh;
        int                     rc;
@@ -1590,9 +1125,9 @@ static int do_read(struct fsg_dev *fsg)
        /* Get the starting Logical Block Address and check that it's
         * not too big */
        if (fsg->cmnd[0] == SC_READ_6)
-               lba = (fsg->cmnd[1] << 16) | get_be16(&fsg->cmnd[2]);
+               lba = get_unaligned_be24(&fsg->cmnd[1]);
        else {
-               lba = get_be32(&fsg->cmnd[2]);
+               lba = get_unaligned_be32(&fsg->cmnd[2]);
 
                /* We allow DPO (Disable Page Out = don't save data in the
                 * cache) and FUA (Force Unit Access = don't read from the
@@ -1634,7 +1169,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;
                }
 
@@ -1644,6 +1180,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;
@@ -1679,6 +1216,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;
                }
 
@@ -1700,7 +1238,7 @@ static int do_read(struct fsg_dev *fsg)
 
 static int do_write(struct fsg_dev *fsg)
 {
-       struct lun              *curlun = fsg->curlun;
+       struct fsg_lun          *curlun = fsg->curlun;
        u32                     lba;
        struct fsg_buffhd       *bh;
        int                     get_some_more;
@@ -1715,14 +1253,16 @@ 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 */
        if (fsg->cmnd[0] == SC_WRITE_6)
-               lba = (fsg->cmnd[1] << 16) | get_be16(&fsg->cmnd[2]);
+               lba = get_unaligned_be24(&fsg->cmnd[1]);
        else {
-               lba = get_be32(&fsg->cmnd[2]);
+               lba = get_unaligned_be32(&fsg->cmnd[2]);
 
                /* We allow DPO (Disable Page Out = don't save data in the
                 * cache) and FUA (Force Unit Access = write directly to the
@@ -1732,8 +1272,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
-                       curlun->filp->f_flags |= O_SYNC;
+               if (fsg->cmnd[1] & 0x08) {      // FUA
+                       spin_lock(&curlun->filp->f_lock);
+                       curlun->filp->f_flags |= O_DSYNC;
+                       spin_unlock(&curlun->filp->f_lock);
+               }
        }
        if (lba >= curlun->num_sectors) {
                curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
@@ -1773,6 +1316,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);
@@ -1815,6 +1359,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;
                        }
 
@@ -1856,6 +1401,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;
                        }
 
@@ -1868,7 +1414,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;
        }
 
@@ -1878,51 +1425,14 @@ static int do_write(struct fsg_dev *fsg)
 
 /*-------------------------------------------------------------------------*/
 
-/* Sync the file data, don't bother with the metadata.
- * This code was copied from fs/buffer.c:sys_fdatasync(). */
-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;
-       mutex_lock(&inode->i_mutex);
-       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;
-       mutex_unlock(&inode->i_mutex);
-       VLDBG(curlun, "fdatasync -> %d\n", rc);
-       return rc;
-}
-
-static void fsync_all(struct fsg_dev *fsg)
-{
-       int     i;
-
-       for (i = 0; i < fsg->nluns; ++i)
-               fsync_sub(&fsg->luns[i]);
-}
-
 static int do_synchronize_cache(struct fsg_dev *fsg)
 {
-       struct lun      *curlun = fsg->curlun;
+       struct fsg_lun  *curlun = fsg->curlun;
        int             rc;
 
        /* We ignore the requested LBA and write out all file's
         * dirty data buffers. */
-       rc = fsync_sub(curlun);
+       rc = fsg_lun_fsync_sub(curlun);
        if (rc)
                curlun->sense_data = SS_WRITE_ERROR;
        return 0;
@@ -1931,19 +1441,19 @@ static int do_synchronize_cache(struct fsg_dev *fsg)
 
 /*-------------------------------------------------------------------------*/
 
-static void invalidate_sub(struct lun *curlun)
+static void invalidate_sub(struct fsg_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);
-       VLDBG(curlun, "invalidate_inode_pages -> %ld\n", rc);
+       rc = invalidate_mapping_pages(inode->i_mapping, 0, -1);
+       VLDBG(curlun, "invalidate_mapping_pages -> %ld\n", rc);
 }
 
 static int do_verify(struct fsg_dev *fsg)
 {
-       struct lun              *curlun = fsg->curlun;
+       struct fsg_lun          *curlun = fsg->curlun;
        u32                     lba;
        u32                     verification_length;
        struct fsg_buffhd       *bh = fsg->next_buffhd_to_fill;
@@ -1954,7 +1464,7 @@ static int do_verify(struct fsg_dev *fsg)
 
        /* Get the starting Logical Block Address and check that it's
         * not too big */
-       lba = get_be32(&fsg->cmnd[2]);
+       lba = get_unaligned_be32(&fsg->cmnd[2]);
        if (lba >= curlun->num_sectors) {
                curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
                return -EINVAL;
@@ -1967,7 +1477,7 @@ static int do_verify(struct fsg_dev *fsg)
                return -EINVAL;
        }
 
-       verification_length = get_be16(&fsg->cmnd[7]);
+       verification_length = get_unaligned_be16(&fsg->cmnd[7]);
        if (unlikely(verification_length == 0))
                return -EIO;            // No default reply
 
@@ -1976,7 +1486,7 @@ static int do_verify(struct fsg_dev *fsg)
        file_offset = ((loff_t) lba) << 9;
 
        /* Write out all the dirty buffers before invalidating them */
-       fsync_sub(curlun);
+       fsg_lun_fsync_sub(curlun);
        if (signal_pending(current))
                return -EINTR;
 
@@ -2000,6 +1510,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;
                }
 
@@ -2026,6 +1537,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;
@@ -2042,23 +1554,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;
 }
@@ -2066,9 +1583,10 @@ static int do_inquiry(struct fsg_dev *fsg, struct fsg_buffhd *bh)
 
 static int do_request_sense(struct fsg_dev *fsg, struct fsg_buffhd *bh)
 {
-       struct lun      *curlun = fsg->curlun;
+       struct fsg_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):
@@ -2096,17 +1614,20 @@ 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
+       put_unaligned_be32(sdinfo, &buf[3]);    /* Sense information */
        buf[7] = 18 - 8;                        // Additional sense length
        buf[12] = ASC(sd);
        buf[13] = ASCQ(sd);
@@ -2116,8 +1637,8 @@ static int do_request_sense(struct fsg_dev *fsg, struct fsg_buffhd *bh)
 
 static int do_read_capacity(struct fsg_dev *fsg, struct fsg_buffhd *bh)
 {
-       struct lun      *curlun = fsg->curlun;
-       u32             lba = get_be32(&fsg->cmnd[2]);
+       struct fsg_lun  *curlun = fsg->curlun;
+       u32             lba = get_unaligned_be32(&fsg->cmnd[2]);
        int             pmi = fsg->cmnd[8];
        u8              *buf = (u8 *) bh->buf;
 
@@ -2127,15 +1648,67 @@ static int do_read_capacity(struct fsg_dev *fsg, struct fsg_buffhd *bh)
                return -EINVAL;
        }
 
-       put_be32(&buf[0], curlun->num_sectors - 1);     // Max logical block
-       put_be32(&buf[4], 512);                         // Block length
+       put_unaligned_be32(curlun->num_sectors - 1, &buf[0]);
+                                               /* Max logical block */
+       put_unaligned_be32(512, &buf[4]);       /* Block length */
        return 8;
 }
 
 
+static int do_read_header(struct fsg_dev *fsg, struct fsg_buffhd *bh)
+{
+       struct fsg_lun  *curlun = fsg->curlun;
+       int             msf = fsg->cmnd[1] & 0x02;
+       u32             lba = get_unaligned_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 fsg_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;
+       struct fsg_lun  *curlun = fsg->curlun;
        int             mscmnd = fsg->cmnd[0];
        u8              *buf = (u8 *) bh->buf;
        u8              *buf0 = buf;
@@ -2186,10 +1759,13 @@ static int do_mode_sense(struct fsg_dev *fsg, struct fsg_buffhd *bh)
                        buf[2] = 0x04;  // Write cache enable,
                                        // Read cache not disabled
                                        // No cache retention priorities
-                       put_be16(&buf[4], 0xffff);  // Don't disable prefetch
-                                       // Minimum prefetch = 0
-                       put_be16(&buf[8], 0xffff);  // Maximum prefetch
-                       put_be16(&buf[10], 0xffff); // Maximum prefetch ceiling
+                       put_unaligned_be16(0xffff, &buf[4]);
+                                       /* Don't disable prefetch */
+                                       /* Minimum prefetch = 0 */
+                       put_unaligned_be16(0xffff, &buf[8]);
+                                       /* Maximum prefetch */
+                       put_unaligned_be16(0xffff, &buf[10]);
+                                       /* Maximum prefetch ceiling */
                }
                buf += 12;
        }
@@ -2206,14 +1782,14 @@ static int do_mode_sense(struct fsg_dev *fsg, struct fsg_buffhd *bh)
        if (mscmnd == SC_MODE_SENSE_6)
                buf0[0] = len - 1;
        else
-               put_be16(buf0, len - 2);
+               put_unaligned_be16(len - 2, buf0);
        return len;
 }
 
 
 static int do_start_stop(struct fsg_dev *fsg)
 {
-       struct lun      *curlun = fsg->curlun;
+       struct fsg_lun  *curlun = fsg->curlun;
        int             loej, start;
 
        if (!mod_data.removable) {
@@ -2243,7 +1819,7 @@ static int do_start_stop(struct fsg_dev *fsg)
                if (loej) {             // Simulate an unload/eject
                        up_read(&fsg->filesem);
                        down_write(&fsg->filesem);
-                       close_backing_file(curlun);
+                       fsg_lun_close(curlun);
                        up_write(&fsg->filesem);
                        down_read(&fsg->filesem);
                }
@@ -2251,7 +1827,7 @@ static int do_start_stop(struct fsg_dev *fsg)
 
                /* Our emulation doesn't support mounting; the medium is
                 * available for use as soon as it is loaded. */
-               if (!backing_file_is_open(curlun)) {
+               if (!fsg_lun_is_open(curlun)) {
                        curlun->sense_data = SS_MEDIUM_NOT_PRESENT;
                        return -EINVAL;
                }
@@ -2263,7 +1839,7 @@ static int do_start_stop(struct fsg_dev *fsg)
 
 static int do_prevent_allow(struct fsg_dev *fsg)
 {
-       struct lun      *curlun = fsg->curlun;
+       struct fsg_lun  *curlun = fsg->curlun;
        int             prevent;
 
        if (!mod_data.removable) {
@@ -2278,7 +1854,7 @@ static int do_prevent_allow(struct fsg_dev *fsg)
        }
 
        if (curlun->prevent_medium_removal && !prevent)
-               fsync_sub(curlun);
+               fsg_lun_fsync_sub(curlun);
        curlun->prevent_medium_removal = prevent;
        return 0;
 }
@@ -2287,23 +1863,24 @@ static int do_prevent_allow(struct fsg_dev *fsg)
 static int do_read_format_capacities(struct fsg_dev *fsg,
                        struct fsg_buffhd *bh)
 {
-       struct lun      *curlun = fsg->curlun;
+       struct fsg_lun  *curlun = fsg->curlun;
        u8              *buf = (u8 *) bh->buf;
 
        buf[0] = buf[1] = buf[2] = 0;
        buf[3] = 8;             // Only the Current/Maximum Capacity Descriptor
        buf += 4;
 
-       put_be32(&buf[0], curlun->num_sectors);         // Number of blocks
-       put_be32(&buf[4], 512);                         // Block length
-       buf[4] = 0x02;                                  // Current capacity
+       put_unaligned_be32(curlun->num_sectors, &buf[0]);
+                                               /* Number of blocks */
+       put_unaligned_be32(512, &buf[4]);       /* Block length */
+       buf[4] = 0x02;                          /* Current capacity */
        return 12;
 }
 
 
 static int do_mode_select(struct fsg_dev *fsg, struct fsg_buffhd *bh)
 {
-       struct lun      *curlun = fsg->curlun;
+       struct fsg_lun  *curlun = fsg->curlun;
 
        /* We don't support MODE SELECT */
        curlun->sense_data = SS_INVALID_COMMAND;
@@ -2322,7 +1899,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;
                }
@@ -2335,6 +1912,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;
@@ -2348,7 +1948,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;
                }
 
@@ -2408,7 +2009,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;
@@ -2521,7 +2123,7 @@ static int finish_reply(struct fsg_dev *fsg)
 
 static int send_status(struct fsg_dev *fsg)
 {
-       struct lun              *curlun = fsg->curlun;
+       struct fsg_lun          *curlun = fsg->curlun;
        struct fsg_buffhd       *bh;
        int                     rc;
        u8                      status = USB_STATUS_PASS;
@@ -2530,7 +2132,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;
        }
 
@@ -2555,10 +2158,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;
@@ -2574,8 +2177,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
@@ -2591,7 +2193,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);
@@ -2614,7 +2215,7 @@ static int check_command(struct fsg_dev *fsg, int cmnd_size,
        int                     lun = fsg->cmnd[1] >> 5;
        static const char       dirletter[4] = {'u', 'o', 'i', 'n'};
        char                    hdlen[20];
-       struct lun              *curlun;
+       struct fsg_lun          *curlun;
 
        /* Adjust the expected cmnd_size for protocol encapsulation padding.
         * Transparent SCSI doesn't pad. */
@@ -2668,11 +2269,24 @@ 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;
                }
@@ -2693,6 +2307,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;
@@ -2729,7 +2344,7 @@ static int check_command(struct fsg_dev *fsg, int cmnd_size,
 
        /* If the medium isn't mounted and the command needs to access
         * it, return an error. */
-       if (curlun && !backing_file_is_open(curlun) && needs_medium) {
+       if (curlun && !fsg_lun_is_open(curlun) && needs_medium) {
                curlun->sense_data = SS_MEDIUM_NOT_PRESENT;
                return -EINVAL;
        }
@@ -2751,9 +2366,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;
 
@@ -2777,7 +2393,7 @@ static int do_scsi_command(struct fsg_dev *fsg)
                break;
 
        case SC_MODE_SELECT_10:
-               fsg->data_size_from_cmnd = get_be16(&fsg->cmnd[7]);
+               fsg->data_size_from_cmnd = get_unaligned_be16(&fsg->cmnd[7]);
                if ((reply = check_command(fsg, 10, DATA_DIR_FROM_HOST,
                                (1<<1) | (3<<7), 0,
                                "MODE SELECT(10)")) == 0)
@@ -2793,7 +2409,7 @@ static int do_scsi_command(struct fsg_dev *fsg)
                break;
 
        case SC_MODE_SENSE_10:
-               fsg->data_size_from_cmnd = get_be16(&fsg->cmnd[7]);
+               fsg->data_size_from_cmnd = get_unaligned_be16(&fsg->cmnd[7]);
                if ((reply = check_command(fsg, 10, DATA_DIR_TO_HOST,
                                (1<<1) | (1<<2) | (3<<7), 0,
                                "MODE SENSE(10)")) == 0)
@@ -2818,7 +2434,8 @@ static int do_scsi_command(struct fsg_dev *fsg)
                break;
 
        case SC_READ_10:
-               fsg->data_size_from_cmnd = get_be16(&fsg->cmnd[7]) << 9;
+               fsg->data_size_from_cmnd =
+                               get_unaligned_be16(&fsg->cmnd[7]) << 9;
                if ((reply = check_command(fsg, 10, DATA_DIR_TO_HOST,
                                (1<<1) | (0xf<<2) | (3<<7), 1,
                                "READ(10)")) == 0)
@@ -2826,7 +2443,8 @@ static int do_scsi_command(struct fsg_dev *fsg)
                break;
 
        case SC_READ_12:
-               fsg->data_size_from_cmnd = get_be32(&fsg->cmnd[6]) << 9;
+               fsg->data_size_from_cmnd =
+                               get_unaligned_be32(&fsg->cmnd[6]) << 9;
                if ((reply = check_command(fsg, 12, DATA_DIR_TO_HOST,
                                (1<<1) | (0xf<<2) | (0xf<<6), 1,
                                "READ(12)")) == 0)
@@ -2841,8 +2459,28 @@ 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_unaligned_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_unaligned_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]);
+               fsg->data_size_from_cmnd = get_unaligned_be16(&fsg->cmnd[7]);
                if ((reply = check_command(fsg, 10, DATA_DIR_TO_HOST,
                                (3<<7), 1,
                                "READ FORMAT CAPACITIES")) == 0)
@@ -2900,7 +2538,8 @@ static int do_scsi_command(struct fsg_dev *fsg)
                break;
 
        case SC_WRITE_10:
-               fsg->data_size_from_cmnd = get_be16(&fsg->cmnd[7]) << 9;
+               fsg->data_size_from_cmnd =
+                               get_unaligned_be16(&fsg->cmnd[7]) << 9;
                if ((reply = check_command(fsg, 10, DATA_DIR_FROM_HOST,
                                (1<<1) | (0xf<<2) | (3<<7), 1,
                                "WRITE(10)")) == 0)
@@ -2908,7 +2547,8 @@ static int do_scsi_command(struct fsg_dev *fsg)
                break;
 
        case SC_WRITE_12:
-               fsg->data_size_from_cmnd = get_be32(&fsg->cmnd[6]) << 9;
+               fsg->data_size_from_cmnd =
+                               get_unaligned_be32(&fsg->cmnd[6]) << 9;
                if ((reply = check_command(fsg, 12, DATA_DIR_FROM_HOST,
                                (1<<1) | (0xf<<2) | (0xf<<6), 1,
                                "WRITE(12)")) == 0)
@@ -2926,6 +2566,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,
@@ -2958,34 +2599,38 @@ 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 usb_request              *req = bh->outreq;
+       struct fsg_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) {
+       if (cbw->Lun >= FSG_MAX_LUNS || cbw->Flags & ~USB_BULK_IN_FLAG ||
+                       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);
@@ -3025,9 +2670,10 @@ 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);
@@ -3041,9 +2687,10 @@ 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;
@@ -3052,9 +2699,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,
@@ -3114,7 +2762,7 @@ static int do_set_interface(struct fsg_dev *fsg, int altsetting)
 
 reset:
        /* Deallocate the requests */
-       for (i = 0; i < NUM_BUFFERS; ++i) {
+       for (i = 0; i < FSG_NUM_BUFFERS; ++i) {
                struct fsg_buffhd *bh = &fsg->buffhds[i];
 
                if (bh->inreq) {
@@ -3152,26 +2800,30 @@ reset:
        DBG(fsg, "set interface %d\n", altsetting);
 
        /* Enable the endpoints */
-       d = ep_desc(fsg->gadget, &fs_bulk_in_desc, &hs_bulk_in_desc);
+       d = fsg_ep_desc(fsg->gadget,
+                       &fsg_fs_bulk_in_desc, &fsg_hs_bulk_in_desc);
        if ((rc = enable_endpoint(fsg, fsg->bulk_in, d)) != 0)
                goto reset;
        fsg->bulk_in_enabled = 1;
 
-       d = ep_desc(fsg->gadget, &fs_bulk_out_desc, &hs_bulk_out_desc);
+       d = fsg_ep_desc(fsg->gadget,
+                       &fsg_fs_bulk_out_desc, &fsg_hs_bulk_out_desc);
        if ((rc = enable_endpoint(fsg, fsg->bulk_out, d)) != 0)
                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);
+               d = fsg_ep_desc(fsg->gadget,
+                               &fsg_fs_intr_in_desc, &fsg_hs_intr_in_desc);
                if ((rc = enable_endpoint(fsg, fsg->intr_in, d)) != 0)
                        goto reset;
                fsg->intr_in_enabled = 1;
        }
 
        /* Allocate the requests */
-       for (i = 0; i < NUM_BUFFERS; ++i) {
+       for (i = 0; i < FSG_NUM_BUFFERS; ++i) {
                struct fsg_buffhd       *bh = &fsg->buffhds[i];
 
                if ((rc = alloc_request(fsg, fsg->bulk_in, &bh->inreq)) != 0)
@@ -3179,7 +2831,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;
@@ -3248,15 +2899,14 @@ static void handle_exception(struct fsg_dev *fsg)
        struct fsg_buffhd       *bh;
        enum fsg_state          old_state;
        u8                      new_config;
-       struct lun              *curlun;
+       struct fsg_lun          *curlun;
        unsigned int            exception_req_tag;
        int                     rc;
 
        /* 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) {
@@ -3269,7 +2919,7 @@ static void handle_exception(struct fsg_dev *fsg)
        /* Cancel all the pending transfers */
        if (fsg->intreq_busy)
                usb_ep_dequeue(fsg->intr_in, fsg->intreq);
-       for (i = 0; i < NUM_BUFFERS; ++i) {
+       for (i = 0; i < FSG_NUM_BUFFERS; ++i) {
                bh = &fsg->buffhds[i];
                if (bh->inreq_busy)
                        usb_ep_dequeue(fsg->bulk_in, bh->inreq);
@@ -3280,7 +2930,7 @@ static void handle_exception(struct fsg_dev *fsg)
        /* Wait until everything is idle */
        for (;;) {
                num_active = fsg->intreq_busy;
-               for (i = 0; i < NUM_BUFFERS; ++i) {
+               for (i = 0; i < FSG_NUM_BUFFERS; ++i) {
                        bh = &fsg->buffhds[i];
                        num_active += bh->inreq_busy + bh->outreq_busy;
                }
@@ -3302,7 +2952,7 @@ static void handle_exception(struct fsg_dev *fsg)
         * state, and the exception.  Then invoke the handler. */
        spin_lock_irq(&fsg->lock);
 
-       for (i = 0; i < NUM_BUFFERS; ++i) {
+       for (i = 0; i < FSG_NUM_BUFFERS; ++i) {
                bh = &fsg->buffhds[i];
                bh->state = BUF_STATE_EMPTY;
        }
@@ -3322,6 +2972,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;
        }
@@ -3344,11 +2995,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,7 +3033,8 @@ static void handle_exception(struct fsg_dev *fsg)
                break;
 
        case FSG_STATE_DISCONNECT:
-               fsync_all(fsg);
+               for (i = 0; i < fsg->nluns; ++i)
+                       fsg_lun_fsync_sub(fsg->luns + i);
                do_set_config(fsg, 0);          // Unconfigured state
                break;
 
@@ -3404,14 +3053,17 @@ static void handle_exception(struct fsg_dev *fsg)
 
 static int fsg_main_thread(void *fsg_)
 {
-       struct fsg_dev          *fsg = (struct fsg_dev *) fsg_;
+       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
@@ -3459,12 +3111,10 @@ static int fsg_main_thread(void *fsg_)
        fsg->thread_task = NULL;
        spin_unlock_irq(&fsg->lock);
 
-       /* In case we are exiting because of a signal, unregister the
-        * gadget driver and close the backing file. */
-       if (test_and_clear_bit(REGISTERED, &fsg->atomic_bitflags)) {
+       /* If we are exiting because of a signal, unregister the
+        * gadget driver. */
+       if (test_and_clear_bit(REGISTERED, &fsg->atomic_bitflags))
                usb_gadget_unregister_driver(&fsg_driver);
-               close_all_backing_files(fsg);
-       }
 
        /* Let the unbind and cleanup routines know the thread has exited */
        complete_and_exit(&fsg->thread_notifier, 0);
@@ -3473,195 +3123,10 @@ static int fsg_main_thread(void *fsg_)
 
 /*-------------------------------------------------------------------------*/
 
-/* If the next two routines are called while the gadget is registered,
- * the caller must own fsg->filesem for writing. */
-
-static int open_backing_file(struct lun *curlun, const char *filename)
-{
-       int                             ro;
-       struct file                     *filp = NULL;
-       int                             rc = -EINVAL;
-       struct inode                    *inode = NULL;
-       loff_t                          size;
-       loff_t                          num_sectors;
-
-       /* R/W if we can, R/O if we must */
-       ro = curlun->ro;
-       if (!ro) {
-               filp = filp_open(filename, O_RDWR | O_LARGEFILE, 0);
-               if (-EROFS == PTR_ERR(filp))
-                       ro = 1;
-       }
-       if (ro)
-               filp = filp_open(filename, O_RDONLY | O_LARGEFILE, 0);
-       if (IS_ERR(filp)) {
-               LINFO(curlun, "unable to open backing file: %s\n", filename);
-               return PTR_ERR(filp);
-       }
-
-       if (!(filp->f_mode & FMODE_WRITE))
-               ro = 1;
-
-       if (filp->f_dentry)
-               inode = filp->f_dentry->d_inode;
-       if (inode && S_ISBLK(inode->i_mode)) {
-               if (bdev_read_only(inode->i_bdev))
-                       ro = 1;
-       } else if (!inode || !S_ISREG(inode->i_mode)) {
-               LINFO(curlun, "invalid file type: %s\n", filename);
-               goto out;
-       }
-
-       /* If we can't read the file, it's no good.
-        * If we can't write the file, use it read-only. */
-       if (!filp->f_op || !(filp->f_op->read || filp->f_op->aio_read)) {
-               LINFO(curlun, "file not readable: %s\n", filename);
-               goto out;
-       }
-       if (!(filp->f_op->write || filp->f_op->aio_write))
-               ro = 1;
-
-       size = i_size_read(inode->i_mapping->host);
-       if (size < 0) {
-               LINFO(curlun, "unable to find file size: %s\n", filename);
-               rc = (int) size;
-               goto out;
-       }
-       num_sectors = size >> 9;        // File size in 512-byte sectors
-       if (num_sectors == 0) {
-               LINFO(curlun, "file too small: %s\n", filename);
-               rc = -ETOOSMALL;
-               goto out;
-       }
-
-       get_file(filp);
-       curlun->ro = ro;
-       curlun->filp = filp;
-       curlun->file_length = size;
-       curlun->num_sectors = num_sectors;
-       LDBG(curlun, "open backing file: %s\n", filename);
-       rc = 0;
-
-out:
-       filp_close(filp, current->files);
-       return rc;
-}
-
-
-static void close_backing_file(struct lun *curlun)
-{
-       if (curlun->filp) {
-               LDBG(curlun, "close backing file\n");
-               fput(curlun->filp);
-               curlun->filp = NULL;
-       }
-}
-
-static void close_all_backing_files(struct fsg_dev *fsg)
-{
-       int     i;
-
-       for (i = 0; i < fsg->nluns; ++i)
-               close_backing_file(&fsg->luns[i]);
-}
-
-
-static ssize_t show_ro(struct device *dev, struct device_attribute *attr, char *buf)
-{
-       struct lun      *curlun = dev_to_lun(dev);
-
-       return sprintf(buf, "%d\n", curlun->ro);
-}
-
-static ssize_t show_file(struct device *dev, struct device_attribute *attr, char *buf)
-{
-       struct lun      *curlun = dev_to_lun(dev);
-       struct fsg_dev  *fsg = (struct fsg_dev *) 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);
-               if (IS_ERR(p))
-                       rc = PTR_ERR(p);
-               else {
-                       rc = strlen(p);
-                       memmove(buf, p, rc);
-                       buf[rc] = '\n';         // Add a newline
-                       buf[++rc] = 0;
-               }
-       } else {                                // No file, return 0 bytes
-               *buf = 0;
-               rc = 0;
-       }
-       up_read(&fsg->filesem);
-       return rc;
-}
-
-
-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);
-       int             i;
-
-       if (sscanf(buf, "%d", &i) != 1)
-               return -EINVAL;
-
-       /* Allow the write-enable status to change only while the backing file
-        * is closed. */
-       down_read(&fsg->filesem);
-       if (backing_file_is_open(curlun)) {
-               LDBG(curlun, "read-only status change prevented\n");
-               rc = -EBUSY;
-       } else {
-               curlun->ro = !!i;
-               LDBG(curlun, "read-only status set to %d\n", curlun->ro);
-       }
-       up_read(&fsg->filesem);
-       return rc;
-}
-
-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);
-       int             rc = 0;
-
-       if (curlun->prevent_medium_removal && backing_file_is_open(curlun)) {
-               LDBG(curlun, "eject attempt prevented\n");
-               return -EBUSY;                          // "Door is locked"
-       }
-
-       /* Remove a trailing newline */
-       if (count > 0 && buf[count-1] == '\n')
-               ((char *) buf)[count-1] = 0;            // Ugh!
-
-       /* Eject current medium */
-       down_write(&fsg->filesem);
-       if (backing_file_is_open(curlun)) {
-               close_backing_file(curlun);
-               curlun->unit_attention_data = SS_MEDIUM_NOT_PRESENT;
-       }
-
-       /* Load new medium */
-       if (count > 0 && buf[0]) {
-               rc = open_backing_file(curlun, buf);
-               if (rc == 0)
-                       curlun->unit_attention_data =
-                                       SS_NOT_READY_TO_READY_TRANSITION;
-       }
-       up_write(&fsg->filesem);
-       return (rc < 0 ? rc : count);
-}
-
 
 /* The write permissions and store_xxx pointers are set in fsg_bind() */
-static DEVICE_ATTR(ro, 0444, show_ro, NULL);
-static DEVICE_ATTR(file, 0444, show_file, NULL);
+static DEVICE_ATTR(ro, 0444, fsg_show_ro, NULL);
+static DEVICE_ATTR(file, 0444, fsg_show_file, NULL);
 
 
 /*-------------------------------------------------------------------------*/
@@ -3676,16 +3141,18 @@ static void fsg_release(struct kref *ref)
 
 static void lun_release(struct device *dev)
 {
-       struct fsg_dev  *fsg = (struct fsg_dev *) dev_get_drvdata(dev);
+       struct rw_semaphore     *filesem = dev_get_drvdata(dev);
+       struct fsg_dev          *fsg =
+               container_of(filesem, struct fsg_dev, filesem);
 
        kref_put(&fsg->ref, fsg_release);
 }
 
-static void __exit 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;
-       struct lun              *curlun;
+       struct fsg_lun          *curlun;
        struct usb_request      *req = fsg->ep0req;
 
        DBG(fsg, "unbind\n");
@@ -3697,6 +3164,7 @@ static void __exit fsg_unbind(struct usb_gadget *gadget)
                if (curlun->registered) {
                        device_remove_file(&curlun->dev, &dev_attr_ro);
                        device_remove_file(&curlun->dev, &dev_attr_file);
+                       fsg_lun_close(curlun);
                        device_unregister(&curlun->dev);
                        curlun->registered = 0;
                }
@@ -3712,19 +3180,12 @@ static void __exit 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 < FSG_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);
        }
 
@@ -3743,19 +3204,19 @@ 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_at91(fsg->gadget))
                mod_data.can_stall = 0;
 
        if (mod_data.release == 0xffff) {       // Parameter wasn't set
-               /* The sa1100 controller is not supported */
-               if (gadget_is_sa1100(fsg->gadget))
-                       gcnum = -1;
-               else
-                       gcnum = usb_gadget_controller_number(fsg->gadget);
+               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;
                }
@@ -3822,7 +3283,7 @@ static int __init fsg_bind(struct usb_gadget *gadget)
        struct fsg_dev          *fsg = the_fsg;
        int                     rc;
        int                     i;
-       struct lun              *curlun;
+       struct fsg_lun          *curlun;
        struct usb_ep           *ep;
        struct usb_request      *req;
        char                    *pathbuf, *p;
@@ -3836,16 +3297,19 @@ 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.store = store_file;
+               dev_attr_file.attr.mode = 0644;
+               dev_attr_file.store = fsg_store_file;
+               if (!mod_data.cdrom) {
+                       dev_attr_ro.attr.mode = 0644;
+                       dev_attr_ro.store = fsg_store_ro;
+               }
        }
 
        /* Find out how many LUNs there should be */
        i = mod_data.nluns;
        if (i == 0)
-               i = max(mod_data.num_filenames, 1);
-       if (i > MAX_LUNS) {
+               i = max(mod_data.num_filenames, 1u);
+       if (i > FSG_MAX_LUNS) {
                ERROR(fsg, "invalid number of LUNs: %d\n", i);
                rc = -EINVAL;
                goto out;
@@ -3853,7 +3317,7 @@ 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 = kzalloc(i * sizeof(struct lun), GFP_KERNEL);
+       fsg->luns = kzalloc(i * sizeof(struct fsg_lun), GFP_KERNEL);
        if (!fsg->luns) {
                rc = -ENOMEM;
                goto out;
@@ -3862,25 +3326,34 @@ static int __init fsg_bind(struct usb_gadget *gadget)
 
        for (i = 0; i < fsg->nluns; ++i) {
                curlun = &fsg->luns[i];
-               curlun->ro = ro[i];
+               curlun->cdrom = !!mod_data.cdrom;
+               curlun->ro = mod_data.cdrom || mod_data.ro[i];
+               curlun->initially_ro = curlun->ro;
+               curlun->removable = mod_data.removable;
+               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_drvdata(&curlun->dev, &fsg->filesem);
+               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);
-                       kref_get(&fsg->ref);
+                       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 = fsg_lun_open(curlun,
+                                       mod_data.file[i])) != 0)
                                goto out;
                } else if (!mod_data.removable) {
                        ERROR(fsg, "no file given for LUN%d\n", i);
@@ -3891,20 +3364,20 @@ static int __init fsg_bind(struct usb_gadget *gadget)
 
        /* Find all the endpoints we will use */
        usb_ep_autoconfig_reset(gadget);
-       ep = usb_ep_autoconfig(gadget, &fs_bulk_in_desc);
+       ep = usb_ep_autoconfig(gadget, &fsg_fs_bulk_in_desc);
        if (!ep)
                goto autoconf_fail;
        ep->driver_data = fsg;          // claim the endpoint
        fsg->bulk_in = ep;
 
-       ep = usb_ep_autoconfig(gadget, &fs_bulk_out_desc);
+       ep = usb_ep_autoconfig(gadget, &fsg_fs_bulk_out_desc);
        if (!ep)
                goto autoconf_fail;
        ep->driver_data = fsg;          // claim the endpoint
        fsg->bulk_out = ep;
 
        if (transport_is_cbi()) {
-               ep = usb_ep_autoconfig(gadget, &fs_intr_in_desc);
+               ep = usb_ep_autoconfig(gadget, &fsg_fs_intr_in_desc);
                if (!ep)
                        goto autoconf_fail;
                ep->driver_data = fsg;          // claim the endpoint
@@ -3918,67 +3391,70 @@ static int __init fsg_bind(struct usb_gadget *gadget)
        device_desc.bcdDevice = cpu_to_le16(mod_data.release);
 
        i = (transport_is_cbi() ? 3 : 2);       // Number of endpoints
-       intf_desc.bNumEndpoints = i;
-       intf_desc.bInterfaceSubClass = mod_data.protocol_type;
-       intf_desc.bInterfaceProtocol = mod_data.transport_type;
-       fs_function[i + FS_FUNCTION_PRE_EP_ENTRIES] = NULL;
+       fsg_intf_desc.bNumEndpoints = i;
+       fsg_intf_desc.bInterfaceSubClass = mod_data.protocol_type;
+       fsg_intf_desc.bInterfaceProtocol = mod_data.transport_type;
+       fsg_fs_function[i + FSG_FS_FUNCTION_PRE_EP_ENTRIES] = NULL;
 
-#ifdef CONFIG_USB_GADGET_DUALSPEED
-       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;
+       if (gadget_is_dualspeed(gadget)) {
+               fsg_hs_function[i + FSG_HS_FUNCTION_PRE_EP_ENTRIES] = NULL;
 
-       /* 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
+               /* Assume ep0 uses the same maxpacket value for both speeds */
+               dev_qualifier.bMaxPacketSize0 = fsg->ep0->maxpacket;
 
-       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 */
+               fsg_hs_bulk_in_desc.bEndpointAddress =
+                       fsg_fs_bulk_in_desc.bEndpointAddress;
+               fsg_hs_bulk_out_desc.bEndpointAddress =
+                       fsg_fs_bulk_out_desc.bEndpointAddress;
+               fsg_hs_intr_in_desc.bEndpointAddress =
+                       fsg_fs_intr_in_desc.bEndpointAddress;
        }
 
+       if (gadget_is_otg(gadget))
+               fsg_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;
 
        /* Allocate the data buffers */
-       for (i = 0; i < NUM_BUFFERS; ++i) {
+       for (i = 0; i < FSG_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;
        }
-       fsg->buffhds[NUM_BUFFERS - 1].next = &fsg->buffhds[0];
+       fsg->buffhds[FSG_NUM_BUFFERS - 1].next = &fsg->buffhds[0];
 
        /* This should reflect the actual gadget power source */
        usb_gadget_set_selfpowered(gadget);
 
-       snprintf(manufacturer, sizeof manufacturer, "%s %s with %s",
-                       system_utsname.sysname, system_utsname.release,
+       snprintf(fsg_string_manufacturer, sizeof fsg_string_manufacturer,
+                       "%s %s with %s",
+                       init_utsname()->sysname, init_utsname()->release,
                        gadget->name);
 
        /* On a real device, serial[] would be loaded from permanent
         * storage.  We just encode it from the driver version string. */
-       for (i = 0; i < sizeof(serial) - 2; i += 2) {
+       for (i = 0; i < sizeof fsg_string_serial - 2; i += 2) {
                unsigned char           c = DRIVER_VERSION[i / 2];
 
                if (!c)
                        break;
-               sprintf(&serial[i], "%02X", c);
+               sprintf(&fsg_string_serial[i], "%02X", c);
        }
 
        fsg->thread_task = kthread_create(fsg_main_thread, fsg,
@@ -3994,12 +3470,11 @@ static int __init fsg_bind(struct usb_gadget *gadget)
        pathbuf = kmalloc(PATH_MAX, GFP_KERNEL);
        for (i = 0; i < fsg->nluns; ++i) {
                curlun = &fsg->luns[i];
-               if (backing_file_is_open(curlun)) {
+               if (fsg_lun_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;
                        }
@@ -4015,10 +3490,10 @@ 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_task->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);
 
@@ -4033,7 +3508,7 @@ autoconf_fail:
 out:
        fsg->state = FSG_STATE_TERMINATED;      // The thread is dead
        fsg_unbind(gadget);
-       close_all_backing_files(fsg);
+       complete(&fsg->thread_notifier);
        return rc;
 }
 
@@ -4065,16 +3540,16 @@ static struct usb_gadget_driver         fsg_driver = {
 #else
        .speed          = USB_SPEED_FULL,
 #endif
-       .function       = (char *) longname,
+       .function       = (char *) fsg_string_product,
        .bind           = fsg_bind,
-       .unbind         = __exit_p(fsg_unbind),
+       .unbind         = fsg_unbind,
        .disconnect     = fsg_disconnect,
        .setup          = fsg_setup,
        .suspend        = fsg_suspend,
        .resume         = fsg_resume,
 
        .driver         = {
-               .name           = (char *) shortname,
+               .name           = DRIVER_NAME,
                .owner          = THIS_MODULE,
                // .release = ...
                // .suspend = ...
@@ -4126,7 +3601,6 @@ static void __exit fsg_cleanup(void)
        /* Wait for the thread to finish up */
        wait_for_completion(&fsg->thread_notifier);
 
-       close_all_backing_files(fsg);
        kref_put(&fsg->ref, fsg_release);
 }
 module_exit(fsg_cleanup);