From 7632ff1445dedee73fea5b4b5a01494c4040c4cd Mon Sep 17 00:00:00 2001 From: gevaerts Date: Mon, 19 Oct 2009 16:21:50 +0000 Subject: [PATCH] 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 --- firmware/export/usb_core.h | 1 - firmware/usbstack/usb_core.c | 56 ++++++++++++++++++++--------------------- firmware/usbstack/usb_hid.c | 10 ++++---- firmware/usbstack/usb_storage.c | 2 +- 4 files changed, 33 insertions(+), 36 deletions(-) diff --git a/firmware/export/usb_core.h b/firmware/export/usb_core.h index c65be5fa3..5286dbcdf 100644 --- a/firmware/export/usb_core.h +++ b/firmware/export/usb_core.h @@ -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); diff --git a/firmware/usbstack/usb_core.c b/firmware/usbstack/usb_core.c index 5093b9330..7d3d14f33 100644 --- a/firmware/usbstack/usb_core.c +++ b/firmware/usbstack/usb_core.c @@ -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() { diff --git a/firmware/usbstack/usb_hid.c b/firmware/usbstack/usb_hid.c index 2f592fcac..53dd767c5 100644 --- a/firmware/usbstack/usb_hid.c +++ b/firmware/usbstack/usb_hid.c @@ -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; diff --git a/firmware/usbstack/usb_storage.c b/firmware/usbstack/usb_storage.c index 4ca4366e7..d16277a5f 100644 --- a/firmware/usbstack/usb_storage.c +++ b/firmware/usbstack/usb_storage.c @@ -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; } -- 2.11.4.GIT