diff options
| author | Frank Gevaerts <frank@gevaerts.be> | 2008-02-20 22:54:26 +0000 |
|---|---|---|
| committer | Frank Gevaerts <frank@gevaerts.be> | 2008-02-20 22:54:26 +0000 |
| commit | 07427592a928ab3d164fbcca842399af6d5ca7ef (patch) | |
| tree | eb7b1b748f8ac9ea28ce357290bc5992f5e2403f /firmware/usbstack/usb_core.c | |
| parent | 6af732d17aa1eb882e3c52242b2bf7f2fcccc752 (diff) | |
| download | rockbox-07427592a928ab3d164fbcca842399af6d5ca7ef.zip rockbox-07427592a928ab3d164fbcca842399af6d5ca7ef.tar.gz rockbox-07427592a928ab3d164fbcca842399af6d5ca7ef.tar.bz2 rockbox-07427592a928ab3d164fbcca842399af6d5ca7ef.tar.xz | |
Major USB stack improvements. It now works at nearly the maximum speed for a full speed connection, and does seem stable.
Still not enabled by default, #define USE_ROCKBOX_USB is still required to enable it.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@16360 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/usbstack/usb_core.c')
| -rw-r--r-- | firmware/usbstack/usb_core.c | 508 |
1 files changed, 264 insertions, 244 deletions
diff --git a/firmware/usbstack/usb_core.c b/firmware/usbstack/usb_core.c index 13993f9..c68093b 100644 --- a/firmware/usbstack/usb_core.c +++ b/firmware/usbstack/usb_core.c @@ -23,44 +23,42 @@ //#define LOGF_ENABLE #include "logf.h" -#ifndef BOOTLOADER -//#define USB_SERIAL -//#define USB_BENCHMARK -#ifdef USE_ROCKBOX_USB -#define USB_STORAGE -#else -#define USB_CHARGING_ONLY -#endif /* USE_ROCKBOX_USB */ -#else -#define USB_CHARGING_ONLY -#endif - #include "usb_ch9.h" #include "usb_drv.h" #include "usb_core.h" +#define USB_THREAD + #if defined(USB_STORAGE) #include "usb_storage.h" -#define USB_THREAD -#elif defined(USB_SERIAL) -#define USB_THREAD +#endif + +#if defined(USB_SERIAL) #include "usb_serial.h" -#elif defined(USB_BENCHMARK) +#endif + +#if defined(USB_BENCHMARK) #include "usb_benchmark.h" #endif +/* TODO: Move this target-specific stuff somewhere else (serial number reading) */ + +#ifdef HAVE_AS3514 +#include "i2c-pp.h" +#include "as3514.h" +#endif + + /*-------------------------------------------------------------------------*/ /* USB protocol descriptors: */ #define USB_SC_SCSI 0x06 /* Transparent */ #define USB_PROT_BULK 0x50 /* bulk only */ -int usb_max_pkt_size = 512; - -static const struct usb_device_descriptor device_descriptor = { +static const struct usb_device_descriptor device_descriptor= { .bLength = sizeof(struct usb_device_descriptor), .bDescriptorType = USB_DT_DEVICE, - .bcdUSB = 0x0200, /* USB version 2.0 */ + .bcdUSB = 0x0200, .bDeviceClass = USB_CLASS_PER_INTERFACE, .bDeviceSubClass = 0, .bDeviceProtocol = 0, @@ -74,158 +72,34 @@ static const struct usb_device_descriptor device_descriptor = { .bNumConfigurations = 1 }; -static const struct { +static struct { struct usb_config_descriptor config_descriptor; - struct usb_interface_descriptor interface_descriptor; - struct usb_endpoint_descriptor ep1_in_descriptor; - struct usb_endpoint_descriptor ep1_out_descriptor; -} config_data_fs = -{ - { - .bLength = sizeof(struct usb_config_descriptor), - .bDescriptorType = USB_DT_CONFIG, - .wTotalLength = sizeof config_data_fs, - .bNumInterfaces = 1, - .bConfigurationValue = 1, - .iConfiguration = 0, - .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER, - .bMaxPower = 250, /* 500mA in 2mA units */ - }, - #ifdef USB_CHARGING_ONLY - /* dummy interface for charging-only */ - { - .bLength = sizeof(struct usb_interface_descriptor), - .bDescriptorType = USB_DT_INTERFACE, - .bInterfaceNumber = 0, - .bAlternateSetting = 0, - .bNumEndpoints = 2, - .bInterfaceClass = USB_CLASS_VENDOR_SPEC, - .bInterfaceSubClass = 0, - .bInterfaceProtocol = 0, - .iInterface = 5 - }, - - { - .bLength = sizeof(struct usb_endpoint_descriptor), - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = EP_TX | USB_DIR_IN, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = 512, - .bInterval = 0 - }, - { - .bLength = sizeof(struct usb_endpoint_descriptor), - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = EP_RX | USB_DIR_OUT, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = 512, - .bInterval = 0 - } + struct usb_interface_descriptor charging_interface_descriptor; + struct usb_endpoint_descriptor charging_ep_in_descriptor; + struct usb_endpoint_descriptor charging_ep_out_descriptor; #endif - #ifdef USB_STORAGE - /* storage interface */ - { - .bLength = sizeof(struct usb_interface_descriptor), - .bDescriptorType = USB_DT_INTERFACE, - .bInterfaceNumber = 0, - .bAlternateSetting = 0, - .bNumEndpoints = 2, - .bInterfaceClass = USB_CLASS_MASS_STORAGE, - .bInterfaceSubClass = USB_SC_SCSI, - .bInterfaceProtocol = USB_PROT_BULK, - .iInterface = 0 - }, - - { - .bLength = sizeof(struct usb_endpoint_descriptor), - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = EP_TX | USB_DIR_IN, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = 16, - .bInterval = 0 - }, - { - .bLength = sizeof(struct usb_endpoint_descriptor), - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = EP_RX | USB_DIR_OUT, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = 16, - .bInterval = 0 - } + struct usb_interface_descriptor mass_storage_interface_descriptor; + struct usb_endpoint_descriptor mass_storage_ep_in_descriptor; + struct usb_endpoint_descriptor mass_storage_ep_out_descriptor; #endif - #ifdef USB_SERIAL - /* serial interface */ - { - .bLength = sizeof(struct usb_interface_descriptor), - .bDescriptorType = USB_DT_INTERFACE, - .bInterfaceNumber = 0, - .bAlternateSetting = 0, - .bNumEndpoints = 2, - .bInterfaceClass = USB_CLASS_CDC_DATA, - .bInterfaceSubClass = 0, - .bInterfaceProtocol = 0, - .iInterface = 0 - }, - - { - .bLength = sizeof(struct usb_endpoint_descriptor), - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = EP_TX | USB_DIR_IN, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = 64, - .bInterval = 0 - }, - { - .bLength = sizeof(struct usb_endpoint_descriptor), - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = EP_RX | USB_DIR_OUT, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = 64, - .bInterval = 0 - } + struct usb_interface_descriptor serial_interface_descriptor; + struct usb_endpoint_descriptor serial_ep_in_descriptor; + struct usb_endpoint_descriptor serial_ep_out_descriptor; #endif - #ifdef USB_BENCHMARK - /* bulk test interface */ - { - .bLength = sizeof(struct usb_interface_descriptor), - .bDescriptorType = USB_DT_INTERFACE, - .bInterfaceNumber = 0, - .bAlternateSetting = 0, - .bNumEndpoints = 2, - .bInterfaceClass = USB_CLASS_VENDOR_SPEC, - .bInterfaceSubClass = 255, - .bInterfaceProtocol = 255, - .iInterface = 4 - }, - - { - .bLength = sizeof(struct usb_endpoint_descriptor), - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = EP_RX | USB_DIR_OUT, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = 64, - .bInterval = 0 - }, - { - .bLength = sizeof(struct usb_endpoint_descriptor), - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = EP_TX | USB_DIR_IN, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = 64, - .bInterval = 0 - } + struct usb_interface_descriptor benchmark_interface_descriptor; + struct usb_endpoint_descriptor benchmark_ep_in_descriptor; + struct usb_endpoint_descriptor benchmark_ep_out_descriptor; #endif -}, -config_data_hs = +} __attribute__((packed)) *config_data, _config_data = { { .bLength = sizeof(struct usb_config_descriptor), .bDescriptorType = USB_DT_CONFIG, - .wTotalLength = sizeof config_data_hs, + .wTotalLength = sizeof _config_data, .bNumInterfaces = 1, .bConfigurationValue = 1, .iConfiguration = 0, @@ -246,23 +120,23 @@ config_data_hs = .bInterfaceProtocol = 0, .iInterface = 5 }, - +/* TODO: try with zero endpoints */ { .bLength = sizeof(struct usb_endpoint_descriptor), .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = EP_TX | USB_DIR_IN, + .bEndpointAddress = EP_CHARGING_ONLY | USB_DIR_IN, .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = 512, + .wMaxPacketSize = 16, .bInterval = 0 }, { .bLength = sizeof(struct usb_endpoint_descriptor), .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = EP_RX | USB_DIR_OUT, + .bEndpointAddress = EP_CHARGING_ONLY | USB_DIR_OUT, .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = 512, + .wMaxPacketSize = 16, .bInterval = 0 - } + }, #endif #ifdef USB_STORAGE @@ -282,19 +156,19 @@ config_data_hs = { .bLength = sizeof(struct usb_endpoint_descriptor), .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = EP_TX | USB_DIR_IN, + .bEndpointAddress = EP_MASS_STORAGE | USB_DIR_IN, .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = 512, + .wMaxPacketSize = 16, .bInterval = 0 }, { .bLength = sizeof(struct usb_endpoint_descriptor), .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = EP_RX | USB_DIR_OUT, + .bEndpointAddress = EP_MASS_STORAGE | USB_DIR_OUT, .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = 512, + .wMaxPacketSize = 16, .bInterval = 0 - } + }, #endif #ifdef USB_SERIAL @@ -314,19 +188,19 @@ config_data_hs = { .bLength = sizeof(struct usb_endpoint_descriptor), .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = EP_TX | USB_DIR_IN, + .bEndpointAddress = EP_SERIAL | USB_DIR_IN, .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = 512, + .wMaxPacketSize = 16, .bInterval = 0 }, { .bLength = sizeof(struct usb_endpoint_descriptor), .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = EP_RX | USB_DIR_OUT, + .bEndpointAddress = EP_SERIAL | USB_DIR_OUT, .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = 512, + .wMaxPacketSize = 16, .bInterval = 0 - } + }, #endif #ifdef USB_BENCHMARK @@ -346,19 +220,19 @@ config_data_hs = { .bLength = sizeof(struct usb_endpoint_descriptor), .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = EP_RX | USB_DIR_OUT, + .bEndpointAddress = EP_BENCHMARK | USB_DIR_OUT, .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = 512, + .wMaxPacketSize = 16, .bInterval = 0 }, { .bLength = sizeof(struct usb_endpoint_descriptor), .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = EP_TX | USB_DIR_IN, + .bEndpointAddress = EP_BENCHMARK | USB_DIR_IN, .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = 512, + .wMaxPacketSize = 16, .bInterval = 0 - } + }, #endif }; @@ -388,13 +262,22 @@ static struct usb_string_descriptor usb_string_iProduct = {'R','o','c','k','b','o','x',' ','m','e','d','i','a',' ','p','l','a','y','e','r'} }; +#if defined(HAVE_AS3514) static struct usb_string_descriptor usb_string_iSerial = { - 34, - USB_DT_STRING, - {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'} + 66, + USB_DT_STRING, + {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0', + '0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'} }; - +#else +static struct usb_string_descriptor usb_string_iSerial = +{ + 34, + USB_DT_STRING, + {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'} + }; +#endif /* Generic for all targets */ @@ -443,10 +326,25 @@ static long usbcore_stack[DEFAULT_STACK_SIZE]; static void usb_core_thread(void); #endif -static void ack_control(struct usb_ctrlrequest* req); +static void usb_core_control_request_handler(struct usb_ctrlrequest* req); +static int ack_control(struct usb_ctrlrequest* req); + +static unsigned char *response_data; +static unsigned char __response_data[CACHEALIGN_UP(2)] CACHEALIGN_ATTR; + +struct usb_core_event +{ + unsigned char endpoint; + bool in; + int status; + int length; + void* data; +}; + +static struct usb_core_event events[NUM_ENDPOINTS]; #ifdef IPOD_ARCH -void set_serial_descriptor(void) +static void set_serial_descriptor(void) { static short hex[16] = {'0','1','2','3','4','5','6','7', '8','9','A','B','C','D','E','F'}; @@ -471,7 +369,23 @@ void set_serial_descriptor(void) x >>= 4; } } +} +#elif defined(HAVE_AS3514) +static void set_serial_descriptor(void) +{ + static short hex[16] = {'0','1','2','3','4','5','6','7', + '8','9','A','B','C','D','E','F'}; + unsigned char serial[16]; + short* p = usb_string_iSerial.wString; + int i; + + i2c_readbytes(AS3514_I2C_ADDR, 0x30, 0x10, serial); + for (i = 0; i < 16; i++) + { + *p++ = hex[(serial[i] >> 4) & 0xF]; + *p++ = hex[(serial[i] >> 0) & 0xF]; + } } #endif @@ -480,9 +394,8 @@ void usb_core_init(void) if (initialized) return; -#ifdef IPOD_ARCH - set_serial_descriptor(); -#endif + config_data = (void*)UNCACHED_ADDR(&_config_data); + response_data = (void*)UNCACHED_ADDR(&__response_data); queue_init(&usbcore_queue, false); usb_drv_init(); @@ -514,10 +427,11 @@ void usb_core_exit(void) { if (initialized) { usb_drv_exit(); - queue_delete(&usbcore_queue); #ifdef USB_THREAD - remove_thread(usbcore_thread); + queue_post(&usbcore_queue, USB_CORE_QUIT, 0); + thread_wait(usbcore_thread); #endif + queue_delete(&usbcore_queue); } data_connection = false; initialized = false; @@ -532,25 +446,52 @@ bool usb_core_data_connection(void) #ifdef USB_THREAD void usb_core_thread(void) { +#if defined(IPOD_ARCH) || defined(HAVE_AS3514) + set_serial_descriptor(); +#endif + while (1) { struct queue_event ev; queue_wait(&usbcore_queue, &ev); + if (ev.id == USB_CORE_QUIT) { + cancel_cpu_boost(); + return; + } + if (ev.id == USB_CORE_TRANSFER_COMPLETION) { + struct usb_core_event* event = (struct usb_core_event*)ev.data; + switch(event->endpoint) { + case EP_CONTROL: + logf("ctrl handled %ld",current_tick); + usb_core_control_request_handler((struct usb_ctrlrequest*)event->data); + break; #ifdef USB_STORAGE - usb_storage_transfer_complete(ev.id); + case EP_MASS_STORAGE: + usb_storage_transfer_complete(event->in,event->status,event->length); + break; #endif - #ifdef USB_SERIAL - usb_serial_transfer_complete(ev.id); + case EP_SERIAL: + usb_serial_transfer_complete(event->in,event->status,event->length); + break; #endif - +#ifdef USB_BENCHMARK + case EP_BENCHMARK: + usb_benchmark_transfer_complete(event->in); + break; +#endif +#ifdef USB_CHARGING_ONLY + case EP_CHARGING_ONLY: + break; +#endif + } + } } } #endif -/* called by usb_drv_int() */ -void usb_core_control_request(struct usb_ctrlrequest* req) +static void usb_core_control_request_handler(struct usb_ctrlrequest* req) { /* note: interrupt context */ data_connection = true; @@ -565,29 +506,31 @@ void usb_core_control_request(struct usb_ctrlrequest* req) switch (req->bRequest) { case USB_REQ_SET_CONFIGURATION: logf("usb_core: SET_CONFIG"); + usb_drv_cancel_all_transfers(); + if (req->wValue){ + usb_state = CONFIGURED; #ifdef USB_STORAGE - usb_storage_control_request(req); + usb_storage_control_request(req); #endif #ifdef USB_SERIAL - usb_serial_control_request(req); + usb_serial_control_request(req); #endif - ack_control(req); - if (req->wValue) - usb_state = CONFIGURED; - else + } + else { usb_state = ADDRESS; + } + ack_control(req); break; case USB_REQ_GET_CONFIGURATION: { - static char confignum; - char* tmp = (void*)UNCACHED_ADDR(&confignum); logf("usb_core: GET_CONFIG"); if (usb_state == ADDRESS) - *tmp = 0; + response_data[0] = 0; else - *tmp = 1; - usb_drv_send(EP_CONTROL, tmp, 1); + response_data[0] = 1; + if(usb_drv_send(EP_CONTROL, response_data, 1)!= 0) + break; ack_control(req); break; } @@ -597,29 +540,54 @@ void usb_core_control_request(struct usb_ctrlrequest* req) ack_control(req); break; + case USB_REQ_GET_INTERFACE: + logf("usb_core: GET_INTERFACE"); + response_data[0] = 0; + if(usb_drv_send(EP_CONTROL, response_data, 1)!=0) + break; + ack_control(req); + break; case USB_REQ_CLEAR_FEATURE: logf("usb_core: CLEAR_FEATURE"); if (req->wValue) - usb_drv_stall(req->wIndex, true); + usb_drv_stall(req->wIndex & 0xf, false,(req->wIndex & 0x80) !=0); else - usb_drv_stall(req->wIndex, false); + usb_drv_stall(req->wIndex & 0xf, false,(req->wIndex & 0x80) !=0); ack_control(req); break; - case USB_REQ_SET_ADDRESS: - usb_address = req->wValue; - logf("usb_core: SET_ADR %d", usb_address); + case USB_REQ_SET_FEATURE: + logf("usb_core: SET_FEATURE"); + if (req->wValue) + usb_drv_stall(req->wIndex & 0xf, true,(req->wIndex & 0x80) !=0); + else + usb_drv_stall(req->wIndex & 0xf, false,(req->wIndex & 0x80) !=0); ack_control(req); + break; + + case USB_REQ_SET_ADDRESS: { + unsigned char address = req->wValue; + logf("usb_core: SET_ADR %d", address); + if(ack_control(req)!=0) + break; + usb_drv_cancel_all_transfers(); + usb_address = address; usb_drv_set_address(usb_address); usb_state = ADDRESS; break; + } case USB_REQ_GET_STATUS: { - static char tmp[2] = {0,0}; - tmp[0] = 0; - tmp[1] = 0; + response_data[0]= 0; + response_data[1]= 0; logf("usb_core: GET_STATUS"); - usb_drv_send(EP_CONTROL, UNCACHED_ADDR(&tmp), 2); + if(req->wIndex>0) { + if(usb_drv_stalled(req->wIndex&0xf,(req->wIndex&0x80)!=0)) + response_data[0] = 1; + } + logf("usb_core: %X %X",response_data[0],response_data[1]); + if(usb_drv_send(EP_CONTROL, response_data, 2)!=0) + break; ack_control(req); break; } @@ -637,18 +605,59 @@ void usb_core_control_request(struct usb_ctrlrequest* req) size = sizeof device_descriptor; break; - case USB_DT_CONFIG: - if(usb_drv_port_speed()) - { - ptr = &config_data_hs; - size = sizeof config_data_hs; + case USB_DT_OTHER_SPEED_CONFIG: + case USB_DT_CONFIG: { + int max_packet_size; + int interface_number=0; + + if(req->wValue >> 8 == USB_DT_CONFIG) { + if(usb_drv_port_speed()) { + max_packet_size=512; + } + else { + max_packet_size=64; + } + config_data->config_descriptor.bDescriptorType=USB_DT_CONFIG; } - else - { - ptr = &config_data_fs; - size = sizeof config_data_fs; + else { + if(usb_drv_port_speed()) { + max_packet_size=64; + } + else { + max_packet_size=512; + } + config_data->config_descriptor.bDescriptorType=USB_DT_OTHER_SPEED_CONFIG; } + +#ifdef USB_CHARGING_ONLY + memcpy(&config_data->charging_ep_in_descriptor.wMaxPacketSize,&max_packet_size,sizeof(unsigned short)); + memcpy(&config_data->charging_ep_out_descriptor.wMaxPacketSize,&max_packet_size,sizeof(unsigned short)); + config_data->charging_interface_descriptor.bInterfaceNumber=interface_number; + interface_number++; +#endif +#ifdef USB_STORAGE + memcpy(&config_data->mass_storage_ep_in_descriptor.wMaxPacketSize,&max_packet_size,sizeof(unsigned short)); + memcpy(&config_data->mass_storage_ep_out_descriptor.wMaxPacketSize,&max_packet_size,sizeof(unsigned short)); + config_data->mass_storage_interface_descriptor.bInterfaceNumber=interface_number; + interface_number++; +#endif +#ifdef USB_SERIAL + memcpy(&config_data->serial_ep_in_descriptor.wMaxPacketSize,&max_packet_size,sizeof(unsigned short)); + memcpy(&config_data->serial_ep_out_descriptor.wMaxPacketSize,&max_packet_size,sizeof(unsigned short)); + config_data->serial_interface_descriptor.bInterfaceNumber=interface_number; + interface_number++; +#endif +#ifdef USB_BENCHMARK + memcpy(&config_data->benchmark_ep_in_descriptor.wMaxPacketSize,&max_packet_size,sizeof(unsigned short)); + memcpy(&config_data->benchmark_ep_out_descriptor.wMaxPacketSize,&max_packet_size,sizeof(unsigned short)); + config_data.benchmark_interface_descriptor.bInterfaceNumber=interface_number; + interface_number++; +#endif + config_data->config_descriptor.bNumInterfaces=interface_number; + ptr = config_data; + size = sizeof _config_data; break; + } case USB_DT_STRING: if ((unsigned)index < (sizeof(usb_strings)/sizeof(struct usb_string_descriptor*))) { @@ -657,7 +666,7 @@ void usb_core_control_request(struct usb_ctrlrequest* req) } else { logf("bad string id %d", index); - usb_drv_stall(EP_CONTROL, true); + usb_drv_stall(EP_CONTROL, true,true); } break; @@ -668,13 +677,14 @@ void usb_core_control_request(struct usb_ctrlrequest* req) default: logf("bad desc %d", req->wValue >> 8); - usb_drv_stall(EP_CONTROL, true); + usb_drv_stall(EP_CONTROL, true,true); break; } if (ptr) { length = MIN(size, length); - usb_drv_send(EP_CONTROL, (void*)UNCACHED_ADDR(ptr), length); + if(usb_drv_send(EP_CONTROL, (void*)UNCACHED_ADDR(ptr), length)!=0) + break; } ack_control(req); break; @@ -693,7 +703,7 @@ void usb_core_control_request(struct usb_ctrlrequest* req) { /* nope. flag error */ logf("usb bad req %d", req->bRequest); - usb_drv_stall(EP_CONTROL, true); + usb_drv_stall(EP_CONTROL, true,true); ack_control(req); } break; @@ -709,9 +719,9 @@ void usb_core_bus_reset(void) } /* called by usb_drv_transfer_completed() */ -void usb_core_transfer_complete(int endpoint, bool in) +void usb_core_transfer_complete(int endpoint, bool in, int status,int length) { -#ifdef USB_CHARGING_ONLY +#if defined(USB_CHARGING_ONLY) || defined(USB_STORAGE) (void)in; #endif @@ -720,25 +730,35 @@ void usb_core_transfer_complete(int endpoint, bool in) /* already handled */ break; - case EP_RX: - case EP_TX: -#if defined(USB_BENCHMARK) - usb_benchmark_transfer_complete(endpoint, in); -#elif defined(USB_STORAGE) || defined(USB_SERIAL) - queue_post(&usbcore_queue, endpoint, 0); -#endif - break; - default: + events[endpoint].endpoint=endpoint; + events[endpoint].in=in; + events[endpoint].data=0; + events[endpoint].status=status; + events[endpoint].length=length; + /* All other endoints. Let the thread deal with it */ + queue_post(&usbcore_queue, USB_CORE_TRANSFER_COMPLETION, (intptr_t)&events[endpoint]); break; } } -static void ack_control(struct usb_ctrlrequest* req) +/* called by usb_drv_int() */ +void usb_core_control_request(struct usb_ctrlrequest* req) +{ + events[0].endpoint=0; + events[0].in=0; + events[0].data=(void *)req; + events[0].status=0; + events[0].length=0; + logf("ctrl received %ld",current_tick); + queue_post(&usbcore_queue, USB_CORE_TRANSFER_COMPLETION,(intptr_t)&events[0]); +} + +static int ack_control(struct usb_ctrlrequest* req) { if (req->bRequestType & 0x80) - usb_drv_recv(EP_CONTROL, NULL, 0); + return usb_drv_recv(EP_CONTROL, NULL, 0); else - usb_drv_send(EP_CONTROL, NULL, 0); + return usb_drv_send(EP_CONTROL, NULL, 0); } |