/*
* file_storage.c -- File-backed USB Storage Gadget, for USB development
*
- * Copyright (C) 2003, 2004 Alan Stern
+ * Copyright (C) 2003-2005 Alan Stern
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
#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
/* wTotalLength computed by usb_gadget_config_buf() */
.bNumInterfaces = 1,
.bConfigurationValue = CONFIG_VALUE,
+ .iConfiguration = STRING_CONFIG,
.bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
.bMaxPower = 1, // self-powered
};
.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,
/* The CBI specification limits the serial string to 12 uppercase hexadecimal
* characters. */
-static char manufacturer[50];
+static char manufacturer[64];
static char serial[13];
/* Static strings, in UTF-8 (for simplicity we use only ASCII characters) */
{STRING_MANUFACTURER, manufacturer},
{STRING_PRODUCT, longname},
{STRING_SERIAL, serial},
+ {STRING_CONFIG, "Self-powered"},
+ {STRING_INTERFACE, "Mass Storage"},
{}
};
{
struct usb_request *req = fsg->ep0req;
int value = -EOPNOTSUPP;
+ u16 w_index = ctrl->wIndex;
+ u16 w_length = ctrl->wLength;
if (!fsg->config)
return value;
if (ctrl->bRequestType != (USB_DIR_OUT |
USB_TYPE_CLASS | USB_RECIP_INTERFACE))
break;
- if (ctrl->wIndex != 0) {
+ if (w_index != 0) {
value = -EDOM;
break;
}
if (ctrl->bRequestType != (USB_DIR_IN |
USB_TYPE_CLASS | USB_RECIP_INTERFACE))
break;
- if (ctrl->wIndex != 0) {
+ if (w_index != 0) {
value = -EDOM;
break;
}
VDBG(fsg, "get max LUN\n");
*(u8 *) req->buf = fsg->nluns - 1;
- value = min(ctrl->wLength, (u16) 1);
+ value = min(w_length, (u16) 1);
break;
}
}
if (ctrl->bRequestType != (USB_DIR_OUT |
USB_TYPE_CLASS | USB_RECIP_INTERFACE))
break;
- if (ctrl->wIndex != 0) {
+ if (w_index != 0) {
value = -EDOM;
break;
}
- if (ctrl->wLength > MAX_COMMAND_SIZE) {
+ if (w_length > MAX_COMMAND_SIZE) {
value = -EOVERFLOW;
break;
}
- value = ctrl->wLength;
+ value = w_length;
fsg->ep0req->context = received_cbi_adsc;
break;
}
"unknown class-specific control req "
"%02x.%02x v%04x i%04x l%u\n",
ctrl->bRequestType, ctrl->bRequest,
- ctrl->wValue, ctrl->wIndex, ctrl->wLength);
+ ctrl->wValue, w_index, w_length);
return value;
}
{
struct usb_request *req = fsg->ep0req;
int value = -EOPNOTSUPP;
+ u16 w_index = ctrl->wIndex;
+ u16 w_value = ctrl->wValue;
+ u16 w_length = ctrl->wLength;
/* Usually this just stores reply data in the pre-allocated ep0 buffer,
* but config change events will also reconfigure hardware. */
if (ctrl->bRequestType != (USB_DIR_IN | USB_TYPE_STANDARD |
USB_RECIP_DEVICE))
break;
- switch (ctrl->wValue >> 8) {
+ switch (w_value >> 8) {
case USB_DT_DEVICE:
VDBG(fsg, "get device descriptor\n");
- value = min(ctrl->wLength, (u16) sizeof device_desc);
+ value = min(w_length, (u16) sizeof device_desc);
memcpy(req->buf, &device_desc, value);
break;
#ifdef CONFIG_USB_GADGET_DUALSPEED
VDBG(fsg, "get device qualifier\n");
if (!fsg->gadget->is_dualspeed)
break;
- value = min(ctrl->wLength, (u16) sizeof dev_qualifier);
+ value = min(w_length, (u16) sizeof dev_qualifier);
memcpy(req->buf, &dev_qualifier, value);
break;
#endif
value = populate_config_buf(fsg->gadget,
req->buf,
- ctrl->wValue >> 8,
- ctrl->wValue & 0xff);
+ w_value >> 8,
+ w_value & 0xff);
if (value >= 0)
- value = min(ctrl->wLength, (u16) value);
+ value = min(w_length, (u16) value);
break;
case USB_DT_STRING:
/* wIndex == language code */
value = usb_gadget_get_string(&stringtab,
- ctrl->wValue & 0xff, req->buf);
+ w_value & 0xff, req->buf);
if (value >= 0)
- value = min(ctrl->wLength, (u16) value);
+ value = min(w_length, (u16) value);
break;
}
break;
USB_RECIP_DEVICE))
break;
VDBG(fsg, "set configuration\n");
- if (ctrl->wValue == CONFIG_VALUE || ctrl->wValue == 0) {
- fsg->new_config = ctrl->wValue;
+ if (w_value == CONFIG_VALUE || w_value == 0) {
+ fsg->new_config = w_value;
/* Raise an exception to wipe out previous transaction
* state (queued bufs, etc) and set the new config. */
break;
VDBG(fsg, "get configuration\n");
*(u8 *) req->buf = fsg->config;
- value = min(ctrl->wLength, (u16) 1);
+ value = min(w_length, (u16) 1);
break;
case USB_REQ_SET_INTERFACE:
if (ctrl->bRequestType != (USB_DIR_OUT| USB_TYPE_STANDARD |
USB_RECIP_INTERFACE))
break;
- if (fsg->config && ctrl->wIndex == 0) {
+ if (fsg->config && w_index == 0) {
/* Raise an exception to wipe out previous transaction
* state (queued bufs, etc) and install the new
break;
if (!fsg->config)
break;
- if (ctrl->wIndex != 0) {
+ if (w_index != 0) {
value = -EDOM;
break;
}
VDBG(fsg, "get interface\n");
*(u8 *) req->buf = 0;
- value = min(ctrl->wLength, (u16) 1);
+ value = min(w_length, (u16) 1);
break;
default:
VDBG(fsg,
"unknown control req %02x.%02x v%04x i%04x l%u\n",
ctrl->bRequestType, ctrl->bRequest,
- ctrl->wValue, ctrl->wIndex, ctrl->wLength);
+ w_value, w_index, w_length);
}
return value;
mod_data.release = 0x0310;
else if (gadget_is_pxa27x(fsg->gadget))
mod_data.release = 0x0311;
+ else if (gadget_is_s3c2410(gadget))
+ mod_data.release = 0x0312;
+ else if (gadget_is_at91(fsg->gadget))
+ mod_data.release = 0x0313;
else {
WARN(fsg, "controller '%s' not recognized\n",
fsg->gadget->name);