vserver 1.9.3
[linux-2.6.git] / drivers / usb / gadget / file_storage.c
index 9b97891..6e8008f 100644 (file)
  *
  * Backing storage is provided by a regular file or a block device, specified
  * by the "file" module parameter.  Access can be limited to read-only by
- * setting the optional "ro" module parameter.
+ * setting the optional "ro" module parameter.  The gadget will indicate that
+ * it has removable media if the optional "removable" module parameter is set.
  *
  * The gadget supports the Control-Bulk (CB), Control-Bulk-Interrupt (CBI),
  * and Bulk-Only (also known as Bulk-Bulk-Bulk or BBB) transports, selected
  * by the optional "transport" module parameter.  It also supports the
  * following protocols: RBC (0x01), ATAPI or SFF-8020i (0x02), QIC-157 (0c03),
  * UFI (0x04), SFF-8070i (0x05), and transparent SCSI (0x06), selected by
- * the optional "protocol" module parameter.  For testing purposes the
- * gadget will indicate that it has removable media if the optional
- * "removable" module parameter is set.  In addition, the default Vendor ID,
- * Product ID, and release number can be overridden.
+ * the optional "protocol" module parameter.  In addition, the default
+ * Vendor ID, Product ID, and release number can be overridden.
  *
  * There is support for multiple logical units (LUNs), each of which has
  * its own backing file.  The number of LUNs can be set using the optional
  *                                     the files or block devices used for
  *                                     backing storage
  *     ro=b[,b...]             Default false, booleans for read-only access
+ *     removable               Default false, boolean for removable media
  *     luns=N                  Default N = number of filenames, number of
  *                                     LUNs to support
  *     transport=XXX           Default BBB, transport name (CB, CBI, or BBB)
  *     protocol=YYY            Default SCSI, protocol name (RBC, 8020 or
  *                                     ATAPI, QIC, UFI, 8070, or SCSI;
  *                                     also 1 - 6)
- *     removable               Default false, boolean for removable media
  *     vendor=0xVVVV           Default 0x0525 (NetChip), USB Vendor ID
  *     product=0xPPPP          Default 0xa4a5 (FSG), USB Product ID
  *     release=0xRRRR          Override the USB release number (bcdDevice)
  *                                     boolean to permit the driver to halt
  *                                     bulk endpoints
  *
- * If CONFIG_USB_FILE_STORAGE_TEST is not set, only the "file" and "ro"
- * options are available; default values are used for everything else.
+ * If CONFIG_USB_FILE_STORAGE_TEST is not set, only the "file", "ro",
+ * "removable", and "luns" options are available; default values are used
+ * for everything else.
  *
  * The pathnames of the backing files and the ro settings are available in
  * the attribute files "file" and "ro" in the lun<n> subdirectory of the
- * gadget's sysfs directory.  If CONFIG_USB_FILE_STORAGE_TEST and the
- * "removable" option are both set, writing to these files will simulate
- * ejecting/loading the medium (writing an empty line means eject) and
- * adjusting a write-enable tab.  Changes to the ro setting are not allowed
- * when the medium is loaded.
+ * gadget's sysfs directory.  If the "removable" option is set, writing to
+ * these files will simulate ejecting/loading the medium (writing an empty
+ * line means eject) and adjusting a write-enable tab.  Changes to the ro
+ * setting are not allowed when the medium is loaded.
  *
  * This gadget driver is heavily based on "Gadget Zero" by David Brownell.
  */
  * Bulk-only specification requires a stall.  In such cases the driver
  * will halt the endpoint and set a flag indicating that it should clear
  * the halt in software during the next device reset.  Hopefully this
- * will permit everything to work correctly.
+ * will permit everything to work correctly.  Furthermore, although the
+ * specification allows the bulk-out endpoint to halt when the host sends
+ * too much data, implementing this would cause an unavoidable race.
+ * The driver will always use the "no-stall" approach for OUT transfers.
  *
  * One subtle point concerns sending status-stage responses for ep0
  * requests.  Some of these requests, such as device reset, can involve
 
 #define DRIVER_DESC            "File-backed Storage Gadget"
 #define DRIVER_NAME            "g_file_storage"
-#define DRIVER_VERSION         "21 March 2004"
+#define DRIVER_VERSION         "28 July 2004"
 
 static const char longname[] = DRIVER_DESC;
 static const char shortname[] = DRIVER_NAME;
@@ -371,14 +373,17 @@ MODULE_PARM_DESC(file, "names of backing files or devices");
 module_param_array(ro, bool, mod_data.num_ros, S_IRUGO);
 MODULE_PARM_DESC(ro, "true to force read-only");
 
+module_param_named(luns, mod_data.nluns, uint, S_IRUGO);
+MODULE_PARM_DESC(luns, "number of LUNs");
 
-/* In the non-TEST version, only the file and ro module parameters
+module_param_named(removable, mod_data.removable, bool, S_IRUGO);
+MODULE_PARM_DESC(removable, "true to simulate removable media");
+
+
+/* In the non-TEST version, only the module parameters listed above
  * are available. */
 #ifdef CONFIG_USB_FILE_STORAGE_TEST
 
-module_param_named(luns, mod_data.nluns, uint, S_IRUGO);
-MODULE_PARM_DESC(luns, "number of LUNs");
-
 module_param_named(transport, mod_data.transport_parm, charp, S_IRUGO);
 MODULE_PARM_DESC(transport, "type of transport (BBB, CBI, or CB)");
 
@@ -386,9 +391,6 @@ module_param_named(protocol, mod_data.protocol_parm, charp, S_IRUGO);
 MODULE_PARM_DESC(protocol, "type of protocol (RBC, 8020, QIC, UFI, "
                "8070, or SCSI)");
 
-module_param_named(removable, mod_data.removable, bool, S_IRUGO);
-MODULE_PARM_DESC(removable, "true to simulate removable media");
-
 module_param_named(vendor, mod_data.vendor, ushort, S_IRUGO);
 MODULE_PARM_DESC(vendor, "USB Vendor ID");
 
@@ -525,11 +527,6 @@ struct interrupt_data {
  * parts of the driver that aren't used in the non-TEST version.  Even gcc
  * can recognize when a test of a constant expression yields a dead code
  * path.
- *
- * Also, in the non-TEST version, open_backing_file() is only used during
- * initialization and the sysfs attribute store_xxx routines aren't used
- * at all.  We will define NORMALLY_INIT to mark them as __init so they
- * don't occupy kernel code space unnecessarily.
  */
 
 #ifdef CONFIG_USB_FILE_STORAGE_TEST
@@ -537,16 +534,12 @@ struct interrupt_data {
 #define transport_is_bbb()     (mod_data.transport_type == USB_PR_BULK)
 #define transport_is_cbi()     (mod_data.transport_type == USB_PR_CBI)
 #define protocol_is_scsi()     (mod_data.protocol_type == USB_SC_SCSI)
-#define backing_file_is_open(curlun)   ((curlun)->filp != NULL)
-#define NORMALLY_INIT
 
 #else
 
 #define transport_is_bbb()     1
 #define transport_is_cbi()     0
 #define protocol_is_scsi()     1
-#define backing_file_is_open(curlun)   1
-#define NORMALLY_INIT          __init
 
 #endif /* CONFIG_USB_FILE_STORAGE_TEST */
 
@@ -567,6 +560,8 @@ struct lun {
        struct device   dev;
 };
 
+#define backing_file_is_open(curlun)   ((curlun)->filp != NULL)
+
 static inline struct lun *dev_to_lun(struct device *dev)
 {
        return container_of(dev, struct lun, dev);
@@ -659,6 +654,7 @@ struct fsg_dev {
        unsigned long           atomic_bitflags;
 #define REGISTERED             0
 #define CLEAR_BULK_HALTS       1
+#define SUSPENDED              2
 
        struct usb_ep           *bulk_in;
        struct usb_ep           *bulk_out;
@@ -1041,8 +1037,6 @@ static int populate_config_buf(enum usb_device_speed speed,
                function = fs_function;
 
        len = usb_gadget_config_buf(&config_desc, buf, EP0_BUFSIZE, function);
-       if (len < 0)
-               return len;
        ((struct usb_config_descriptor *) buf)->bDescriptorType = type;
        return len;
 }
@@ -1172,9 +1166,10 @@ static void bulk_out_complete(struct usb_ep *ep, struct usb_request *req)
        wakeup_thread(fsg);
 }
 
+
+#ifdef CONFIG_USB_FILE_STORAGE_TEST
 static void intr_in_complete(struct usb_ep *ep, struct usb_request *req)
 {
-#ifdef CONFIG_USB_FILE_STORAGE_TEST
        struct fsg_dev          *fsg = (struct fsg_dev *) ep->driver_data;
        struct fsg_buffhd       *bh = (struct fsg_buffhd *) req->context;
 
@@ -1190,17 +1185,21 @@ static void intr_in_complete(struct usb_ep *ep, struct usb_request *req)
        bh->state = BUF_STATE_EMPTY;
        spin_unlock(&fsg->lock);
        wakeup_thread(fsg);
-#endif /* CONFIG_USB_FILE_STORAGE_TEST */
 }
 
+#else
+static void intr_in_complete(struct usb_ep *ep, struct usb_request *req)
+{}
+#endif /* CONFIG_USB_FILE_STORAGE_TEST */
+
 
 /*-------------------------------------------------------------------------*/
 
 /* Ep0 class-specific handlers.  These always run in_irq. */
 
+#ifdef CONFIG_USB_FILE_STORAGE_TEST
 static void received_cbi_adsc(struct fsg_dev *fsg, struct fsg_buffhd *bh)
 {
-#ifdef CONFIG_USB_FILE_STORAGE_TEST
        struct usb_request      *req = fsg->ep0req;
        static u8               cbi_reset_cmnd[6] = {
                        SC_SEND_DIAGNOSTIC, 4, 0xff, 0xff, 0xff, 0xff};
@@ -1238,9 +1237,13 @@ static void received_cbi_adsc(struct fsg_dev *fsg, struct fsg_buffhd *bh)
 
        spin_unlock(&fsg->lock);
        wakeup_thread(fsg);
-#endif /* CONFIG_USB_FILE_STORAGE_TEST */
 }
 
+#else
+static void received_cbi_adsc(struct fsg_dev *fsg, struct fsg_buffhd *bh)
+{}
+#endif /* CONFIG_USB_FILE_STORAGE_TEST */
+
 
 static int class_setup_req(struct fsg_dev *fsg,
                const struct usb_ctrlrequest *ctrl)
@@ -1465,8 +1468,8 @@ static int fsg_setup(struct usb_gadget *gadget,
        /* Respond with data/status or defer until later? */
        if (rc >= 0 && rc != DELAYED_STATUS) {
                fsg->ep0req->length = rc;
-               fsg->ep0req->zero = rc < ctrl->wLength
-                               && (rc % gadget->ep0->maxpacket) == 0;
+               fsg->ep0req->zero = (rc < ctrl->wLength &&
+                               (rc % gadget->ep0->maxpacket) == 0);
                fsg->ep0req_name = (ctrl->bRequestType & USB_DIR_IN ?
                                "ep0-in" : "ep0-out");
                rc = ep0_queue(fsg);
@@ -2443,14 +2446,19 @@ static int finish_reply(struct fsg_dev *fsg)
                        rc = -EINTR;
                }
 
-               /* We haven't processed all the incoming data.  If we are
-                * allowed to stall, halt the bulk-out endpoint and cancel
-                * any outstanding requests. */
+               /* We haven't processed all the incoming data.  Even though
+                * we may be allowed to stall, doing so would cause a race.
+                * The controller may already have ACK'ed all the remaining
+                * bulk-out packets, in which case the host wouldn't see a
+                * STALL.  Not realizing the endpoint was halted, it wouldn't
+                * clear the halt -- leading to problems later on. */
+#if 0
                else if (mod_data.can_stall) {
                        fsg_set_halt(fsg, fsg->bulk_out);
                        raise_exception(fsg, FSG_STATE_ABORT_BULK_OUT);
                        rc = -EINTR;
                }
+#endif
 
                /* We can't stall.  Read in the excess data and throw it
                 * all away. */
@@ -2513,7 +2521,7 @@ static int send_status(struct fsg_dev *fsg)
 
        } else if (mod_data.transport_type == USB_PR_CB) {
 
-               /* Control-Bulk transport has no status stage! */
+               /* Control-Bulk transport has no status phase! */
                return 0;
 
        } else {                        // USB_PR_CBI
@@ -2603,8 +2611,10 @@ static int check_command(struct fsg_dev *fsg, int cmnd_size,
        fsg->residue = fsg->usb_amount_left = fsg->data_size;
 
        /* Conflicting data directions is a phase error */
-       if (fsg->data_dir != data_dir && fsg->data_size_from_cmnd > 0)
-               goto phase_error;
+       if (fsg->data_dir != data_dir && fsg->data_size_from_cmnd > 0) {
+               fsg->phase_error = 1;
+               return -EINVAL;
+       }
 
        /* Verify the length of the command itself */
        if (cmnd_size != fsg->cmnd_size) {
@@ -2613,8 +2623,10 @@ static int check_command(struct fsg_dev *fsg, int cmnd_size,
                 * with cbw->Length == 12 (it should be 6). */
                if (fsg->cmnd[0] == SC_REQUEST_SENSE && fsg->cmnd_size == 12)
                        cmnd_size = fsg->cmnd_size;
-               else
-                       goto phase_error;
+               else {
+                       fsg->phase_error = 1;
+                       return -EINVAL;
+               }
        }
 
        /* Check that the LUN values are oonsistent */
@@ -2674,10 +2686,6 @@ static int check_command(struct fsg_dev *fsg, int cmnd_size,
        }
 
        return 0;
-
-phase_error:
-       fsg->phase_error = 1;
-       return -EINVAL;
 }
 
 
@@ -3424,8 +3432,7 @@ static int fsg_main_thread(void *fsg_)
 /* If the next two routines are called while the gadget is registered,
  * the caller must own fsg->filesem for writing. */
 
-static int NORMALLY_INIT open_backing_file(struct lun *curlun,
-               const char *filename)
+static int open_backing_file(struct lun *curlun, const char *filename)
 {
        int                             ro;
        struct file                     *filp = NULL;
@@ -3550,8 +3557,7 @@ static ssize_t show_file(struct device *dev, char *buf)
 }
 
 
-ssize_t NORMALLY_INIT store_ro(struct device *dev, const char *buf,
-               size_t count)
+ssize_t store_ro(struct device *dev, const char *buf, size_t count)
 {
        ssize_t         rc = count;
        struct lun      *curlun = dev_to_lun(dev);
@@ -3575,8 +3581,7 @@ ssize_t NORMALLY_INIT store_ro(struct device *dev, const char *buf,
        return rc;
 }
 
-ssize_t NORMALLY_INIT store_file(struct device *dev, const char *buf,
-               size_t count)
+ssize_t store_file(struct device *dev, const char *buf, size_t count)
 {
        struct lun      *curlun = dev_to_lun(dev);
        struct fsg_dev  *fsg = (struct fsg_dev *) dev_get_drvdata(dev);
@@ -3708,6 +3713,8 @@ static int __init check_parameters(struct fsg_dev *fsg)
                        mod_data.release = __constant_cpu_to_le16(0x0307);
                else if (gadget_is_omap(fsg->gadget))
                        mod_data.release = __constant_cpu_to_le16(0x0308);
+               else if (gadget_is_lh7a40x(gadget))
+                       mod_data.release = __constant_cpu_to_le16 (0x0309);
                else {
                        WARN(fsg, "controller '%s' not recognized\n",
                                fsg->gadget->name);
@@ -3805,9 +3812,8 @@ static int __init fsg_bind(struct usb_gadget *gadget)
                goto out;
        }
 
-       /* Create the LUNs and open their backing files.  We can't register
-        * the LUN devices until the gadget itself is registered, which
-        * doesn't happen until after fsg_bind() returns. */
+       /* Create the LUNs, open their backing files, and register the
+        * LUN devices in sysfs. */
        fsg->luns = kmalloc(i * sizeof(struct lun), GFP_KERNEL);
        if (!fsg->luns) {
                rc = -ENOMEM;
@@ -3825,6 +3831,15 @@ static int __init fsg_bind(struct usb_gadget *gadget)
                snprintf(curlun->dev.bus_id, BUS_ID_SIZE,
                                "%s-lun%d", gadget->dev.bus_id, i);
 
+               if ((rc = device_register(&curlun->dev)) != 0)
+                       INFO(fsg, "failed to register LUN%d: %d\n", i, rc);
+               else {
+                       curlun->registered = 1;
+                       curlun->dev.release = lun_release;
+                       device_create_file(&curlun->dev, &dev_attr_ro);
+                       device_create_file(&curlun->dev, &dev_attr_file);
+               }
+
                if (file[i] && *file[i]) {
                        if ((rc = open_backing_file(curlun, file[i])) != 0)
                                goto out;
@@ -3972,6 +3987,25 @@ out:
 }
 
 
+/*-------------------------------------------------------------------------*/
+
+static void fsg_suspend(struct usb_gadget *gadget)
+{
+       struct fsg_dev          *fsg = get_gadget_data(gadget);
+
+       DBG(fsg, "suspend\n");
+       set_bit(SUSPENDED, &fsg->atomic_bitflags);
+}
+
+static void fsg_resume(struct usb_gadget *gadget)
+{
+       struct fsg_dev          *fsg = get_gadget_data(gadget);
+
+       DBG(fsg, "resume\n");
+       clear_bit(SUSPENDED, &fsg->atomic_bitflags);
+}
+
+
 /*-------------------------------------------------------------------------*/
 
 static struct usb_gadget_driver                fsg_driver = {
@@ -3985,6 +4019,8 @@ static struct usb_gadget_driver           fsg_driver = {
        .unbind         = fsg_unbind,
        .disconnect     = fsg_disconnect,
        .setup          = fsg_setup,
+       .suspend        = fsg_suspend,
+       .resume         = fsg_resume,
 
        .driver         = {
                .name           = (char *) shortname,
@@ -4024,8 +4060,6 @@ static int __init fsg_init(void)
 {
        int             rc;
        struct fsg_dev  *fsg;
-       int             i;
-       struct lun      *curlun;
 
        if ((rc = fsg_alloc()) != 0)
                return rc;
@@ -4036,19 +4070,6 @@ static int __init fsg_init(void)
        }
        set_bit(REGISTERED, &fsg->atomic_bitflags);
 
-       /* Register the LUN devices and their attribute files */
-       for (i = 0; i < fsg->nluns; ++i) {
-               curlun = &fsg->luns[i];
-               if ((rc = device_register(&curlun->dev)) != 0)
-                       INFO(fsg, "failed to register LUN%d: %d\n", i, rc);
-               else {
-                       curlun->registered = 1;
-                       curlun->dev.release = lun_release;
-                       device_create_file(&curlun->dev, &dev_attr_ro);
-                       device_create_file(&curlun->dev, &dev_attr_file);
-               }
-       }
-
        /* Tell the thread to start working */
        complete(&fsg->thread_notifier);
        return 0;