X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;ds=sidebyside;f=drivers%2Fusb%2Fgadget%2Ffile_storage.c;h=ae82b80748aeeb1aa454e7f6a0e4233dfbf3e2ff;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=6e8008fa43cb0af86f80e4f9ea84f4276f160c9e;hpb=87fc8d1bb10cd459024a742c6a10961fefcef18f;p=linux-2.6.git diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c index 6e8008fa4..ae82b8074 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c @@ -217,6 +217,7 @@ #include #include #include +#include #include #include #include @@ -234,8 +235,8 @@ #include #include #include -#include -#include +#include +#include #include #include @@ -248,7 +249,7 @@ #define DRIVER_DESC "File-backed Storage Gadget" #define DRIVER_NAME "g_file_storage" -#define DRIVER_VERSION "28 July 2004" +#define DRIVER_VERSION "20 October 2004" static const char longname[] = DRIVER_DESC; static const char shortname[] = DRIVER_NAME; @@ -367,10 +368,10 @@ static struct { }; -module_param_array(file, charp, mod_data.num_filenames, S_IRUGO); +module_param_array(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(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); @@ -428,9 +429,9 @@ MODULE_PARM_DESC(stall, "false to prevent bulk stalls"); /* Command Block Wrapper */ struct bulk_cb_wrap { - u32 Signature; // Contains 'USBC' + __le32 Signature; // Contains 'USBC' u32 Tag; // Unique per command id - u32 DataTransferLength; // Size of the data + __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 @@ -443,9 +444,9 @@ struct bulk_cb_wrap { /* Command Status Wrapper */ struct bulk_cs_wrap { - u32 Signature; // Should = 'USBS' + __le32 Signature; // Should = 'USBS' u32 Tag; // Same as original command - u32 Residue; // Amount not transferred + __le32 Residue; // Amount not transferred u8 Status; // See below }; @@ -866,6 +867,14 @@ config_desc = { .bMaxPower = 1, // self-powered }; +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 @@ -914,12 +923,14 @@ fs_intr_in_desc = { }; 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 @@ -976,12 +987,14 @@ hs_intr_in_desc = { }; 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)) @@ -996,7 +1009,7 @@ static const struct usb_descriptor_header *hs_function[] = { /* The CBI specification limits the serial string to 12 uppercase hexadecimal * characters. */ -static char manufacturer[40]; +static char manufacturer[50]; static char serial[13]; /* Static strings, in UTF-8 (for simplicity we use only ASCII characters) */ @@ -1018,9 +1031,12 @@ static struct usb_gadget_strings stringtab = { * 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, +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; @@ -1036,6 +1052,10 @@ static int populate_config_buf(enum usb_device_speed speed, #endif function = fs_function; + /* for now, don't advertise srp-only devices */ + if (!gadget->is_otg) + function++; + len = usb_gadget_config_buf(&config_desc, buf, EP0_BUFSIZE, function); ((struct usb_config_descriptor *) buf)->bDescriptorType = type; return len; @@ -1366,7 +1386,7 @@ static int standard_setup_req(struct fsg_dev *fsg, #ifdef CONFIG_USB_GADGET_DUALSPEED get_config: #endif - value = populate_config_buf(fsg->gadget->speed, + value = populate_config_buf(fsg->gadget, req->buf, ctrl->wValue >> 8, ctrl->wValue & 0xff); @@ -1523,6 +1543,8 @@ static int sleep_thread(struct fsg_dev *fsg) rc = wait_event_interruptible(fsg->thread_wqh, fsg->thread_wakeup_needed); fsg->thread_wakeup_needed = 0; + if (current->flags & PF_FREEZE) + refrigerator(PF_FREEZE); return (rc ? -EINTR : 0); } @@ -2280,8 +2302,7 @@ static int halt_bulk_in_endpoint(struct fsg_dev *fsg) } /* Wait for a short time and then try again */ - set_current_state(TASK_INTERRUPTIBLE); - if (schedule_timeout(HZ / 10) != 0) + if (msleep_interruptible(100) != 0) return -EINTR; rc = usb_ep_set_halt(fsg->bulk_in); } @@ -3110,7 +3131,7 @@ reset: if ((rc = enable_endpoint(fsg, fsg->bulk_out, d)) != 0) goto reset; fsg->bulk_out_enabled = 1; - fsg->bulk_out_maxpacket = d->wMaxPacketSize; + fsg->bulk_out_maxpacket = le16_to_cpu(d->wMaxPacketSize); if (transport_is_cbi()) { d = ep_desc(fsg->gadget, &fs_intr_in_desc, &hs_intr_in_desc); @@ -3557,7 +3578,7 @@ static ssize_t show_file(struct device *dev, char *buf) } -ssize_t store_ro(struct device *dev, const char *buf, size_t count) +static ssize_t store_ro(struct device *dev, const char *buf, size_t count) { ssize_t rc = count; struct lun *curlun = dev_to_lun(dev); @@ -3581,7 +3602,7 @@ ssize_t store_ro(struct device *dev, const char *buf, size_t count) return rc; } -ssize_t store_file(struct device *dev, const char *buf, size_t count) +static 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); @@ -3697,28 +3718,32 @@ static int __init check_parameters(struct fsg_dev *fsg) if (mod_data.release == 0xffff) { // Parameter wasn't set if (gadget_is_net2280(fsg->gadget)) - mod_data.release = __constant_cpu_to_le16(0x0301); + mod_data.release = 0x0301; else if (gadget_is_dummy(fsg->gadget)) - mod_data.release = __constant_cpu_to_le16(0x0302); + mod_data.release = 0x0302; else if (gadget_is_pxa(fsg->gadget)) - mod_data.release = __constant_cpu_to_le16(0x0303); + mod_data.release = 0x0303; else if (gadget_is_sh(fsg->gadget)) - mod_data.release = __constant_cpu_to_le16(0x0304); + mod_data.release = 0x0304; /* The sa1100 controller is not supported */ else if (gadget_is_goku(fsg->gadget)) - mod_data.release = __constant_cpu_to_le16(0x0306); + mod_data.release = 0x0306; else if (gadget_is_mq11xx(fsg->gadget)) - mod_data.release = __constant_cpu_to_le16(0x0307); + mod_data.release = 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); + mod_data.release = 0x0308; + else if (gadget_is_lh7a40x(fsg->gadget)) + mod_data.release = 0x0309; + else if (gadget_is_n9604(fsg->gadget)) + mod_data.release = 0x0310; + else if (gadget_is_pxa27x(fsg->gadget)) + mod_data.release = 0x0311; else { WARN(fsg, "controller '%s' not recognized\n", fsg->gadget->name); - mod_data.release = __constant_cpu_to_le16(0x0399); + mod_data.release = 0x0399; } } @@ -3882,10 +3907,10 @@ static int __init fsg_bind(struct usb_gadget *gadget) intf_desc.bNumEndpoints = i; intf_desc.bInterfaceSubClass = mod_data.protocol_type; intf_desc.bInterfaceProtocol = mod_data.transport_type; - fs_function[i+1] = NULL; + fs_function[i + FS_FUNCTION_PRE_EP_ENTRIES] = NULL; #ifdef CONFIG_USB_GADGET_DUALSPEED - hs_function[i+1] = NULL; + 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; @@ -3896,6 +3921,11 @@ static int __init fsg_bind(struct usb_gadget *gadget) hs_intr_in_desc.bEndpointAddress = fs_intr_in_desc.bEndpointAddress; #endif + if (gadget->is_otg) { + otg_desc.bmAttributes |= USB_OTG_HNP, + config_desc.bmAttributes |= USB_CONFIG_ATT_WAKEUP; + } + rc = -ENOMEM; /* Allocate the request and buffer for endpoint 0 */ @@ -3923,8 +3953,8 @@ static int __init fsg_bind(struct usb_gadget *gadget) /* This should reflect the actual gadget power source */ usb_gadget_set_selfpowered(gadget); - snprintf(manufacturer, sizeof manufacturer, - UTS_SYSNAME " " UTS_RELEASE " with %s", + snprintf(manufacturer, sizeof manufacturer, "%s %s with %s", + system_utsname.sysname, system_utsname.release, gadget->name); /* On a real device, serial[] would be loaded from permanent