Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 226907
b: refs/heads/master
c: 8be8a9d
h: refs/heads/master
i:
  226905: dac96a0
  226903: 6c91bcc
v: v3
  • Loading branch information
Tatyana Brokhman authored and Greg Kroah-Hartman committed Nov 11, 2010
1 parent 0008ef9 commit 06e6472
Show file tree
Hide file tree
Showing 2 changed files with 136 additions and 117 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: 0eadcc09203349b11ca477ec367079b23d32ab91
refs/heads/master: 8be8a9d3d16a25645b7869e4544a9d0ec386966a
251 changes: 135 additions & 116 deletions trunk/drivers/usb/gadget/dummy_hcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -1197,6 +1197,139 @@ static struct dummy_ep *find_endpoint (struct dummy *dum, u8 address)
#define Ep_Request (USB_TYPE_STANDARD | USB_RECIP_ENDPOINT)
#define Ep_InRequest (Ep_Request | USB_DIR_IN)


/**
* handle_control_request() - handles all control transfers
* @dum: pointer to dummy (the_controller)
* @urb: the urb request to handle
* @setup: pointer to the setup data for a USB device control
* request
* @status: pointer to request handling status
*
* Return 0 - if the request was handled
* 1 - if the request wasn't handles
* error code on error
*/
static int handle_control_request(struct dummy *dum, struct urb *urb,
struct usb_ctrlrequest *setup,
int *status)
{
struct dummy_ep *ep2;
int ret_val = 1;
unsigned w_index;
unsigned w_value;

w_index = le16_to_cpu(setup->wIndex);
w_value = le16_to_cpu(setup->wValue);
switch (setup->bRequest) {
case USB_REQ_SET_ADDRESS:
if (setup->bRequestType != Dev_Request)
break;
dum->address = w_value;
*status = 0;
dev_dbg(udc_dev(dum), "set_address = %d\n",
w_value);
ret_val = 0;
break;
case USB_REQ_SET_FEATURE:
if (setup->bRequestType == Dev_Request) {
ret_val = 0;
switch (w_value) {
case USB_DEVICE_REMOTE_WAKEUP:
break;
case USB_DEVICE_B_HNP_ENABLE:
dum->gadget.b_hnp_enable = 1;
break;
case USB_DEVICE_A_HNP_SUPPORT:
dum->gadget.a_hnp_support = 1;
break;
case USB_DEVICE_A_ALT_HNP_SUPPORT:
dum->gadget.a_alt_hnp_support = 1;
break;
default:
ret_val = -EOPNOTSUPP;
}
if (ret_val == 0) {
dum->devstatus |= (1 << w_value);
*status = 0;
}
} else if (setup->bRequestType == Ep_Request) {
/* endpoint halt */
ep2 = find_endpoint(dum, w_index);
if (!ep2 || ep2->ep.name == ep0name) {
ret_val = -EOPNOTSUPP;
break;
}
ep2->halted = 1;
ret_val = 0;
*status = 0;
}
break;
case USB_REQ_CLEAR_FEATURE:
if (setup->bRequestType == Dev_Request) {
ret_val = 0;
switch (w_value) {
case USB_DEVICE_REMOTE_WAKEUP:
w_value = USB_DEVICE_REMOTE_WAKEUP;
break;
default:
ret_val = -EOPNOTSUPP;
break;
}
if (ret_val == 0) {
dum->devstatus &= ~(1 << w_value);
*status = 0;
}
} else if (setup->bRequestType == Ep_Request) {
/* endpoint halt */
ep2 = find_endpoint(dum, w_index);
if (!ep2) {
ret_val = -EOPNOTSUPP;
break;
}
if (!ep2->wedged)
ep2->halted = 0;
ret_val = 0;
*status = 0;
}
break;
case USB_REQ_GET_STATUS:
if (setup->bRequestType == Dev_InRequest
|| setup->bRequestType == Intf_InRequest
|| setup->bRequestType == Ep_InRequest) {
char *buf;
/*
* device: remote wakeup, selfpowered
* interface: nothing
* endpoint: halt
*/
buf = (char *)urb->transfer_buffer;
if (urb->transfer_buffer_length > 0) {
if (setup->bRequestType == Ep_InRequest) {
ep2 = find_endpoint(dum, w_index);
if (!ep2) {
ret_val = -EOPNOTSUPP;
break;
}
buf[0] = ep2->halted;
} else if (setup->bRequestType ==
Dev_InRequest) {
buf[0] = (u8)dum->devstatus;
} else
buf[0] = 0;
}
if (urb->transfer_buffer_length > 1)
buf[1] = 0;
urb->actual_length = min_t(u32, 2,
urb->transfer_buffer_length);
ret_val = 0;
*status = 0;
}
break;
}
return ret_val;
}

/* drive both sides of the transfers; looks like irq handlers to
* both drivers except the callbacks aren't in_irq().
*/
Expand Down Expand Up @@ -1299,14 +1432,8 @@ static void dummy_timer (unsigned long _dum)
if (ep == &dum->ep [0] && ep->setup_stage) {
struct usb_ctrlrequest setup;
int value = 1;
struct dummy_ep *ep2;
unsigned w_index;
unsigned w_value;

setup = *(struct usb_ctrlrequest*) urb->setup_packet;
w_index = le16_to_cpu(setup.wIndex);
w_value = le16_to_cpu(setup.wValue);

/* paranoia, in case of stale queued data */
list_for_each_entry (req, &ep->queue, queue) {
list_del_init (&req->queue);
Expand All @@ -1328,117 +1455,9 @@ static void dummy_timer (unsigned long _dum)
ep->last_io = jiffies;
ep->setup_stage = 0;
ep->halted = 0;
switch (setup.bRequest) {
case USB_REQ_SET_ADDRESS:
if (setup.bRequestType != Dev_Request)
break;
dum->address = w_value;
status = 0;
dev_dbg (udc_dev(dum), "set_address = %d\n",
w_value);
value = 0;
break;
case USB_REQ_SET_FEATURE:
if (setup.bRequestType == Dev_Request) {
value = 0;
switch (w_value) {
case USB_DEVICE_REMOTE_WAKEUP:
break;
case USB_DEVICE_B_HNP_ENABLE:
dum->gadget.b_hnp_enable = 1;
break;
case USB_DEVICE_A_HNP_SUPPORT:
dum->gadget.a_hnp_support = 1;
break;
case USB_DEVICE_A_ALT_HNP_SUPPORT:
dum->gadget.a_alt_hnp_support
= 1;
break;
default:
value = -EOPNOTSUPP;
}
if (value == 0) {
dum->devstatus |=
(1 << w_value);
status = 0;
}

} else if (setup.bRequestType == Ep_Request) {
// endpoint halt
ep2 = find_endpoint (dum, w_index);
if (!ep2 || ep2->ep.name == ep0name) {
value = -EOPNOTSUPP;
break;
}
ep2->halted = 1;
value = 0;
status = 0;
}
break;
case USB_REQ_CLEAR_FEATURE:
if (setup.bRequestType == Dev_Request) {
switch (w_value) {
case USB_DEVICE_REMOTE_WAKEUP:
dum->devstatus &= ~(1 <<
USB_DEVICE_REMOTE_WAKEUP);
value = 0;
status = 0;
break;
default:
value = -EOPNOTSUPP;
break;
}
} else if (setup.bRequestType == Ep_Request) {
// endpoint halt
ep2 = find_endpoint (dum, w_index);
if (!ep2) {
value = -EOPNOTSUPP;
break;
}
if (!ep2->wedged)
ep2->halted = 0;
value = 0;
status = 0;
}
break;
case USB_REQ_GET_STATUS:
if (setup.bRequestType == Dev_InRequest
|| setup.bRequestType
== Intf_InRequest
|| setup.bRequestType
== Ep_InRequest
) {
char *buf;

// device: remote wakeup, selfpowered
// interface: nothing
// endpoint: halt
buf = (char *)urb->transfer_buffer;
if (urb->transfer_buffer_length > 0) {
if (setup.bRequestType ==
Ep_InRequest) {
ep2 = find_endpoint (dum, w_index);
if (!ep2) {
value = -EOPNOTSUPP;
break;
}
buf [0] = ep2->halted;
} else if (setup.bRequestType ==
Dev_InRequest) {
buf [0] = (u8)
dum->devstatus;
} else
buf [0] = 0;
}
if (urb->transfer_buffer_length > 1)
buf [1] = 0;
urb->actual_length = min_t(u32, 2,
urb->transfer_buffer_length);
value = 0;
status = 0;
}
break;
}
value = handle_control_request(dum, urb, &setup,
&status);

/* gadget driver handles all other requests. block
* until setup() returns; no reentrancy issues etc.
Expand Down

0 comments on commit 06e6472

Please sign in to comment.