Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 151378
b: refs/heads/master
c: 32ebbe7
h: refs/heads/master
v: v3
  • Loading branch information
Josua Dietze authored and Greg Kroah-Hartman committed Jun 16, 2009
1 parent 602d26d commit ed7d3c5
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 53 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 68335e816a92411649955a9903b1f30c388ea322
refs/heads/master: 32ebbe7b6ad44ae9c276419710b56de6ba705303
121 changes: 69 additions & 52 deletions trunk/drivers/usb/storage/option_ms.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ MODULE_PARM_DESC(option_zero_cd, "ZeroCD mode (1=Force Modem (default),"

#define RESPONSE_LEN 1024

static int option_rezero(struct us_data *us, int ep_in, int ep_out)
static int option_rezero(struct us_data *us)
{
const unsigned char rezero_msg[] = {
0x55, 0x53, 0x42, 0x43, 0x78, 0x56, 0x34, 0x12,
Expand All @@ -54,10 +54,10 @@ static int option_rezero(struct us_data *us, int ep_in, int ep_out)
if (buffer == NULL)
return USB_STOR_TRANSPORT_ERROR;

memcpy(buffer, rezero_msg, sizeof (rezero_msg));
memcpy(buffer, rezero_msg, sizeof(rezero_msg));
result = usb_stor_bulk_transfer_buf(us,
usb_sndbulkpipe(us->pusb_dev, ep_out),
buffer, sizeof (rezero_msg), NULL);
us->send_bulk_pipe,
buffer, sizeof(rezero_msg), NULL);
if (result != USB_STOR_XFER_GOOD) {
result = USB_STOR_XFER_ERROR;
goto out;
Expand All @@ -66,74 +66,91 @@ static int option_rezero(struct us_data *us, int ep_in, int ep_out)
/* Some of the devices need to be asked for a response, but we don't
* care what that response is.
*/
result = usb_stor_bulk_transfer_buf(us,
usb_sndbulkpipe(us->pusb_dev, ep_out),
usb_stor_bulk_transfer_buf(us,
us->recv_bulk_pipe,
buffer, RESPONSE_LEN, NULL);

/* Read the CSW */
usb_stor_bulk_transfer_buf(us,
us->recv_bulk_pipe,
buffer, 13, NULL);

result = USB_STOR_XFER_GOOD;

out:
kfree(buffer);
return result;
}

int option_ms_init(struct us_data *us)
static int option_inquiry(struct us_data *us)
{
struct usb_device *udev;
struct usb_interface *intf;
struct usb_host_interface *iface_desc;
struct usb_endpoint_descriptor *endpoint = NULL;
u8 ep_in = 0, ep_out = 0;
int ep_in_size = 0, ep_out_size = 0;
int i, result;

udev = us->pusb_dev;
intf = us->pusb_intf;

/* Ensure it's really a ZeroCD device; devices that are already
* in modem mode return 0xFF for class, subclass, and protocol.
*/
if (udev->descriptor.bDeviceClass != 0 ||
udev->descriptor.bDeviceSubClass != 0 ||
udev->descriptor.bDeviceProtocol != 0 ||
udev->actconfig->desc.bNumInterfaces == 3)
return 0;
const unsigned char inquiry_msg[] = {
0x55, 0x53, 0x42, 0x43, 0x12, 0x34, 0x56, 0x78,
0x24, 0x00, 0x00, 0x00, 0x80, 0x00, 0x06, 0x12,
0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
char *buffer;
int result;

US_DEBUGP("Option MS: option_ms_init called\n");
US_DEBUGP("Option MS: %s", "device inquiry for vendor name\n");

/* Find the right mass storage interface */
iface_desc = intf->cur_altsetting;
if (iface_desc->desc.bInterfaceClass != 0x8 ||
iface_desc->desc.bInterfaceSubClass != 0x6 ||
iface_desc->desc.bInterfaceProtocol != 0x50) {
US_DEBUGP("Option MS: mass storage interface not found, no action "
"required\n");
return 0;
buffer = kzalloc(0x24, GFP_KERNEL);
if (buffer == NULL)
return USB_STOR_TRANSPORT_ERROR;

memcpy(buffer, inquiry_msg, sizeof(inquiry_msg));
result = usb_stor_bulk_transfer_buf(us,
us->send_bulk_pipe,
buffer, sizeof(inquiry_msg), NULL);
if (result != USB_STOR_XFER_GOOD) {
result = USB_STOR_XFER_ERROR;
goto out;
}

/* Find the mass storage bulk endpoints */
for (i = 0; i < iface_desc->desc.bNumEndpoints && (!ep_in_size || !ep_out_size); ++i) {
endpoint = &iface_desc->endpoint[i].desc;

if (usb_endpoint_is_bulk_in(endpoint)) {
ep_in = usb_endpoint_num(endpoint);
ep_in_size = le16_to_cpu(endpoint->wMaxPacketSize);
} else if (usb_endpoint_is_bulk_out(endpoint)) {
ep_out = usb_endpoint_num(endpoint);
ep_out_size = le16_to_cpu(endpoint->wMaxPacketSize);
}
result = usb_stor_bulk_transfer_buf(us,
us->recv_bulk_pipe,
buffer, 0x24, NULL);
if (result != USB_STOR_XFER_GOOD) {
result = USB_STOR_XFER_ERROR;
goto out;
}

/* Can't find the mass storage endpoints */
if (!ep_in_size || !ep_out_size) {
US_DEBUGP("Option MS: mass storage endpoints not found, no action "
"required\n");
result = memcmp(buffer+8, "Option", 6);

/* Read the CSW */
usb_stor_bulk_transfer_buf(us,
us->recv_bulk_pipe,
buffer, 13, NULL);

out:
kfree(buffer);
return result;
}


int option_ms_init(struct us_data *us)
{
int result;

US_DEBUGP("Option MS: option_ms_init called\n");

/* Additional test for vendor information via INQUIRY,
* because some vendor/product IDs are ambiguous
*/
result = option_inquiry(us);
if (result != 0) {
US_DEBUGP("Option MS: vendor is not Option or not determinable,"
" no action taken\n");
return 0;
}
} else
US_DEBUGP("Option MS: this is a genuine Option device,"
" proceeding\n");

/* Force Modem mode */
if (option_zero_cd == ZCD_FORCE_MODEM) {
US_DEBUGP("Option MS: %s", "Forcing Modem Mode\n");
result = option_rezero(us, ep_in, ep_out);
result = option_rezero(us);
if (result != USB_STOR_XFER_GOOD)
US_DEBUGP("Option MS: Failed to switch to modem mode.\n");
return -EIO;
Expand Down

0 comments on commit ed7d3c5

Please sign in to comment.