Loading drivers/usb/gadget/dummy_hcd.c +135 −116 Original line number Diff line number Diff line Loading @@ -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(). */ Loading Loading @@ -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); Loading @@ -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. Loading Loading
drivers/usb/gadget/dummy_hcd.c +135 −116 Original line number Diff line number Diff line Loading @@ -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(). */ Loading Loading @@ -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); Loading @@ -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. Loading