Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux...
[linux-2.6.git] / drivers / usb / gadget / file_storage.c
index 5e14dbaf65bc4e7c20d2340f0167c621f7b8aa5e..29dfb0277ffbf5c9d6adcd80d2b68b274401c17d 100644 (file)
 #include <linux/freezer.h>
 #include <linux/utsname.h>
 
-#include <asm/unaligned.h>
-
 #include <linux/usb/ch9.h>
 #include <linux/usb/gadget.h>
 
 #define DRIVER_NAME            "g_file_storage"
 #define DRIVER_VERSION         "20 November 2008"
 
-static const char longname[] = DRIVER_DESC;
-static const char shortname[] = DRIVER_NAME;
+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"
+
 
 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
@@ -298,54 +295,12 @@ MODULE_LICENSE("Dual BSD/GPL");
 
 /*-------------------------------------------------------------------------*/
 
-#define LDBG(lun,fmt,args...) \
-       dev_dbg(&(lun)->dev , fmt , ## args)
-#define MDBG(fmt,args...) \
-       pr_debug(DRIVER_NAME ": " fmt , ## args)
-
-#ifndef DEBUG
-#undef VERBOSE_DEBUG
-#undef DUMP_MSGS
-#endif /* !DEBUG */
-
-#ifdef VERBOSE_DEBUG
-#define VLDBG  LDBG
-#else
-#define VLDBG(lun,fmt,args...) \
-       do { } while (0)
-#endif /* VERBOSE_DEBUG */
-
-#define LERROR(lun,fmt,args...) \
-       dev_err(&(lun)->dev , fmt , ## args)
-#define LWARN(lun,fmt,args...) \
-       dev_warn(&(lun)->dev , fmt , ## args)
-#define LINFO(lun,fmt,args...) \
-       dev_info(&(lun)->dev , fmt , ## args)
-
-#define MINFO(fmt,args...) \
-       pr_info(DRIVER_NAME ": " fmt , ## args)
-
-#define DBG(d, fmt, args...) \
-       dev_dbg(&(d)->gadget->dev , fmt , ## args)
-#define VDBG(d, fmt, args...) \
-       dev_vdbg(&(d)->gadget->dev , fmt , ## args)
-#define ERROR(d, fmt, args...) \
-       dev_err(&(d)->gadget->dev , fmt , ## args)
-#define WARNING(d, fmt, args...) \
-       dev_warn(&(d)->gadget->dev , fmt , ## args)
-#define INFO(d, fmt, args...) \
-       dev_info(&(d)->gadget->dev , fmt , ## args)
-
-
-/*-------------------------------------------------------------------------*/
 
 /* Encapsulate the module parameter settings */
 
-#define MAX_LUNS       8
-
 static struct {
-       char            *file[MAX_LUNS];
-       int             ro[MAX_LUNS];
+       char            *file[FSG_MAX_LUNS];
+       int             ro[FSG_MAX_LUNS];
        unsigned int    num_filenames;
        unsigned int    num_ros;
        unsigned int    nluns;
@@ -372,8 +327,8 @@ static struct {
        .removable              = 0,
        .can_stall              = 1,
        .cdrom                  = 0,
-       .vendor                 = DRIVER_VENDOR_ID,
-       .product                = DRIVER_PRODUCT_ID,
+       .vendor                 = FSG_VENDOR_ID,
+       .product                = FSG_PRODUCT_ID,
        .release                = 0xffff,       // Use controller chip type
        .buflen                 = 16384,
        };
@@ -425,125 +380,6 @@ MODULE_PARM_DESC(buflen, "I/O buffer size");
 #endif /* CONFIG_USB_FILE_STORAGE_TEST */
 
 
-/*-------------------------------------------------------------------------*/
-
-/* SCSI device types */
-#define TYPE_DISK      0x00
-#define TYPE_CDROM     0x05
-
-/* USB protocol value = the transport method */
-#define USB_PR_CBI     0x00            // Control/Bulk/Interrupt
-#define USB_PR_CB      0x01            // Control/Bulk w/o interrupt
-#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_READ_HEADER                 0x44
-#define SC_READ_TOC                    0x43
-#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
@@ -566,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;
-       unsigned int    info_valid : 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 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;
-       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 */
@@ -662,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;
 
@@ -687,7 +450,7 @@ 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;
@@ -712,8 +475,8 @@ 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 *);
@@ -739,49 +502,9 @@ static void 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);
-
 
 /*-------------------------------------------------------------------------*/
 
-#ifdef DUMP_MSGS
-
-static void dump_msg(struct fsg_dev *fsg, const char *label,
-               const u8 *buf, unsigned int length)
-{
-       if (length < 512) {
-               DBG(fsg, "%s, length %u:\n", label, length);
-               print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET,
-                               16, 1, buf, length, 0);
-       }
-}
-
-static void dump_cdb(struct fsg_dev *fsg)
-{}
-
-#else
-
-static void dump_msg(struct fsg_dev *fsg, const char *label,
-               const u8 *buf, unsigned int length)
-{}
-
-#ifdef VERBOSE_DEBUG
-
-static void dump_cdb(struct fsg_dev *fsg)
-{
-       print_hex_dump(KERN_DEBUG, "SCSI CDB: ", DUMP_PREFIX_NONE,
-                       16, 1, fsg->cmnd, fsg->cmnd_size, 0);
-}
-
-#else
-
-static void dump_cdb(struct fsg_dev *fsg)
-{}
-
-#endif /* VERBOSE_DEBUG */
-#endif /* DUMP_MSGS */
-
-
 static int fsg_set_halt(struct fsg_dev *fsg, struct usb_ep *ep)
 {
        const char      *name;
@@ -797,16 +520,6 @@ static int fsg_set_halt(struct fsg_dev *fsg, struct usb_ep *ep)
 }
 
 
-/*-------------------------------------------------------------------------*/
-
-/* Routines for unaligned data access */
-
-static u32 get_unaligned_be24(u8 *buf)
-{
-       return 0xffffff & (u32) get_unaligned_be32(buf - 1);
-}
-
-
 /*-------------------------------------------------------------------------*/
 
 /*
@@ -814,11 +527,6 @@ static u32 get_unaligned_be24(u8 *buf)
  * 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
@@ -832,13 +540,13 @@ device_desc = {
        .bDeviceClass =         USB_CLASS_PER_INTERFACE,
 
        /* The next three values can be overridden by module parameters */
-       .idVendor =             cpu_to_le16(DRIVER_VENDOR_ID),
-       .idProduct =            cpu_to_le16(DRIVER_PRODUCT_ID),
+       .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,
 };
 
@@ -850,86 +558,12 @@ 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 =            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 =       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
-
-
-/*
- * 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,
@@ -941,78 +575,6 @@ dev_qualifier = {
        .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 =       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 =       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 =       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. */
-static struct usb_endpoint_descriptor *
-ep_desc(struct usb_gadget *g, struct usb_endpoint_descriptor *fs,
-               struct usb_endpoint_descriptor *hs)
-{
-       if (gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH)
-               return hs;
-       return fs;
-}
-
-
-/* The CBI specification limits the serial string to 12 uppercase hexadecimal
- * 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,
-};
 
 
 /*
@@ -1032,10 +594,9 @@ static int populate_config_buf(struct usb_gadget *gadget,
 
        if (gadget_is_dualspeed(gadget) && type == USB_DT_OTHER_SPEED_CONFIG)
                speed = (USB_SPEED_FULL + USB_SPEED_HIGH) - speed;
-       if (gadget_is_dualspeed(gadget) && speed == USB_SPEED_HIGH)
-               function = hs_function;
-       else
-               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(gadget))
@@ -1386,7 +947,7 @@ get_config:
                        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;
                }
@@ -1551,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;
@@ -1677,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;
@@ -1864,33 +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;
-
-       if (curlun->ro || !filp)
-               return 0;
-       return vfs_fsync(filp, filp->f_path.dentry, 1);
-}
-
-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;
@@ -1899,7 +1441,7 @@ 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_path.dentry->d_inode;
@@ -1911,7 +1453,7 @@ static void invalidate_sub(struct lun *curlun)
 
 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;
@@ -1944,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;
 
@@ -2041,7 +1583,7 @@ 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;
@@ -2095,7 +1637,7 @@ 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;
+       struct fsg_lun  *curlun = fsg->curlun;
        u32             lba = get_unaligned_be32(&fsg->cmnd[2]);
        int             pmi = fsg->cmnd[8];
        u8              *buf = (u8 *) bh->buf;
@@ -2113,27 +1655,9 @@ static int do_read_capacity(struct fsg_dev *fsg, struct fsg_buffhd *bh)
 }
 
 
-static void store_cdrom_address(u8 *dest, int msf, u32 addr)
-{
-       if (msf) {
-               /* Convert to Minutes-Seconds-Frames */
-               addr >>= 2;             /* Convert to 2048-byte frames */
-               addr += 2*75;           /* Lead-in occupies 2 seconds */
-               dest[3] = addr % 75;    /* Frames */
-               addr /= 75;
-               dest[2] = addr % 60;    /* Seconds */
-               addr /= 60;
-               dest[1] = addr;         /* Minutes */
-               dest[0] = 0;            /* Reserved */
-       } else {
-               /* Absolute sector */
-               put_unaligned_be32(addr, dest);
-       }
-}
-
 static int do_read_header(struct fsg_dev *fsg, struct fsg_buffhd *bh)
 {
-       struct lun      *curlun = fsg->curlun;
+       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;
@@ -2156,7 +1680,7 @@ static int do_read_header(struct fsg_dev *fsg, struct fsg_buffhd *bh)
 
 static int do_read_toc(struct fsg_dev *fsg, struct fsg_buffhd *bh)
 {
-       struct lun      *curlun = fsg->curlun;
+       struct fsg_lun  *curlun = fsg->curlun;
        int             msf = fsg->cmnd[1] & 0x02;
        int             start_track = fsg->cmnd[6];
        u8              *buf = (u8 *) bh->buf;
@@ -2184,7 +1708,7 @@ static int do_read_toc(struct fsg_dev *fsg, struct fsg_buffhd *bh)
 
 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;
@@ -2265,7 +1789,7 @@ static int do_mode_sense(struct fsg_dev *fsg, struct fsg_buffhd *bh)
 
 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) {
@@ -2295,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);
                }
@@ -2303,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;
                }
@@ -2315,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) {
@@ -2330,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;
 }
@@ -2339,7 +1863,7 @@ 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;
@@ -2356,7 +1880,7 @@ static int do_read_format_capacities(struct fsg_dev *fsg,
 
 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;
@@ -2599,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;
@@ -2691,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. */
@@ -2820,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;
        }
@@ -3075,8 +2599,8 @@ 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 = req->buf;
+       struct usb_request              *req = bh->outreq;
+       struct fsg_bulk_cb_wrap *cbw = req->buf;
 
        /* Was this a real packet?  Should it be ignored? */
        if (req->status || test_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags))
@@ -3105,7 +2629,7 @@ static int received_cbw(struct fsg_dev *fsg, struct fsg_buffhd *bh)
        }
 
        /* Is the CBW meaningful? */
-       if (cbw->Lun >= MAX_LUNS || cbw->Flags & ~USB_BULK_IN_FLAG ||
+       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",
@@ -3238,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) {
@@ -3276,12 +2800,14 @@ 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;
@@ -3289,14 +2815,15 @@ reset:
        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)
@@ -3372,7 +2899,7 @@ 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;
 
@@ -3392,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);
@@ -3403,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;
                }
@@ -3425,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;
        }
@@ -3506,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;
 
@@ -3595,201 +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;
-       loff_t                          min_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_path.dentry)
-               inode = filp->f_path.dentry->d_inode;
-       if (inode && S_ISBLK(inode->i_mode)) {
-               if (bdev_read_only(inode->i_bdev))
-                       ro = 1;
-       } 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 blocks
-       min_sectors = 1;
-       if (mod_data.cdrom) {
-               num_sectors &= ~3;      // Reduce to a multiple of 2048
-               min_sectors = 300*4;    // Smallest track is 300 frames
-               if (num_sectors >= 256*60*75*4) {
-                       num_sectors = (256*60*75 - 1) * 4;
-                       LINFO(curlun, "file too big: %s\n", filename);
-                       LINFO(curlun, "using only first %d blocks\n",
-                                       (int) num_sectors);
-               }
-       }
-       if (num_sectors < min_sectors) {
-               LINFO(curlun, "file too small: %s\n", filename);
-               rc = -ETOOSMALL;
-               goto out;
-       }
-
-       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 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 = 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_path, 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 = 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 = 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);
 
 
 /*-------------------------------------------------------------------------*/
@@ -3804,7 +3141,9 @@ static void fsg_release(struct kref *ref)
 
 static void lun_release(struct device *dev)
 {
-       struct fsg_dev  *fsg = 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);
 }
@@ -3813,7 +3152,7 @@ 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");
@@ -3825,7 +3164,7 @@ static void /* __init_or_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);
-                       close_backing_file(curlun);
+                       fsg_lun_close(curlun);
                        device_unregister(&curlun->dev);
                        curlun->registered = 0;
                }
@@ -3841,7 +3180,7 @@ static void /* __init_or_exit */ fsg_unbind(struct usb_gadget *gadget)
        }
 
        /* Free the data buffers */
-       for (i = 0; i < NUM_BUFFERS; ++i)
+       for (i = 0; i < FSG_NUM_BUFFERS; ++i)
                kfree(fsg->buffhds[i].buf);
 
        /* Free the request and buffer for endpoint 0 */
@@ -3948,7 +3287,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;
@@ -3963,10 +3302,10 @@ static int __init fsg_bind(struct usb_gadget *gadget)
 
        if (mod_data.removable) {       // Enable the store_xxx attributes
                dev_attr_file.attr.mode = 0644;
-               dev_attr_file.store = store_file;
+               dev_attr_file.store = fsg_store_file;
                if (!mod_data.cdrom) {
                        dev_attr_ro.attr.mode = 0644;
-                       dev_attr_ro.store = store_ro;
+                       dev_attr_ro.store = fsg_store_ro;
                }
        }
 
@@ -3974,7 +3313,7 @@ static int __init fsg_bind(struct usb_gadget *gadget)
        i = mod_data.nluns;
        if (i == 0)
                i = max(mod_data.num_filenames, 1u);
-       if (i > MAX_LUNS) {
+       if (i > FSG_MAX_LUNS) {
                ERROR(fsg, "invalid number of LUNs: %d\n", i);
                rc = -EINVAL;
                goto out;
@@ -3982,7 +3321,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;
@@ -3991,13 +3330,14 @@ static int __init fsg_bind(struct usb_gadget *gadget)
 
        for (i = 0; i < fsg->nluns; ++i) {
                curlun = &fsg->luns[i];
-               curlun->ro = mod_data.ro[i];
-               if (mod_data.cdrom)
-                       curlun->ro = 1;
+               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);
+               dev_set_drvdata(&curlun->dev, &fsg->filesem);
                dev_set_name(&curlun->dev,"%s-lun%d",
                             dev_name(&gadget->dev), i);
 
@@ -4016,7 +3356,7 @@ static int __init fsg_bind(struct usb_gadget *gadget)
                kref_get(&fsg->ref);
 
                if (mod_data.file[i] && *mod_data.file[i]) {
-                       if ((rc = open_backing_file(curlun,
+                       if ((rc = fsg_lun_open(curlun,
                                        mod_data.file[i])) != 0)
                                goto out;
                } else if (!mod_data.removable) {
@@ -4028,20 +3368,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
@@ -4055,28 +3395,28 @@ 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;
 
        if (gadget_is_dualspeed(gadget)) {
-               hs_function[i + HS_FUNCTION_PRE_EP_ENTRIES] = NULL;
+               fsg_hs_function[i + FSG_HS_FUNCTION_PRE_EP_ENTRIES] = NULL;
 
                /* Assume ep0 uses the same maxpacket value for both speeds */
                dev_qualifier.bMaxPacketSize0 = fsg->ep0->maxpacket;
 
                /* Assume endpoint addresses are the same for both speeds */
-               hs_bulk_in_desc.bEndpointAddress =
-                               fs_bulk_in_desc.bEndpointAddress;
-               hs_bulk_out_desc.bEndpointAddress =
-                               fs_bulk_out_desc.bEndpointAddress;
-               hs_intr_in_desc.bEndpointAddress =
-                               fs_intr_in_desc.bEndpointAddress;
+               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))
-               otg_desc.bmAttributes |= USB_OTG_HNP;
+               fsg_otg_desc.bmAttributes |= USB_OTG_HNP;
 
        rc = -ENOMEM;
 
@@ -4090,7 +3430,7 @@ static int __init fsg_bind(struct usb_gadget *gadget)
        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];
 
                /* Allocate for the bulk-in endpoint.  We assume that
@@ -4101,23 +3441,24 @@ static int __init fsg_bind(struct usb_gadget *gadget)
                        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",
+       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,
@@ -4133,7 +3474,7 @@ 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_path,
@@ -4203,7 +3544,7 @@ 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         = fsg_unbind,
        .disconnect     = fsg_disconnect,
@@ -4212,7 +3553,7 @@ static struct usb_gadget_driver           fsg_driver = {
        .resume         = fsg_resume,
 
        .driver         = {
-               .name           = (char *) shortname,
+               .name           = DRIVER_NAME,
                .owner          = THIS_MODULE,
                // .release = ...
                // .suspend = ...