Change control handling to start expecting host packets before sending data to the host. This makes the handling less timing sensitive on some controllers

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@23263 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Frank Gevaerts 2009-10-19 16:21:50 +00:00
parent ee6557eeda
commit bad510ad10
4 changed files with 33 additions and 36 deletions

View file

@ -51,7 +51,6 @@ void usb_core_enable_driver(int driver,bool enabled);
bool usb_core_driver_enabled(int driver);
void usb_core_handle_transfer_completion(
struct usb_transfer_completion_event_data* event);
int usb_core_ack_control(struct usb_ctrlrequest* req);
int usb_core_request_endpoint(int type, int dir,struct usb_class_driver* drv);
void usb_core_release_endpoint(int dir);

View file

@ -507,6 +507,15 @@ static void allocate_interfaces_and_endpoints(void)
usb_core_num_interfaces = interface;
}
static int usb_core_ack_control(struct usb_ctrlrequest* req)
{
if (req->bRequestType & USB_DIR_IN)
return usb_drv_recv(EP_CONTROL,NULL,0);
else
return usb_drv_send(EP_CONTROL,NULL,0);
}
static void control_request_handler_drivers(struct usb_ctrlrequest* req)
{
int i, interface = req->wIndex;
@ -608,11 +617,9 @@ static void request_handler_device_get_descriptor(struct usb_ctrlrequest* req)
memcpy(response_data,ptr,length);
}
if(usb_drv_send(EP_CONTROL,response_data,length))
return;
usb_drv_recv(EP_CONTROL,NULL,0);
usb_drv_send(EP_CONTROL,response_data,length);
}
if (handled)
usb_core_ack_control(req);
}
static void request_handler_device(struct usb_ctrlrequest* req)
@ -623,8 +630,8 @@ static void request_handler_device(struct usb_ctrlrequest* req)
case USB_REQ_GET_CONFIGURATION: {
logf("usb_core: GET_CONFIG");
response_data[0] = (usb_state == ADDRESS ? 0 : 1);
if(!usb_drv_send(EP_CONTROL, response_data, 1))
usb_core_ack_control(req);
usb_drv_recv(EP_CONTROL,NULL,0);
usb_drv_send(EP_CONTROL, response_data, 1);
break;
}
case USB_REQ_SET_CONFIGURATION: {
@ -640,14 +647,13 @@ static void request_handler_device(struct usb_ctrlrequest* req)
else {
usb_state = ADDRESS;
}
usb_core_ack_control(req);
usb_drv_send(EP_CONTROL,NULL,0);
break;
}
case USB_REQ_SET_ADDRESS: {
unsigned char address = req->wValue;
logf("usb_core: SET_ADR %d", address);
if(usb_core_ack_control(req))
break;
usb_drv_send(EP_CONTROL,NULL,0);
usb_drv_cancel_all_transfers();
usb_address = address;
usb_drv_set_address(usb_address);
@ -663,15 +669,15 @@ static void request_handler_device(struct usb_ctrlrequest* req)
case USB_REQ_SET_FEATURE:
if(req->wValue==USB_DEVICE_TEST_MODE) {
int mode=req->wIndex>>8;
usb_core_ack_control(req);
usb_drv_send(EP_CONTROL,NULL,0);
usb_drv_set_test_mode(mode);
}
break;
case USB_REQ_GET_STATUS:
response_data[0]= 0;
response_data[1]= 0;
if(!usb_drv_send(EP_CONTROL, response_data, 2))
usb_core_ack_control(req);
usb_drv_recv(EP_CONTROL,NULL,0);
usb_drv_send(EP_CONTROL, response_data, 2);
break;
default:
break;
@ -684,14 +690,14 @@ static void request_handler_interface_standard(struct usb_ctrlrequest* req)
{
case USB_REQ_SET_INTERFACE:
logf("usb_core: SET_INTERFACE");
usb_core_ack_control(req);
usb_drv_send(EP_CONTROL,NULL,0);
break;
case USB_REQ_GET_INTERFACE:
logf("usb_core: GET_INTERFACE");
response_data[0]=0;
if(!usb_drv_send(EP_CONTROL,response_data,1))
usb_core_ack_control(req);
usb_drv_recv(EP_CONTROL,NULL,0);
usb_drv_send(EP_CONTROL,response_data,1);
break;
case USB_REQ_CLEAR_FEATURE:
break;
@ -700,8 +706,8 @@ static void request_handler_interface_standard(struct usb_ctrlrequest* req)
case USB_REQ_GET_STATUS:
response_data[0]=0;
response_data[1]=0;
if(!usb_drv_send(EP_CONTROL, response_data, 2))
usb_core_ack_control(req);
usb_drv_recv(EP_CONTROL,NULL,0);
usb_drv_send(EP_CONTROL, response_data, 2);
break;
default:
control_request_handler_drivers(req);
@ -730,13 +736,13 @@ static void request_handler_endpoint(struct usb_ctrlrequest* req)
if (req->wValue==USB_ENDPOINT_HALT) {
usb_drv_stall(EP_NUM(req->wIndex), false, EP_DIR(req->wIndex));
}
usb_core_ack_control(req);
usb_drv_send(EP_CONTROL,NULL,0);
break;
case USB_REQ_SET_FEATURE:
if (req->wValue==USB_ENDPOINT_HALT) {
usb_drv_stall(EP_NUM(req->wIndex), true, EP_DIR(req->wIndex));
}
usb_core_ack_control(req);
usb_drv_send(EP_CONTROL,NULL,0);
break;
case USB_REQ_GET_STATUS:
response_data[0]=0;
@ -746,8 +752,8 @@ static void request_handler_endpoint(struct usb_ctrlrequest* req)
response_data[0]=usb_drv_stalled(EP_NUM(req->wIndex),
EP_DIR(req->wIndex));
}
if(!usb_drv_send(EP_CONTROL,response_data,2))
usb_core_ack_control(req);
usb_drv_recv(EP_CONTROL,NULL,0);
usb_drv_send(EP_CONTROL,response_data,2);
break;
default: {
bool handled;
@ -843,14 +849,6 @@ void usb_core_control_request(struct usb_ctrlrequest* req)
usb_signal_transfer_completion(completion_event);
}
int usb_core_ack_control(struct usb_ctrlrequest* req)
{
if (req->bRequestType & USB_DIR_IN)
return usb_drv_recv(EP_CONTROL,NULL,0);
else
return usb_drv_send(EP_CONTROL,NULL,0);
}
#ifdef HAVE_USB_POWER
unsigned short usb_allowed_current()
{

View file

@ -739,10 +739,10 @@ bool usb_hid_control_request(struct usb_ctrlrequest *req, unsigned char *dest)
logf("hid: unsup. std. req");
break;
}
if (dest != orig_dest &&
!usb_drv_send(EP_CONTROL, orig_dest, dest - orig_dest))
if (dest != orig_dest)
{
usb_core_ack_control(req);
usb_drv_recv(EP_CONTROL, NULL, 0); /* ack */
usb_drv_send(EP_CONTROL, orig_dest, dest - orig_dest);
handled = true;
}
break;
@ -754,14 +754,14 @@ bool usb_hid_control_request(struct usb_ctrlrequest *req, unsigned char *dest)
{
case USB_HID_SET_IDLE:
logf("hid: set idle");
usb_core_ack_control(req);
usb_drv_send(EP_CONTROL, NULL, 0); /* ack */
handled = true;
break;
case USB_HID_SET_REPORT:
logf("hid: set report");
if (!usb_hid_set_report(req))
{
usb_core_ack_control(req);
usb_drv_send(EP_CONTROL, NULL, 0); /* ack */
handled = true;
}
break;

View file

@ -659,8 +659,8 @@ bool usb_storage_control_request(struct usb_ctrlrequest* req, unsigned char* des
*tb.max_lun --;
#endif
logf("ums: getmaxlun");
usb_drv_send(EP_CONTROL, tb.max_lun, 1);
usb_drv_recv(EP_CONTROL, NULL, 0); /* ack */
usb_drv_send(EP_CONTROL, tb.max_lun, 1);
handled = true;
break;
}