diff options
author | Frank Gevaerts <frank@gevaerts.be> | 2008-10-03 22:43:16 +0000 |
---|---|---|
committer | Frank Gevaerts <frank@gevaerts.be> | 2008-10-03 22:43:16 +0000 |
commit | 478fc5baed82e5573938041aed0f1a4f73f32128 (patch) | |
tree | b7115cb1200101075bf93d93f61bd0be65ff9d42 /firmware | |
parent | 6219f4c862919367972e497c47324121fe48f3f6 (diff) | |
download | rockbox-478fc5baed82e5573938041aed0f1a4f73f32128.tar.gz rockbox-478fc5baed82e5573938041aed0f1a4f73f32128.zip |
reorganise the USB stack a bit to allow for easier integration of non-ARC controller drivers
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@18703 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/export/usb.h | 2 | ||||
-rw-r--r-- | firmware/export/usb_core.h | 8 | ||||
-rw-r--r-- | firmware/export/usb_drv.h | 2 | ||||
-rw-r--r-- | firmware/target/arm/usb-drv-arc.c | 49 | ||||
-rw-r--r-- | firmware/usbstack/usb_charging_only.c | 7 | ||||
-rw-r--r-- | firmware/usbstack/usb_charging_only.h | 2 | ||||
-rw-r--r-- | firmware/usbstack/usb_class_driver.h | 13 | ||||
-rw-r--r-- | firmware/usbstack/usb_core.c | 84 | ||||
-rw-r--r-- | firmware/usbstack/usb_serial.c | 39 | ||||
-rw-r--r-- | firmware/usbstack/usb_serial.h | 4 | ||||
-rw-r--r-- | firmware/usbstack/usb_storage.c | 70 | ||||
-rw-r--r-- | firmware/usbstack/usb_storage.h | 4 |
12 files changed, 185 insertions, 99 deletions
diff --git a/firmware/export/usb.h b/firmware/export/usb.h index 9952a074bb..08ae27999a 100644 --- a/firmware/export/usb.h +++ b/firmware/export/usb.h @@ -85,7 +85,7 @@ enum { struct usb_transfer_completion_event_data { unsigned char endpoint; - bool in; + int dir; int status; int length; void* data; diff --git a/firmware/export/usb_core.h b/firmware/export/usb_core.h index 6aada54399..9d9e327bb3 100644 --- a/firmware/export/usb_core.h +++ b/firmware/export/usb_core.h @@ -45,10 +45,12 @@ extern int usb_max_pkt_size; +struct usb_class_driver; + void usb_core_init(void); void usb_core_exit(void); void usb_core_control_request(struct usb_ctrlrequest* req); -void usb_core_transfer_complete(int endpoint, bool in, int status, int length); +void usb_core_transfer_complete(int endpoint, int dir, int status, int length); void usb_core_bus_reset(void); bool usb_core_exclusive_connection(void); void usb_core_enable_driver(int driver,bool enabled); @@ -56,6 +58,10 @@ 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 dir, struct usb_class_driver *drv); +void usb_core_release_endpoint(int dir); + #ifdef HAVE_HOTSWAP void usb_core_hotswap_event(int volume,bool inserted); #endif diff --git a/firmware/export/usb_drv.h b/firmware/export/usb_drv.h index 3db82efd6a..3bd8e1fdf4 100644 --- a/firmware/export/usb_drv.h +++ b/firmware/export/usb_drv.h @@ -41,5 +41,7 @@ int usb_drv_port_speed(void); void usb_drv_cancel_all_transfers(void); void usb_drv_set_test_mode(int mode); bool usb_drv_connected(void); +int usb_drv_request_endpoint(int dir); +void usb_drv_release_endpoint(int ep); #endif diff --git a/firmware/target/arm/usb-drv-arc.c b/firmware/target/arm/usb-drv-arc.c index a30e1c5139..529f6cf7f8 100644 --- a/firmware/target/arm/usb-drv-arc.c +++ b/firmware/target/arm/usb-drv-arc.c @@ -363,6 +363,8 @@ static const unsigned int pipe2mask[] = { 0x10, 0x100000, }; +static char ep_allocation[NUM_ENDPOINTS]; + /*-------------------------------------------------------------------------*/ static void transfer_completed(void); static void control_received(void); @@ -534,23 +536,23 @@ void usb_drv_int(void) bool usb_drv_stalled(int endpoint,bool in) { if(in) { - return ((REG_ENDPTCTRL(endpoint) & EPCTRL_TX_EP_STALL)!=0); + return ((REG_ENDPTCTRL(endpoint&0x7f) & EPCTRL_TX_EP_STALL)!=0); } else { - return ((REG_ENDPTCTRL(endpoint) & EPCTRL_RX_EP_STALL)!=0); + return ((REG_ENDPTCTRL(endpoint&0x7f) & EPCTRL_RX_EP_STALL)!=0); } } void usb_drv_stall(int endpoint, bool stall,bool in) { - logf("%sstall %d", stall?"":"un", endpoint); + logf("%sstall %d", stall?"":"un", endpoint&0x7f); if(in) { if (stall) { - REG_ENDPTCTRL(endpoint) |= EPCTRL_TX_EP_STALL; + REG_ENDPTCTRL(endpoint&0x7f) |= EPCTRL_TX_EP_STALL; } else { - REG_ENDPTCTRL(endpoint) &= ~EPCTRL_TX_EP_STALL; + REG_ENDPTCTRL(endpoint&0x7f) &= ~EPCTRL_TX_EP_STALL; } } else { @@ -565,23 +567,23 @@ void usb_drv_stall(int endpoint, bool stall,bool in) int usb_drv_send_nonblocking(int endpoint, void* ptr, int length) { - return prime_transfer(endpoint, ptr, length, true, false); + return prime_transfer(endpoint&0x7f, ptr, length, true, false); } int usb_drv_send(int endpoint, void* ptr, int length) { - return prime_transfer(endpoint, ptr, length, true, true); + return prime_transfer(endpoint&0x7f, ptr, length, true, true); } int usb_drv_recv(int endpoint, void* ptr, int length) { //logf("usbrecv(%x, %d)", ptr, length); - return prime_transfer(endpoint, ptr, length, false, false); + return prime_transfer(endpoint&0x7f, ptr, length, false, false); } void usb_drv_wait(int endpoint, bool send) { - int pipe = endpoint * 2 + (send ? 1 : 0); + int pipe = (endpoint&0x7f) * 2 + (send ? 1 : 0); struct queue_head* qh = &qh_array[pipe]; while (qh->dtd.size_ioc_sts & QH_STATUS_ACTIVE) { @@ -609,7 +611,7 @@ void usb_drv_set_address(int address) void usb_drv_reset_endpoint(int endpoint, bool send) { - int pipe = endpoint * 2 + (send ? 1 : 0); + int pipe = (endpoint&0x7f) * 2 + (send ? 1 : 0); unsigned int mask = pipe2mask[pipe]; REG_ENDPTFLUSH = mask; while (REG_ENDPTFLUSH & mask); @@ -753,6 +755,29 @@ void usb_drv_cancel_all_transfers(void) } } +int usb_drv_request_endpoint(int dir) +{ + int i, bit; + + bit=(dir & USB_DIR_IN)? 2:1; + + for (i=1; i < NUM_ENDPOINTS; i++) { + if((ep_allocation[i] & bit)!=0) + continue; + ep_allocation[i] |= bit; + return i | dir; + } + + return -1; +} + +void usb_drv_release_endpoint(int ep) +{ + int mask = (ep & USB_DIR_IN)? ~2:~1; + ep_allocation[ep & 0x7f] &= mask; +} + + static void prepare_td(struct transfer_descriptor* td, struct transfer_descriptor* previous_td, void *ptr, int len,int pipe) @@ -831,7 +856,7 @@ static void transfer_completed(void) qh->wait=0; wakeup_signal(&transfer_completion_signal[pipe]); } - usb_core_transfer_complete(ep, dir, qh->status, qh->length); + usb_core_transfer_complete(ep, dir?USB_DIR_IN:USB_DIR_OUT, qh->status, qh->length); } } } @@ -900,6 +925,7 @@ static void init_bulk_queue_heads(void) rx_packetsize = 64; tx_packetsize = 64; } + /* TODO: this should take ep_allocation into account */ /*** bulk ***/ for(i=1;i<NUM_ENDPOINTS;i++) { @@ -913,6 +939,7 @@ static void init_bulk_queue_heads(void) static void init_endpoints(void) { int i; + /* TODO: this should take ep_allocation into account */ /* bulk */ for(i=1;i<NUM_ENDPOINTS;i++) { REG_ENDPTCTRL(i) = diff --git a/firmware/usbstack/usb_charging_only.c b/firmware/usbstack/usb_charging_only.c index 8cce4fcef3..e20d1885a0 100644 --- a/firmware/usbstack/usb_charging_only.c +++ b/firmware/usbstack/usb_charging_only.c @@ -48,11 +48,12 @@ static struct usb_interface_descriptor __attribute__((aligned(2))) static int usb_interface; -int usb_charging_only_set_first_endpoint(int endpoint) +int usb_charging_only_request_endpoints(struct usb_class_driver *drv) { - /* The dummy charging_only driver doesn't need an endpoint pair */ - return endpoint; + (void) drv; + return 0; } + int usb_charging_only_set_first_interface(int interface) { usb_interface = interface; diff --git a/firmware/usbstack/usb_charging_only.h b/firmware/usbstack/usb_charging_only.h index 65ab7df4c1..8bdf58ff1d 100644 --- a/firmware/usbstack/usb_charging_only.h +++ b/firmware/usbstack/usb_charging_only.h @@ -24,7 +24,7 @@ #include "usb_ch9.h" void usb_charging_only_init(void); -int usb_charging_only_set_first_endpoint(int endpoint); +int usb_charging_only_request_endpoints(struct usb_class_driver *); int usb_charging_only_set_first_interface(int interface); int usb_charging_only_get_config_descriptor(unsigned char *dest,int max_packet_size); bool usb_charging_only_control_request(struct usb_ctrlrequest* req); diff --git a/firmware/usbstack/usb_class_driver.h b/firmware/usbstack/usb_class_driver.h index bda0b7663c..e089c488a8 100644 --- a/firmware/usbstack/usb_class_driver.h +++ b/firmware/usbstack/usb_class_driver.h @@ -35,6 +35,9 @@ struct usb_class_driver { /* Set this to true if the driver needs exclusive disk access (e.g. usb storage) */ bool needs_exclusive_ata; + /* Let the driver request endpoints it need. Returns zero on success */ + int (*request_endpoints)(struct usb_class_driver *); + /* Tells the driver what its first interface number will be. The driver returns the number of the first available interface for the next driver (i.e. a driver with one interface will return interface+1) @@ -42,12 +45,6 @@ struct usb_class_driver { Mandatory function */ int (*set_first_interface)(int interface); - /* Tells the driver what its first endpoint pair number will be. The driver - returns the number of the first available endpoint pair for the next - driver (i.e. a driver with one endpoint pair will return endpoint +1) - Mandatory function */ - int (*set_first_endpoint)(int endpoint); - /* Asks the driver to put the interface descriptor and all other needed descriptor for this driver at dest. Returns the number of bytes taken by these descriptors. @@ -69,10 +66,10 @@ struct usb_class_driver { Optional function */ void (*disconnect)(void); - /* Tells the driver that a usb transfer has been completed. Note that "in" + /* Tells the driver that a usb transfer has been completed. Note that "dir" is relative to the host Optional function */ - void (*transfer_complete)(int ep,bool in, int status, int length); + void (*transfer_complete)(int ep,int dir, int status, int length); /* Tells the driver that a control request has come in. If the driver is able to handle it, it should ack the request, and return true. Otherwise diff --git a/firmware/usbstack/usb_core.c b/firmware/usbstack/usb_core.c index d26610d82b..afdf0b176f 100644 --- a/firmware/usbstack/usb_core.c +++ b/firmware/usbstack/usb_core.c @@ -22,7 +22,7 @@ #include "thread.h" #include "kernel.h" #include "string.h" -//#define LOGF_ENABLE +#define LOGF_ENABLE #include "logf.h" #include "usb.h" @@ -164,10 +164,13 @@ static enum { DEFAULT, ADDRESS, CONFIGURED } usb_state; static int usb_core_num_interfaces; +typedef void (*completion_handler_t)(int ep,int dir, int status, int length); +typedef bool (*control_handler_t)(struct usb_ctrlrequest* req); + static struct { - void (*completion_handler)(int ep,bool in, int status, int length); - bool (*control_handler)(struct usb_ctrlrequest* req); + completion_handler_t completion_handler[2]; + control_handler_t control_handler[2]; struct usb_transfer_completion_event_data completion_event; } ep_data[NUM_ENDPOINTS]; @@ -179,8 +182,8 @@ static struct usb_class_driver drivers[USB_NUM_DRIVERS] = .needs_exclusive_ata = true, .first_interface = 0, .last_interface = 0, + .request_endpoints = usb_storage_request_endpoints, .set_first_interface = usb_storage_set_first_interface, - .set_first_endpoint = usb_storage_set_first_endpoint, .get_config_descriptor = usb_storage_get_config_descriptor, .init_connection = usb_storage_init_connection, .init = usb_storage_init, @@ -198,8 +201,8 @@ static struct usb_class_driver drivers[USB_NUM_DRIVERS] = .needs_exclusive_ata = false, .first_interface = 0, .last_interface = 0, + .request_endpoints = usb_serial_request_endpoints, .set_first_interface = usb_serial_set_first_interface, - .set_first_endpoint = usb_serial_set_first_endpoint, .get_config_descriptor = usb_serial_get_config_descriptor, .init_connection = usb_serial_init_connection, .init = usb_serial_init, @@ -217,8 +220,8 @@ static struct usb_class_driver drivers[USB_NUM_DRIVERS] = .needs_exclusive_ata = false, .first_interface = 0, .last_interface = 0, + .request_endpoints = usb_charging_only_request_endpoints, .set_first_interface = usb_charging_only_set_first_interface, - .set_first_endpoint = usb_charging_only_set_first_endpoint, .get_config_descriptor = usb_charging_only_get_config_descriptor, .init_connection = NULL, .init = NULL, @@ -339,6 +342,7 @@ void usb_core_handle_transfer_completion( struct usb_transfer_completion_event_data* event) { int ep = event->endpoint; + switch(ep) { case EP_CONTROL: logf("ctrl handled %ld",current_tick); @@ -346,8 +350,8 @@ void usb_core_handle_transfer_completion( (struct usb_ctrlrequest*)event->data); break; default: - if(ep_data[ep].completion_handler != NULL) - ep_data[ep].completion_handler(ep,event->in, + if(ep_data[ep].completion_handler[event->dir>>7] != NULL) + ep_data[ep].completion_handler[event->dir>>7](ep,event->dir, event->status,event->length); break; } @@ -388,34 +392,60 @@ static void usb_core_set_serial_function_id(void) usb_string_iSerial.wString[0] = hex[id]; } +int usb_core_request_endpoint(int dir, struct usb_class_driver *drv) +{ + int ret, ep; + + ret = usb_drv_request_endpoint(dir); + + if (ret == -1) + return -1; + + ep = ret & 0x7f; + dir = ret >> 7; + + ep_data[ep].completion_handler[dir] = drv->transfer_complete; + ep_data[ep].control_handler[dir] = drv->control_request; + + return ret; +} + +void usb_core_release_endpoint(int ep) +{ + int dir; + + usb_drv_release_endpoint(ep); + + dir = ep >> 7; + ep &= 0x7f; + + ep_data[ep].completion_handler[dir] = NULL; + ep_data[ep].control_handler[dir] = NULL; +} + static void allocate_interfaces_and_endpoints(void) { - int i,j; + int i; int interface=0; - int endpoint=1; memset(ep_data,0,sizeof(ep_data)); - for(i=0;i<USB_NUM_DRIVERS;i++) { + for (i = 0; i < NUM_ENDPOINTS; i++) { + usb_drv_release_endpoint(i | USB_DIR_OUT); + usb_drv_release_endpoint(i | USB_DIR_IN); + } + + for(i=0; i < USB_NUM_DRIVERS; i++) { if(drivers[i].enabled) { - int oldendpoint = endpoint; drivers[i].first_interface = interface; - endpoint = drivers[i].set_first_endpoint(endpoint); - if(endpoint>NUM_ENDPOINTS) { + if (drivers[i].request_endpoints(&drivers[i])) { drivers[i].enabled = false; continue; } + interface = drivers[i].set_first_interface(interface); drivers[i].last_interface = interface; - - for(j=oldendpoint;j<endpoint;j++) { - ep_data[j].completion_handler=drivers[i].transfer_complete; - ep_data[j].control_handler=drivers[i].control_request; - } - } - if(endpoint>NUM_ENDPOINTS) { - drivers[i].enabled = false; } } usb_core_num_interfaces = interface; @@ -666,8 +696,8 @@ static void usb_core_control_request_handler(struct usb_ctrlrequest* req) break; default: { bool handled=false; - if(ep_data[req->wIndex & 0xf].control_handler != NULL) - handled = ep_data[req->wIndex & 0xf].control_handler(req); + if(ep_data[req->wIndex & 0xf].control_handler[0] != NULL) + handled = ep_data[req->wIndex & 0xf].control_handler[0](req); if(!handled) { /* nope. flag error */ logf("usb bad req %d", req->bRequest); @@ -689,7 +719,7 @@ void usb_core_bus_reset(void) } /* called by usb_drv_transfer_completed() */ -void usb_core_transfer_complete(int endpoint, bool in, int status,int length) +void usb_core_transfer_complete(int endpoint, int dir, int status,int length) { switch (endpoint) { case EP_CONTROL: @@ -698,7 +728,7 @@ void usb_core_transfer_complete(int endpoint, bool in, int status,int length) default: ep_data[endpoint].completion_event.endpoint=endpoint; - ep_data[endpoint].completion_event.in=in; + ep_data[endpoint].completion_event.dir=dir; ep_data[endpoint].completion_event.data=0; ep_data[endpoint].completion_event.status=status; ep_data[endpoint].completion_event.length=length; @@ -712,7 +742,7 @@ void usb_core_transfer_complete(int endpoint, bool in, int status,int length) void usb_core_control_request(struct usb_ctrlrequest* req) { ep_data[0].completion_event.endpoint=0; - ep_data[0].completion_event.in=0; + ep_data[0].completion_event.dir=0; ep_data[0].completion_event.data=(void *)req; ep_data[0].completion_event.status=0; ep_data[0].completion_event.length=0; diff --git a/firmware/usbstack/usb_serial.c b/firmware/usbstack/usb_serial.c index 8d6ce67823..1b143d56eb 100644 --- a/firmware/usbstack/usb_serial.c +++ b/firmware/usbstack/usb_serial.c @@ -72,7 +72,7 @@ static int buffer_start; static int buffer_length; static bool active = false; -static int usb_endpoint; +static int ep_in, ep_out; static int usb_interface; static struct mutex sendlock SHAREDBSS_ATTR; @@ -82,22 +82,33 @@ static void sendout(void) if(buffer_start+buffer_length > BUFFER_SIZE) { /* Buffer wraps. Only send the first part */ - usb_drv_send_nonblocking(usb_endpoint, &send_buffer[buffer_start], + usb_drv_send_nonblocking(ep_in, &send_buffer[buffer_start], (BUFFER_SIZE - buffer_start)); } else { /* Send everything */ - usb_drv_send_nonblocking(usb_endpoint, &send_buffer[buffer_start], + usb_drv_send_nonblocking(ep_in, &send_buffer[buffer_start], buffer_length); } busy_sending=true; } -int usb_serial_set_first_endpoint(int endpoint) +int usb_serial_request_endpoints(struct usb_class_driver *drv) { - usb_endpoint = endpoint; - return endpoint + 1; + ep_in = usb_core_request_endpoint(USB_DIR_IN, drv); + + if (ep_in < 0) + return -1; + + ep_out = usb_core_request_endpoint(USB_DIR_OUT, drv); + + if (ep_out < 0) { + usb_core_release_endpoint(ep_in); + return -1; + } + + return 0; } int usb_serial_set_first_interface(int interface) @@ -117,11 +128,11 @@ int usb_serial_get_config_descriptor(unsigned char *dest,int max_packet_size) memcpy(dest,&interface_descriptor,sizeof(struct usb_interface_descriptor)); dest+=sizeof(struct usb_interface_descriptor); - endpoint_descriptor.bEndpointAddress = usb_endpoint | USB_DIR_IN; + endpoint_descriptor.bEndpointAddress = ep_in; memcpy(dest,&endpoint_descriptor,sizeof(struct usb_endpoint_descriptor)); dest+=sizeof(struct usb_endpoint_descriptor); - endpoint_descriptor.bEndpointAddress = usb_endpoint | USB_DIR_OUT; + endpoint_descriptor.bEndpointAddress = ep_out; memcpy(dest,&endpoint_descriptor,sizeof(struct usb_endpoint_descriptor)); dest+=sizeof(struct usb_endpoint_descriptor); @@ -131,7 +142,7 @@ int usb_serial_get_config_descriptor(unsigned char *dest,int max_packet_size) void usb_serial_init_connection(void) { /* prime rx endpoint */ - usb_drv_recv(usb_endpoint, receive_buffer, sizeof receive_buffer); + usb_drv_recv(ep_out, receive_buffer, sizeof receive_buffer); /* we come here too after a bus reset, so reset some data */ mutex_lock(&sendlock); @@ -202,17 +213,17 @@ void usb_serial_send(unsigned char *data,int length) } /* called by usb_core_transfer_complete() */ -void usb_serial_transfer_complete(int ep,bool in, int status, int length) +void usb_serial_transfer_complete(int ep,int dir, int status, int length) { (void)ep; - switch (in) { - case false: + switch (dir) { + case USB_DIR_OUT: logf("serial: %s", receive_buffer); /* Data received. TODO : Do something with it ? */ - usb_drv_recv(usb_endpoint, receive_buffer, sizeof receive_buffer); + usb_drv_recv(ep_out, receive_buffer, sizeof receive_buffer); break; - case true: + case USB_DIR_IN: mutex_lock(&sendlock); /* Data sent out. Update circular buffer */ if(status == 0) diff --git a/firmware/usbstack/usb_serial.h b/firmware/usbstack/usb_serial.h index 69ad3fd647..94decdc42b 100644 --- a/firmware/usbstack/usb_serial.h +++ b/firmware/usbstack/usb_serial.h @@ -23,13 +23,13 @@ #include "usb_ch9.h" -int usb_serial_set_first_endpoint(int endpoint); +int usb_serial_request_endpoints(struct usb_class_driver *); int usb_serial_set_first_interface(int interface); int usb_serial_get_config_descriptor(unsigned char *dest,int max_packet_size); void usb_serial_init_connection(void); void usb_serial_init(void); void usb_serial_disconnect(void); -void usb_serial_transfer_complete(int ep,bool in, int status, int length); +void usb_serial_transfer_complete(int ep,int dir, int status, int length); bool usb_serial_control_request(struct usb_ctrlrequest* req); void usb_serial_send(unsigned char *data,int length); diff --git a/firmware/usbstack/usb_storage.c b/firmware/usbstack/usb_storage.c index f774d14cbc..9c524a37b8 100644 --- a/firmware/usbstack/usb_storage.c +++ b/firmware/usbstack/usb_storage.c @@ -22,7 +22,7 @@ #include "system.h" #include "usb_core.h" #include "usb_drv.h" -//#define LOGF_ENABLE +#define LOGF_ENABLE #include "logf.h" #include "ata.h" #include "hotswap.h" @@ -263,8 +263,8 @@ static void identify2inquiry(int lun); static void send_and_read_next(void); static bool ejected[NUM_VOLUMES]; -static int usb_endpoint; static int usb_interface; +static int ep_in, ep_out; static enum { WAITING_FOR_COMMAND, @@ -321,7 +321,7 @@ void usb_storage_reconnect(void) && usb_inserted()) { for(i=0;i<NUM_VOLUMES;i++) ejected[i] = !check_disk_present(IF_MV(i)); - + logf("%s", __func__); usb_request_exclusive_ata(); } } @@ -336,12 +336,23 @@ void usb_storage_init(void) logf("usb_storage_init done"); } - -int usb_storage_set_first_endpoint(int endpoint) +int usb_storage_request_endpoints(struct usb_class_driver *drv) { - usb_endpoint = endpoint; - return endpoint + 1; + ep_in = usb_core_request_endpoint(USB_DIR_IN, drv); + + if (ep_in < 0) + return -1; + + ep_out = usb_core_request_endpoint(USB_DIR_OUT, drv); + + if (ep_out < 0) { + usb_core_release_endpoint(ep_in); + return -1; + } + + return 0; } + int usb_storage_set_first_interface(int interface) { usb_interface = interface; @@ -357,12 +368,12 @@ int usb_storage_get_config_descriptor(unsigned char *dest,int max_packet_size) sizeof(struct usb_interface_descriptor)); dest+=sizeof(struct usb_interface_descriptor); - endpoint_descriptor.bEndpointAddress = usb_endpoint | USB_DIR_IN; + endpoint_descriptor.bEndpointAddress = ep_in; memcpy(dest,&endpoint_descriptor, sizeof(struct usb_endpoint_descriptor)); dest+=sizeof(struct usb_endpoint_descriptor); - endpoint_descriptor.bEndpointAddress = usb_endpoint | USB_DIR_OUT; + endpoint_descriptor.bEndpointAddress = ep_out; memcpy(dest,&endpoint_descriptor, sizeof(struct usb_endpoint_descriptor)); @@ -376,7 +387,8 @@ void usb_storage_init_connection(void) /* prime rx endpoint. We only need room for commands */ state = WAITING_FOR_COMMAND; -#if CONFIG_CPU == IMX31L || CONFIG_USBOTG == USBOTG_ISP1583 +#if CONFIG_CPU == IMX31L || CONFIG_USBOTG == USBOTG_ISP1583 || \ + defined(CPU_TCC77X) || defined(CPU_TCC780X) static unsigned char _transfer_buffer[BUFFER_SIZE*2] USBDEVBSS_ATTR __attribute__((aligned(32))); tb.transfer_buffer = (void *)_transfer_buffer; @@ -390,11 +402,11 @@ void usb_storage_init_connection(void) (void *)UNCACHED_ADDR((unsigned int)(audio_buffer + 31) & 0xffffffe0); invalidate_icache(); #endif - usb_drv_recv(usb_endpoint, tb.transfer_buffer, 1024); + usb_drv_recv(ep_out, tb.transfer_buffer, 1024); } /* called by usb_core_transfer_complete() */ -void usb_storage_transfer_complete(int ep,bool in,int status,int length) +void usb_storage_transfer_complete(int ep,int dir,int status,int length) { (void)ep; struct command_block_wrapper* cbw = (void*)tb.transfer_buffer; @@ -402,7 +414,7 @@ void usb_storage_transfer_complete(int ep,bool in,int status,int length) //logf("transfer result %X %d", status, length); switch(state) { case RECEIVING_BLOCKS: - if(in==true) { + if(dir==USB_DIR_IN) { logf("IN received in RECEIVING"); } logf("scsi write %d %d", cur_cmd.sector, cur_cmd.count); @@ -470,7 +482,7 @@ void usb_storage_transfer_complete(int ep,bool in,int status,int length) } break; case WAITING_FOR_COMMAND: - if(in==true) { + if(dir==USB_DIR_IN) { logf("IN received in WAITING_FOR_COMMAND"); } //logf("command received"); @@ -478,20 +490,20 @@ void usb_storage_transfer_complete(int ep,bool in,int status,int length) handle_scsi(cbw); } else { - usb_drv_stall(usb_endpoint, true,true); - usb_drv_stall(usb_endpoint, true,false); + usb_drv_stall(ep_in, true,true); + usb_drv_stall(ep_out, true,false); } break; case SENDING_CSW: - if(in==false) { + if(dir==USB_DIR_OUT) { logf("OUT received in SENDING_CSW"); } //logf("csw sent, now go back to idle"); state = WAITING_FOR_COMMAND; - usb_drv_recv(usb_endpoint, tb.transfer_buffer, 1024); + usb_drv_recv(ep_out, tb.transfer_buffer, 1024); break; case SENDING_RESULT: - if(in==false) { + if(dir==USB_DIR_OUT) { logf("OUT received in SENDING"); } if(status==0) { @@ -509,13 +521,13 @@ void usb_storage_transfer_complete(int ep,bool in,int status,int length) } break; case SENDING_FAILED_RESULT: - if(in==false) { + if(dir==USB_DIR_OUT) { logf("OUT received in SENDING"); } send_csw(UMS_STATUS_FAIL); break; case SENDING_BLOCKS: - if(in==false) { + if(dir==USB_DIR_OUT) { logf("OUT received in SENDING"); } if(status==0) { @@ -567,8 +579,8 @@ bool usb_storage_control_request(struct usb_ctrlrequest* req) data toggle bits and endpoint STALL conditions despite the Bulk-Only Mass Storage Reset. */ #if 0 - usb_drv_reset_endpoint(usb_endpoint, false); - usb_drv_reset_endpoint(usb_endpoint, true); + usb_drv_reset_endpoint(ep_in, false); + usb_drv_reset_endpoint(ep_out, true); #endif usb_drv_send(EP_CONTROL, NULL, 0); /* ack */ @@ -972,7 +984,7 @@ static void handle_scsi(struct command_block_wrapper* cbw) default: logf("scsi unknown cmd %x",cbw->command_block[0x0]); - usb_drv_stall(usb_endpoint, true,true); + usb_drv_stall(ep_in, true,true); send_csw(UMS_STATUS_FAIL); break; } @@ -980,25 +992,25 @@ static void handle_scsi(struct command_block_wrapper* cbw) static void send_block_data(void *data,int size) { - usb_drv_send_nonblocking(usb_endpoint, data,size); + usb_drv_send_nonblocking(ep_in, data,size); state = SENDING_BLOCKS; } static void send_command_result(void *data,int size) { - usb_drv_send_nonblocking(usb_endpoint, data,size); + usb_drv_send_nonblocking(ep_in, data,size); state = SENDING_RESULT; } static void send_command_failed_result(void) { - usb_drv_send_nonblocking(usb_endpoint, NULL, 0); + usb_drv_send_nonblocking(ep_in, NULL, 0); state = SENDING_FAILED_RESULT; } static void receive_block_data(void *data,int size) { - usb_drv_recv(usb_endpoint, data, size); + usb_drv_recv(ep_out, data, size); state = RECEIVING_BLOCKS; } @@ -1009,7 +1021,7 @@ static void send_csw(int status) tb.csw->data_residue = 0; tb.csw->status = status; - usb_drv_send_nonblocking(usb_endpoint, tb.csw, + usb_drv_send_nonblocking(ep_in, tb.csw, sizeof(struct command_status_wrapper)); state = SENDING_CSW; //logf("CSW: %X",status); diff --git a/firmware/usbstack/usb_storage.h b/firmware/usbstack/usb_storage.h index 7054d24501..4c89039bfd 100644 --- a/firmware/usbstack/usb_storage.h +++ b/firmware/usbstack/usb_storage.h @@ -23,12 +23,12 @@ #include "usb_ch9.h" -int usb_storage_set_first_endpoint(int endpoint); +int usb_storage_request_endpoints(struct usb_class_driver *); int usb_storage_set_first_interface(int interface); int usb_storage_get_config_descriptor(unsigned char *dest,int max_packet_size); void usb_storage_init_connection(void); void usb_storage_init(void); -void usb_storage_transfer_complete(int ep,bool in,int state,int length); +void usb_storage_transfer_complete(int ep,int dir,int state,int length); bool usb_storage_control_request(struct usb_ctrlrequest* req); #ifdef HAVE_HOTSWAP void usb_storage_notify_hotswap(int volume,bool inserted); |