ChangeSet 1.1673.8.59, 2004/03/31 13:08:35-08:00, [EMAIL PROTECTED]

[PATCH] USB Gadget: Use configuration-buffer library in file-storage

This patch imports the config-buffer library into the file-storage gadget,
simplifying and decreasing the amount of code needed for assembling
configuration descriptors.  It also changes the driver to remove any
pretense at bus-powered operation and to use the new DUALSPEED
configuration option.  This is in line with recent changes made to other
gadget drivers.


 drivers/usb/gadget/Makefile       |    2 
 drivers/usb/gadget/file_storage.c |  198 +++++++++++++++++---------------------
 2 files changed, 92 insertions(+), 108 deletions(-)


diff -Nru a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile
--- a/drivers/usb/gadget/Makefile       Wed Apr 14 14:35:07 2004
+++ b/drivers/usb/gadget/Makefile       Wed Apr 14 14:35:07 2004
@@ -13,7 +13,7 @@
 g_ether-objs                   := ether.o usbstring.o config.o epautoconf.o
 g_serial-objs                  := serial.o usbstring.o
 gadgetfs-objs                  := inode.o
-g_file_storage-objs            := file_storage.o usbstring.o
+g_file_storage-objs            := file_storage.o usbstring.o config.o
 
 ifeq ($(CONFIG_USB_ETH_RNDIS),y)
        g_ether-objs            += rndis.o
diff -Nru a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c
--- a/drivers/usb/gadget/file_storage.c Wed Apr 14 14:35:07 2004
+++ b/drivers/usb/gadget/file_storage.c Wed Apr 14 14:35:07 2004
@@ -264,6 +264,12 @@
 /*-------------------------------------------------------------------------*/
 
 /*
+ * This driver assumes self-powered hardware and has no way for users to
+ * trigger remote wakeup.
+ */
+
+
+/*
  * Hardware-specific configuration, controlled by which device
  * controller driver was configured.
  *
@@ -273,9 +279,6 @@
  * EP_*_NUM ... numbers for them (often limited by hardware)
  * FS_BULK_IN_MAXPACKET ... maxpacket value for full-speed bulk-in ep
  * FS_BULK_OUT_MAXPACKET ... maxpacket value for full-speed bulk-out ep
- * HIGHSPEED ... define if ep0 and descriptors need high speed support
- * MAX_USB_POWER ... define if we use other than 100 mA bus current
- * SELFPOWER ... if we can run on bus power, zero
  * NO_BULK_STALL ... bulk endpoint halts don't work well so avoid them
  */
 
@@ -298,7 +301,6 @@
 #define FS_BULK_OUT_MAXPACKET  64
 static const char EP_INTR_IN_NAME[] = "ep-e";
 #define EP_INTR_IN_NUM         5
-#define HIGHSPEED
 #endif
 
 
@@ -319,7 +321,6 @@
 #define FS_BULK_OUT_MAXPACKET  64
 static const char EP_INTR_IN_NAME[] = "ep-e";
 #define EP_INTR_IN_NUM         5
-#define HIGHSPEED
 #endif
 
 
@@ -396,25 +397,6 @@
 #      error Configure some USB peripheral controller driver!
 #endif
 
-/* Power usage is config specific.
- * Hardware that supports remote wakeup defaults to disabling it.
- */
-#ifndef        SELFPOWER
-/* default: say we're self-powered */
-#define SELFPOWER USB_CONFIG_ATT_SELFPOWER
-/* else:
- * - SELFPOWER value must be zero
- * - MAX_USB_POWER may be nonzero.
- */
-#endif
-
-#ifndef        MAX_USB_POWER
-/* Any hub supports this steady state bus power consumption */
-#define MAX_USB_POWER  100     /* mA */
-#endif
-
-/* We don't support remote wake-up */
-
 #ifdef NO_BULK_STALL
 #define CAN_STALL      0
 #else
@@ -1015,11 +997,11 @@
        .bLength =              sizeof config_desc,
        .bDescriptorType =      USB_DT_CONFIG,
 
-       /* wTotalLength adjusted during bind() */
+       /* wTotalLength computed by usb_gadget_config_buf() */
        .bNumInterfaces =       1,
        .bConfigurationValue =  CONFIG_VALUE,
-       .bmAttributes =         USB_CONFIG_ATT_ONE | SELFPOWER,
-       .bMaxPower =            (MAX_USB_POWER + 1) / 2,
+       .bmAttributes =         USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
+       .bMaxPower =            1,      // self-powered
 };
 
 /* There is only one interface. */
@@ -1069,7 +1051,16 @@
        .bInterval =            32,     // frames -> 32 ms
 };
 
-#ifdef HIGHSPEED
+static const struct usb_descriptor_header *fs_function[] = {
+       (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,
+};
+
+
+#ifdef CONFIG_USB_GADGET_DUALSPEED
 
 /*
  * USB 2.0 devices need to expose both high speed and full speed
@@ -1079,47 +1070,52 @@
  * and a "device qualifier" ... plus more construction options
  * for the config descriptor.
  */
-static const struct usb_endpoint_descriptor
+static struct usb_qualifier_descriptor
+dev_qualifier = {
+       .bLength =              sizeof dev_qualifier,
+       .bDescriptorType =      USB_DT_DEVICE_QUALIFIER,
+
+       .bcdUSB =               __constant_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 =     EP_BULK_IN_NUM | USB_DIR_IN,
        .bmAttributes =         USB_ENDPOINT_XFER_BULK,
        .wMaxPacketSize =       __constant_cpu_to_le16(512),
 };
 
-static const struct usb_endpoint_descriptor
+static struct usb_endpoint_descriptor
 hs_bulk_out_desc = {
        .bLength =              USB_DT_ENDPOINT_SIZE,
        .bDescriptorType =      USB_DT_ENDPOINT,
 
-       .bEndpointAddress =     EP_BULK_OUT_NUM,
        .bmAttributes =         USB_ENDPOINT_XFER_BULK,
        .wMaxPacketSize =       __constant_cpu_to_le16(512),
        .bInterval =            1,      // NAK every 1 uframe
 };
 
-static const struct usb_endpoint_descriptor
+static struct usb_endpoint_descriptor
 hs_intr_in_desc = {
        .bLength =              USB_DT_ENDPOINT_SIZE,
        .bDescriptorType =      USB_DT_ENDPOINT,
 
-       .bEndpointAddress =     EP_INTR_IN_NUM | USB_DIR_IN,
        .bmAttributes =         USB_ENDPOINT_XFER_INT,
        .wMaxPacketSize =       __constant_cpu_to_le16(2),
        .bInterval =            9,      // 2**(9-1) = 256 uframes -> 32 ms
 };
 
-static struct usb_qualifier_descriptor
-dev_qualifier = {
-       .bLength =              sizeof dev_qualifier,
-       .bDescriptorType =      USB_DT_DEVICE_QUALIFIER,
-
-       .bcdUSB =               __constant_cpu_to_le16(0x0200),
-       .bDeviceClass =         USB_CLASS_PER_INTERFACE,
-
-       .bNumConfigurations =   1,
+static const struct usb_descriptor_header *hs_function[] = {
+       (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,
 };
 
 /* Maxpacket and other transfer characteristics vary by speed. */
@@ -1127,22 +1123,23 @@
 
 #else
 
-/* If there's no high speed support, maxpacket doesn't change. */
+/* If there's no high speed support, always use the full-speed descriptor. */
 #define ep_desc(g,fs,hs)       fs
 
-#endif /* !HIGHSPEED */
+#endif /* !CONFIG_USB_GADGET_DUALSPEED */
 
 
 /* The CBI specification limits the serial string to 12 uppercase hexadecimal
  * characters. */
+static char                            manufacturer[40];
 static char                            serial[13];
 
-/* Static strings, in ISO 8859/1 */
+/* Static strings, in UTF-8 (for simplicity we use only ASCII characters) */
 static struct usb_string               strings[] = {
-       { STRING_MANUFACTURER, UTS_SYSNAME " " UTS_RELEASE " with " CHIP, },
-       { STRING_PRODUCT, longname, },
-       { STRING_SERIAL, serial, },
-       { }                     // end of list
+       {STRING_MANUFACTURER,   manufacturer},
+       {STRING_PRODUCT,        longname},
+       {STRING_SERIAL,         serial},
+       {}
 };
 
 static struct usb_gadget_strings       stringtab = {
@@ -1152,61 +1149,33 @@
 
 
 /*
- * Config descriptors are handcrafted.  They must agree with the code
- * that sets configurations and with code managing interfaces and their
- * altsettings.  They must also handle different speeds and other-speed
- * requests.
+ * Config descriptors must agree with the code that sets configurations
+ * and with code managing interfaces and their altsettings.  They must
+ * also handle different speeds and other-speed requests.
  */
 static int populate_config_buf(enum usb_device_speed speed,
-               u8 *buf0, u8 type, unsigned index)
+               u8 *buf, u8 type, unsigned index)
 {
-       u8      *buf = buf0;
-#ifdef HIGHSPEED
-       int     hs;
-#endif
+       int                                     len;
+       const struct usb_descriptor_header      **function;
 
        if (index > 0)
                return -EINVAL;
-       if (config_desc.wTotalLength  > EP0_BUFSIZE)
-               return -EDOM;
 
-       /* Config (or other speed config) */
-       memcpy(buf, &config_desc, USB_DT_CONFIG_SIZE);
-       buf[1] = type;
-       buf += USB_DT_CONFIG_SIZE;
-
-       /* Interface */
-       memcpy(buf, &intf_desc, USB_DT_INTERFACE_SIZE);
-       buf += USB_DT_INTERFACE_SIZE;
-
-       /* The endpoints in the interface (at that speed) */
-#ifdef HIGHSPEED
-       hs = (speed == USB_SPEED_HIGH);
+#ifdef CONFIG_USB_GADGET_DUALSPEED
        if (type == USB_DT_OTHER_SPEED_CONFIG)
-               hs = !hs;
-       if (hs) {
-               memcpy(buf, &hs_bulk_in_desc, USB_DT_ENDPOINT_SIZE);
-               buf += USB_DT_ENDPOINT_SIZE;
-               memcpy(buf, &hs_bulk_out_desc, USB_DT_ENDPOINT_SIZE);
-               buf += USB_DT_ENDPOINT_SIZE;
-               if (transport_is_cbi()) {
-                       memcpy(buf, &hs_intr_in_desc, USB_DT_ENDPOINT_SIZE);
-                       buf += USB_DT_ENDPOINT_SIZE;
-               }
-       } else
+               speed = (USB_SPEED_FULL + USB_SPEED_HIGH) - speed;
+       if (speed == USB_SPEED_HIGH)
+               function = hs_function;
+       else
 #endif
-       {
-               memcpy(buf, &fs_bulk_in_desc, USB_DT_ENDPOINT_SIZE);
-               buf += USB_DT_ENDPOINT_SIZE;
-               memcpy(buf, &fs_bulk_out_desc, USB_DT_ENDPOINT_SIZE);
-               buf += USB_DT_ENDPOINT_SIZE;
-               if (transport_is_cbi()) {
-                       memcpy(buf, &fs_intr_in_desc, USB_DT_ENDPOINT_SIZE);
-                       buf += USB_DT_ENDPOINT_SIZE;
-               }
-       }
+               function = fs_function;
 
-       return buf - buf0;
+       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;
 }
 
 
@@ -1505,22 +1474,26 @@
                        value = min(ctrl->wLength, (u16) sizeof device_desc);
                        memcpy(req->buf, &device_desc, value);
                        break;
-#ifdef HIGHSPEED
+#ifdef CONFIG_USB_GADGET_DUALSPEED
                case USB_DT_DEVICE_QUALIFIER:
                        VDBG(fsg, "get device qualifier\n");
+                       if (!fsg->gadget->is_dualspeed)
+                               break;
                        value = min(ctrl->wLength, (u16) sizeof dev_qualifier);
                        memcpy(req->buf, &dev_qualifier, value);
                        break;
 
                case USB_DT_OTHER_SPEED_CONFIG:
                        VDBG(fsg, "get other-speed config descriptor\n");
+                       if (!fsg->gadget->is_dualspeed)
+                               break;
                        goto get_config;
-#endif /* HIGHSPEED */
+#endif
                case USB_DT_CONFIG:
                        VDBG(fsg, "get configuration descriptor\n");
-#ifdef HIGHSPEED
+#ifdef CONFIG_USB_GADGET_DUALSPEED
                get_config:
-#endif /* HIGHSPEED */
+#endif
                        value = populate_config_buf(fsg->gadget->speed,
                                        req->buf,
                                        ctrl->wValue >> 8,
@@ -3258,6 +3231,7 @@
        if ((rc = enable_endpoint(fsg, fsg->bulk_out, d)) != 0)
                goto reset;
        fsg->bulk_out_enabled = 1;
+       fsg->bulk_out_maxpacket = d->wMaxPacketSize;
 
        if (transport_is_cbi()) {
                d = ep_desc(fsg->gadget, &fs_intr_in_desc, &hs_intr_in_desc);
@@ -3964,19 +3938,27 @@
 
        /* Fix up the descriptors */
        device_desc.bMaxPacketSize0 = fsg->ep0->maxpacket;
-#ifdef HIGHSPEED
-       dev_qualifier.bMaxPacketSize0 = fsg->ep0->maxpacket;            // ???
-#endif
        device_desc.idVendor = cpu_to_le16(mod_data.vendor);
        device_desc.idProduct = cpu_to_le16(mod_data.product);
        device_desc.bcdDevice = cpu_to_le16(mod_data.release);
 
        i = (transport_is_cbi() ? 3 : 2);       // Number of endpoints
-       config_desc.wTotalLength = USB_DT_CONFIG_SIZE + USB_DT_INTERFACE_SIZE
-                       + USB_DT_ENDPOINT_SIZE * i;
        intf_desc.bNumEndpoints = i;
        intf_desc.bInterfaceSubClass = mod_data.protocol_type;
        intf_desc.bInterfaceProtocol = mod_data.transport_type;
+       fs_function[i+1] = NULL;
+
+#ifdef CONFIG_USB_GADGET_DUALSPEED
+       hs_function[i+1] = NULL;
+
+       /* Assume ep0 uses the same maxpacket value for both speeds */
+       dev_qualifier.bMaxPacketSize0 = fsg->ep0->maxpacket;
+
+       /* Assume that all endpoint addresses are the same for both speeds */
+       hs_bulk_in_desc.bEndpointAddress = fs_bulk_in_desc.bEndpointAddress;
+       hs_bulk_out_desc.bEndpointAddress = fs_bulk_out_desc.bEndpointAddress;
+       hs_intr_in_desc.bEndpointAddress = fs_intr_in_desc.bEndpointAddress;
+#endif
 
        /* Find all the endpoints we will use */
        gadget_for_each_ep(ep, gadget) {
@@ -3993,8 +3975,6 @@
                rc = -ENOTSUPP;
                goto out;
        }
-       fsg->bulk_out_maxpacket = (gadget->speed == USB_SPEED_HIGH ? 512 :
-                       FS_BULK_OUT_MAXPACKET);
 
        rc = -ENOMEM;
 
@@ -4023,6 +4003,10 @@
        /* This should reflect the actual gadget power source */
        usb_gadget_set_selfpowered(gadget);
 
+       snprintf(manufacturer, sizeof manufacturer,
+                       UTS_SYSNAME " " UTS_RELEASE " with %s",
+                       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) {
@@ -4082,7 +4066,7 @@
 /*-------------------------------------------------------------------------*/
 
 static struct usb_gadget_driver                fsg_driver = {
-#ifdef HIGHSPEED
+#ifdef CONFIG_USB_GADGET_DUALSPEED
        .speed          = USB_SPEED_HIGH,
 #else
        .speed          = USB_SPEED_FULL,



-------------------------------------------------------
This SF.Net email is sponsored by: IBM Linux Tutorials
Free Linux tutorial presented by Daniel Robbins, President and CEO of
GenToo technologies. Learn everything from fundamentals to system
administration.http://ads.osdn.com/?ad_id70&alloc_id638&op=click
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to