forked from len0rd/rockbox
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
This commit is contained in:
parent
6219f4c862
commit
478fc5baed
12 changed files with 185 additions and 99 deletions
|
@ -85,7 +85,7 @@ enum {
|
||||||
struct usb_transfer_completion_event_data
|
struct usb_transfer_completion_event_data
|
||||||
{
|
{
|
||||||
unsigned char endpoint;
|
unsigned char endpoint;
|
||||||
bool in;
|
int dir;
|
||||||
int status;
|
int status;
|
||||||
int length;
|
int length;
|
||||||
void* data;
|
void* data;
|
||||||
|
|
|
@ -45,10 +45,12 @@
|
||||||
|
|
||||||
extern int usb_max_pkt_size;
|
extern int usb_max_pkt_size;
|
||||||
|
|
||||||
|
struct usb_class_driver;
|
||||||
|
|
||||||
void usb_core_init(void);
|
void usb_core_init(void);
|
||||||
void usb_core_exit(void);
|
void usb_core_exit(void);
|
||||||
void usb_core_control_request(struct usb_ctrlrequest* req);
|
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);
|
void usb_core_bus_reset(void);
|
||||||
bool usb_core_exclusive_connection(void);
|
bool usb_core_exclusive_connection(void);
|
||||||
void usb_core_enable_driver(int driver,bool enabled);
|
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(
|
void usb_core_handle_transfer_completion(
|
||||||
struct usb_transfer_completion_event_data* event);
|
struct usb_transfer_completion_event_data* event);
|
||||||
int usb_core_ack_control(struct usb_ctrlrequest* req);
|
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
|
#ifdef HAVE_HOTSWAP
|
||||||
void usb_core_hotswap_event(int volume,bool inserted);
|
void usb_core_hotswap_event(int volume,bool inserted);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -41,5 +41,7 @@ int usb_drv_port_speed(void);
|
||||||
void usb_drv_cancel_all_transfers(void);
|
void usb_drv_cancel_all_transfers(void);
|
||||||
void usb_drv_set_test_mode(int mode);
|
void usb_drv_set_test_mode(int mode);
|
||||||
bool usb_drv_connected(void);
|
bool usb_drv_connected(void);
|
||||||
|
int usb_drv_request_endpoint(int dir);
|
||||||
|
void usb_drv_release_endpoint(int ep);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -363,6 +363,8 @@ static const unsigned int pipe2mask[] = {
|
||||||
0x10, 0x100000,
|
0x10, 0x100000,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static char ep_allocation[NUM_ENDPOINTS];
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------*/
|
||||||
static void transfer_completed(void);
|
static void transfer_completed(void);
|
||||||
static void control_received(void);
|
static void control_received(void);
|
||||||
|
@ -534,23 +536,23 @@ void usb_drv_int(void)
|
||||||
bool usb_drv_stalled(int endpoint,bool in)
|
bool usb_drv_stalled(int endpoint,bool in)
|
||||||
{
|
{
|
||||||
if(in) {
|
if(in) {
|
||||||
return ((REG_ENDPTCTRL(endpoint) & EPCTRL_TX_EP_STALL)!=0);
|
return ((REG_ENDPTCTRL(endpoint&0x7f) & EPCTRL_TX_EP_STALL)!=0);
|
||||||
}
|
}
|
||||||
else {
|
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)
|
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(in) {
|
||||||
if (stall) {
|
if (stall) {
|
||||||
REG_ENDPTCTRL(endpoint) |= EPCTRL_TX_EP_STALL;
|
REG_ENDPTCTRL(endpoint&0x7f) |= EPCTRL_TX_EP_STALL;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
REG_ENDPTCTRL(endpoint) &= ~EPCTRL_TX_EP_STALL;
|
REG_ENDPTCTRL(endpoint&0x7f) &= ~EPCTRL_TX_EP_STALL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
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)
|
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)
|
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)
|
int usb_drv_recv(int endpoint, void* ptr, int length)
|
||||||
{
|
{
|
||||||
//logf("usbrecv(%x, %d)", ptr, 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)
|
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];
|
struct queue_head* qh = &qh_array[pipe];
|
||||||
|
|
||||||
while (qh->dtd.size_ioc_sts & QH_STATUS_ACTIVE) {
|
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)
|
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];
|
unsigned int mask = pipe2mask[pipe];
|
||||||
REG_ENDPTFLUSH = mask;
|
REG_ENDPTFLUSH = mask;
|
||||||
while (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,
|
static void prepare_td(struct transfer_descriptor* td,
|
||||||
struct transfer_descriptor* previous_td,
|
struct transfer_descriptor* previous_td,
|
||||||
void *ptr, int len,int pipe)
|
void *ptr, int len,int pipe)
|
||||||
|
@ -831,7 +856,7 @@ static void transfer_completed(void)
|
||||||
qh->wait=0;
|
qh->wait=0;
|
||||||
wakeup_signal(&transfer_completion_signal[pipe]);
|
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;
|
rx_packetsize = 64;
|
||||||
tx_packetsize = 64;
|
tx_packetsize = 64;
|
||||||
}
|
}
|
||||||
|
/* TODO: this should take ep_allocation into account */
|
||||||
|
|
||||||
/*** bulk ***/
|
/*** bulk ***/
|
||||||
for(i=1;i<NUM_ENDPOINTS;i++) {
|
for(i=1;i<NUM_ENDPOINTS;i++) {
|
||||||
|
@ -913,6 +939,7 @@ static void init_bulk_queue_heads(void)
|
||||||
static void init_endpoints(void)
|
static void init_endpoints(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
/* TODO: this should take ep_allocation into account */
|
||||||
/* bulk */
|
/* bulk */
|
||||||
for(i=1;i<NUM_ENDPOINTS;i++) {
|
for(i=1;i<NUM_ENDPOINTS;i++) {
|
||||||
REG_ENDPTCTRL(i) =
|
REG_ENDPTCTRL(i) =
|
||||||
|
|
|
@ -48,11 +48,12 @@ static struct usb_interface_descriptor __attribute__((aligned(2)))
|
||||||
|
|
||||||
static int usb_interface;
|
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 */
|
(void) drv;
|
||||||
return endpoint;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int usb_charging_only_set_first_interface(int interface)
|
int usb_charging_only_set_first_interface(int interface)
|
||||||
{
|
{
|
||||||
usb_interface = interface;
|
usb_interface = interface;
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
#include "usb_ch9.h"
|
#include "usb_ch9.h"
|
||||||
|
|
||||||
void usb_charging_only_init(void);
|
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_set_first_interface(int interface);
|
||||||
int usb_charging_only_get_config_descriptor(unsigned char *dest,int max_packet_size);
|
int usb_charging_only_get_config_descriptor(unsigned char *dest,int max_packet_size);
|
||||||
bool usb_charging_only_control_request(struct usb_ctrlrequest* req);
|
bool usb_charging_only_control_request(struct usb_ctrlrequest* req);
|
||||||
|
|
|
@ -35,6 +35,9 @@ struct usb_class_driver {
|
||||||
/* Set this to true if the driver needs exclusive disk access (e.g. usb storage) */
|
/* Set this to true if the driver needs exclusive disk access (e.g. usb storage) */
|
||||||
bool needs_exclusive_ata;
|
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
|
/* Tells the driver what its first interface number will be. The driver
|
||||||
returns the number of the first available interface for the next driver
|
returns the number of the first available interface for the next driver
|
||||||
(i.e. a driver with one interface will return interface+1)
|
(i.e. a driver with one interface will return interface+1)
|
||||||
|
@ -42,12 +45,6 @@ struct usb_class_driver {
|
||||||
Mandatory function */
|
Mandatory function */
|
||||||
int (*set_first_interface)(int interface);
|
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
|
/* Asks the driver to put the interface descriptor and all other
|
||||||
needed descriptor for this driver at dest.
|
needed descriptor for this driver at dest.
|
||||||
Returns the number of bytes taken by these descriptors.
|
Returns the number of bytes taken by these descriptors.
|
||||||
|
@ -69,10 +66,10 @@ struct usb_class_driver {
|
||||||
Optional function */
|
Optional function */
|
||||||
void (*disconnect)(void);
|
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
|
is relative to the host
|
||||||
Optional function */
|
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
|
/* 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
|
able to handle it, it should ack the request, and return true. Otherwise
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
#include "thread.h"
|
#include "thread.h"
|
||||||
#include "kernel.h"
|
#include "kernel.h"
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
//#define LOGF_ENABLE
|
#define LOGF_ENABLE
|
||||||
#include "logf.h"
|
#include "logf.h"
|
||||||
|
|
||||||
#include "usb.h"
|
#include "usb.h"
|
||||||
|
@ -164,10 +164,13 @@ static enum { DEFAULT, ADDRESS, CONFIGURED } usb_state;
|
||||||
|
|
||||||
static int usb_core_num_interfaces;
|
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
|
static struct
|
||||||
{
|
{
|
||||||
void (*completion_handler)(int ep,bool in, int status, int length);
|
completion_handler_t completion_handler[2];
|
||||||
bool (*control_handler)(struct usb_ctrlrequest* req);
|
control_handler_t control_handler[2];
|
||||||
struct usb_transfer_completion_event_data completion_event;
|
struct usb_transfer_completion_event_data completion_event;
|
||||||
} ep_data[NUM_ENDPOINTS];
|
} ep_data[NUM_ENDPOINTS];
|
||||||
|
|
||||||
|
@ -179,8 +182,8 @@ static struct usb_class_driver drivers[USB_NUM_DRIVERS] =
|
||||||
.needs_exclusive_ata = true,
|
.needs_exclusive_ata = true,
|
||||||
.first_interface = 0,
|
.first_interface = 0,
|
||||||
.last_interface = 0,
|
.last_interface = 0,
|
||||||
|
.request_endpoints = usb_storage_request_endpoints,
|
||||||
.set_first_interface = usb_storage_set_first_interface,
|
.set_first_interface = usb_storage_set_first_interface,
|
||||||
.set_first_endpoint = usb_storage_set_first_endpoint,
|
|
||||||
.get_config_descriptor = usb_storage_get_config_descriptor,
|
.get_config_descriptor = usb_storage_get_config_descriptor,
|
||||||
.init_connection = usb_storage_init_connection,
|
.init_connection = usb_storage_init_connection,
|
||||||
.init = usb_storage_init,
|
.init = usb_storage_init,
|
||||||
|
@ -198,8 +201,8 @@ static struct usb_class_driver drivers[USB_NUM_DRIVERS] =
|
||||||
.needs_exclusive_ata = false,
|
.needs_exclusive_ata = false,
|
||||||
.first_interface = 0,
|
.first_interface = 0,
|
||||||
.last_interface = 0,
|
.last_interface = 0,
|
||||||
|
.request_endpoints = usb_serial_request_endpoints,
|
||||||
.set_first_interface = usb_serial_set_first_interface,
|
.set_first_interface = usb_serial_set_first_interface,
|
||||||
.set_first_endpoint = usb_serial_set_first_endpoint,
|
|
||||||
.get_config_descriptor = usb_serial_get_config_descriptor,
|
.get_config_descriptor = usb_serial_get_config_descriptor,
|
||||||
.init_connection = usb_serial_init_connection,
|
.init_connection = usb_serial_init_connection,
|
||||||
.init = usb_serial_init,
|
.init = usb_serial_init,
|
||||||
|
@ -217,8 +220,8 @@ static struct usb_class_driver drivers[USB_NUM_DRIVERS] =
|
||||||
.needs_exclusive_ata = false,
|
.needs_exclusive_ata = false,
|
||||||
.first_interface = 0,
|
.first_interface = 0,
|
||||||
.last_interface = 0,
|
.last_interface = 0,
|
||||||
|
.request_endpoints = usb_charging_only_request_endpoints,
|
||||||
.set_first_interface = usb_charging_only_set_first_interface,
|
.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,
|
.get_config_descriptor = usb_charging_only_get_config_descriptor,
|
||||||
.init_connection = NULL,
|
.init_connection = NULL,
|
||||||
.init = NULL,
|
.init = NULL,
|
||||||
|
@ -339,6 +342,7 @@ void usb_core_handle_transfer_completion(
|
||||||
struct usb_transfer_completion_event_data* event)
|
struct usb_transfer_completion_event_data* event)
|
||||||
{
|
{
|
||||||
int ep = event->endpoint;
|
int ep = event->endpoint;
|
||||||
|
|
||||||
switch(ep) {
|
switch(ep) {
|
||||||
case EP_CONTROL:
|
case EP_CONTROL:
|
||||||
logf("ctrl handled %ld",current_tick);
|
logf("ctrl handled %ld",current_tick);
|
||||||
|
@ -346,8 +350,8 @@ void usb_core_handle_transfer_completion(
|
||||||
(struct usb_ctrlrequest*)event->data);
|
(struct usb_ctrlrequest*)event->data);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if(ep_data[ep].completion_handler != NULL)
|
if(ep_data[ep].completion_handler[event->dir>>7] != NULL)
|
||||||
ep_data[ep].completion_handler(ep,event->in,
|
ep_data[ep].completion_handler[event->dir>>7](ep,event->dir,
|
||||||
event->status,event->length);
|
event->status,event->length);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -388,34 +392,60 @@ static void usb_core_set_serial_function_id(void)
|
||||||
usb_string_iSerial.wString[0] = hex[id];
|
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)
|
static void allocate_interfaces_and_endpoints(void)
|
||||||
{
|
{
|
||||||
int i,j;
|
int i;
|
||||||
int interface=0;
|
int interface=0;
|
||||||
int endpoint=1;
|
|
||||||
|
|
||||||
memset(ep_data,0,sizeof(ep_data));
|
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) {
|
if(drivers[i].enabled) {
|
||||||
int oldendpoint = endpoint;
|
|
||||||
drivers[i].first_interface = interface;
|
drivers[i].first_interface = interface;
|
||||||
|
|
||||||
endpoint = drivers[i].set_first_endpoint(endpoint);
|
if (drivers[i].request_endpoints(&drivers[i])) {
|
||||||
if(endpoint>NUM_ENDPOINTS) {
|
|
||||||
drivers[i].enabled = false;
|
drivers[i].enabled = false;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface = drivers[i].set_first_interface(interface);
|
interface = drivers[i].set_first_interface(interface);
|
||||||
drivers[i].last_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;
|
usb_core_num_interfaces = interface;
|
||||||
|
@ -666,8 +696,8 @@ static void usb_core_control_request_handler(struct usb_ctrlrequest* req)
|
||||||
break;
|
break;
|
||||||
default: {
|
default: {
|
||||||
bool handled=false;
|
bool handled=false;
|
||||||
if(ep_data[req->wIndex & 0xf].control_handler != NULL)
|
if(ep_data[req->wIndex & 0xf].control_handler[0] != NULL)
|
||||||
handled = ep_data[req->wIndex & 0xf].control_handler(req);
|
handled = ep_data[req->wIndex & 0xf].control_handler[0](req);
|
||||||
if(!handled) {
|
if(!handled) {
|
||||||
/* nope. flag error */
|
/* nope. flag error */
|
||||||
logf("usb bad req %d", req->bRequest);
|
logf("usb bad req %d", req->bRequest);
|
||||||
|
@ -689,7 +719,7 @@ void usb_core_bus_reset(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* called by usb_drv_transfer_completed() */
|
/* 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) {
|
switch (endpoint) {
|
||||||
case EP_CONTROL:
|
case EP_CONTROL:
|
||||||
|
@ -698,7 +728,7 @@ void usb_core_transfer_complete(int endpoint, bool in, int status,int length)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ep_data[endpoint].completion_event.endpoint=endpoint;
|
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.data=0;
|
||||||
ep_data[endpoint].completion_event.status=status;
|
ep_data[endpoint].completion_event.status=status;
|
||||||
ep_data[endpoint].completion_event.length=length;
|
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)
|
void usb_core_control_request(struct usb_ctrlrequest* req)
|
||||||
{
|
{
|
||||||
ep_data[0].completion_event.endpoint=0;
|
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.data=(void *)req;
|
||||||
ep_data[0].completion_event.status=0;
|
ep_data[0].completion_event.status=0;
|
||||||
ep_data[0].completion_event.length=0;
|
ep_data[0].completion_event.length=0;
|
||||||
|
|
|
@ -72,7 +72,7 @@ static int buffer_start;
|
||||||
static int buffer_length;
|
static int buffer_length;
|
||||||
static bool active = false;
|
static bool active = false;
|
||||||
|
|
||||||
static int usb_endpoint;
|
static int ep_in, ep_out;
|
||||||
static int usb_interface;
|
static int usb_interface;
|
||||||
|
|
||||||
static struct mutex sendlock SHAREDBSS_ATTR;
|
static struct mutex sendlock SHAREDBSS_ATTR;
|
||||||
|
@ -82,22 +82,33 @@ static void sendout(void)
|
||||||
if(buffer_start+buffer_length > BUFFER_SIZE)
|
if(buffer_start+buffer_length > BUFFER_SIZE)
|
||||||
{
|
{
|
||||||
/* Buffer wraps. Only send the first part */
|
/* 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));
|
(BUFFER_SIZE - buffer_start));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Send everything */
|
/* Send everything */
|
||||||
usb_drv_send_nonblocking(usb_endpoint, &send_buffer[buffer_start],
|
usb_drv_send_nonblocking(ep_in, &send_buffer[buffer_start],
|
||||||
buffer_length);
|
buffer_length);
|
||||||
}
|
}
|
||||||
busy_sending=true;
|
busy_sending=true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int usb_serial_set_first_endpoint(int endpoint)
|
int usb_serial_request_endpoints(struct usb_class_driver *drv)
|
||||||
{
|
{
|
||||||
usb_endpoint = endpoint;
|
ep_in = usb_core_request_endpoint(USB_DIR_IN, drv);
|
||||||
return endpoint + 1;
|
|
||||||
|
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)
|
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));
|
memcpy(dest,&interface_descriptor,sizeof(struct usb_interface_descriptor));
|
||||||
dest+=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));
|
memcpy(dest,&endpoint_descriptor,sizeof(struct usb_endpoint_descriptor));
|
||||||
dest+=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));
|
memcpy(dest,&endpoint_descriptor,sizeof(struct usb_endpoint_descriptor));
|
||||||
dest+=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)
|
void usb_serial_init_connection(void)
|
||||||
{
|
{
|
||||||
/* prime rx endpoint */
|
/* 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 */
|
/* we come here too after a bus reset, so reset some data */
|
||||||
mutex_lock(&sendlock);
|
mutex_lock(&sendlock);
|
||||||
|
@ -202,17 +213,17 @@ void usb_serial_send(unsigned char *data,int length)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* called by usb_core_transfer_complete() */
|
/* 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;
|
(void)ep;
|
||||||
switch (in) {
|
switch (dir) {
|
||||||
case false:
|
case USB_DIR_OUT:
|
||||||
logf("serial: %s", receive_buffer);
|
logf("serial: %s", receive_buffer);
|
||||||
/* Data received. TODO : Do something with it ? */
|
/* 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;
|
break;
|
||||||
|
|
||||||
case true:
|
case USB_DIR_IN:
|
||||||
mutex_lock(&sendlock);
|
mutex_lock(&sendlock);
|
||||||
/* Data sent out. Update circular buffer */
|
/* Data sent out. Update circular buffer */
|
||||||
if(status == 0)
|
if(status == 0)
|
||||||
|
|
|
@ -23,13 +23,13 @@
|
||||||
|
|
||||||
#include "usb_ch9.h"
|
#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_set_first_interface(int interface);
|
||||||
int usb_serial_get_config_descriptor(unsigned char *dest,int max_packet_size);
|
int usb_serial_get_config_descriptor(unsigned char *dest,int max_packet_size);
|
||||||
void usb_serial_init_connection(void);
|
void usb_serial_init_connection(void);
|
||||||
void usb_serial_init(void);
|
void usb_serial_init(void);
|
||||||
void usb_serial_disconnect(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);
|
bool usb_serial_control_request(struct usb_ctrlrequest* req);
|
||||||
|
|
||||||
void usb_serial_send(unsigned char *data,int length);
|
void usb_serial_send(unsigned char *data,int length);
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
#include "system.h"
|
#include "system.h"
|
||||||
#include "usb_core.h"
|
#include "usb_core.h"
|
||||||
#include "usb_drv.h"
|
#include "usb_drv.h"
|
||||||
//#define LOGF_ENABLE
|
#define LOGF_ENABLE
|
||||||
#include "logf.h"
|
#include "logf.h"
|
||||||
#include "ata.h"
|
#include "ata.h"
|
||||||
#include "hotswap.h"
|
#include "hotswap.h"
|
||||||
|
@ -263,8 +263,8 @@ static void identify2inquiry(int lun);
|
||||||
static void send_and_read_next(void);
|
static void send_and_read_next(void);
|
||||||
static bool ejected[NUM_VOLUMES];
|
static bool ejected[NUM_VOLUMES];
|
||||||
|
|
||||||
static int usb_endpoint;
|
|
||||||
static int usb_interface;
|
static int usb_interface;
|
||||||
|
static int ep_in, ep_out;
|
||||||
|
|
||||||
static enum {
|
static enum {
|
||||||
WAITING_FOR_COMMAND,
|
WAITING_FOR_COMMAND,
|
||||||
|
@ -321,7 +321,7 @@ void usb_storage_reconnect(void)
|
||||||
&& usb_inserted()) {
|
&& usb_inserted()) {
|
||||||
for(i=0;i<NUM_VOLUMES;i++)
|
for(i=0;i<NUM_VOLUMES;i++)
|
||||||
ejected[i] = !check_disk_present(IF_MV(i));
|
ejected[i] = !check_disk_present(IF_MV(i));
|
||||||
|
logf("%s", __func__);
|
||||||
usb_request_exclusive_ata();
|
usb_request_exclusive_ata();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -336,12 +336,23 @@ void usb_storage_init(void)
|
||||||
logf("usb_storage_init done");
|
logf("usb_storage_init done");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int usb_storage_request_endpoints(struct usb_class_driver *drv)
|
||||||
int usb_storage_set_first_endpoint(int endpoint)
|
|
||||||
{
|
{
|
||||||
usb_endpoint = endpoint;
|
ep_in = usb_core_request_endpoint(USB_DIR_IN, drv);
|
||||||
return endpoint + 1;
|
|
||||||
|
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)
|
int usb_storage_set_first_interface(int interface)
|
||||||
{
|
{
|
||||||
usb_interface = 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));
|
sizeof(struct usb_interface_descriptor));
|
||||||
dest+=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,
|
memcpy(dest,&endpoint_descriptor,
|
||||||
sizeof(struct usb_endpoint_descriptor));
|
sizeof(struct usb_endpoint_descriptor));
|
||||||
dest+=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,
|
memcpy(dest,&endpoint_descriptor,
|
||||||
sizeof(struct usb_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 */
|
/* prime rx endpoint. We only need room for commands */
|
||||||
state = WAITING_FOR_COMMAND;
|
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]
|
static unsigned char _transfer_buffer[BUFFER_SIZE*2]
|
||||||
USBDEVBSS_ATTR __attribute__((aligned(32)));
|
USBDEVBSS_ATTR __attribute__((aligned(32)));
|
||||||
tb.transfer_buffer = (void *)_transfer_buffer;
|
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);
|
(void *)UNCACHED_ADDR((unsigned int)(audio_buffer + 31) & 0xffffffe0);
|
||||||
invalidate_icache();
|
invalidate_icache();
|
||||||
#endif
|
#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() */
|
/* 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;
|
(void)ep;
|
||||||
struct command_block_wrapper* cbw = (void*)tb.transfer_buffer;
|
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);
|
//logf("transfer result %X %d", status, length);
|
||||||
switch(state) {
|
switch(state) {
|
||||||
case RECEIVING_BLOCKS:
|
case RECEIVING_BLOCKS:
|
||||||
if(in==true) {
|
if(dir==USB_DIR_IN) {
|
||||||
logf("IN received in RECEIVING");
|
logf("IN received in RECEIVING");
|
||||||
}
|
}
|
||||||
logf("scsi write %d %d", cur_cmd.sector, cur_cmd.count);
|
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;
|
break;
|
||||||
case WAITING_FOR_COMMAND:
|
case WAITING_FOR_COMMAND:
|
||||||
if(in==true) {
|
if(dir==USB_DIR_IN) {
|
||||||
logf("IN received in WAITING_FOR_COMMAND");
|
logf("IN received in WAITING_FOR_COMMAND");
|
||||||
}
|
}
|
||||||
//logf("command received");
|
//logf("command received");
|
||||||
|
@ -478,20 +490,20 @@ void usb_storage_transfer_complete(int ep,bool in,int status,int length)
|
||||||
handle_scsi(cbw);
|
handle_scsi(cbw);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
usb_drv_stall(usb_endpoint, true,true);
|
usb_drv_stall(ep_in, true,true);
|
||||||
usb_drv_stall(usb_endpoint, true,false);
|
usb_drv_stall(ep_out, true,false);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SENDING_CSW:
|
case SENDING_CSW:
|
||||||
if(in==false) {
|
if(dir==USB_DIR_OUT) {
|
||||||
logf("OUT received in SENDING_CSW");
|
logf("OUT received in SENDING_CSW");
|
||||||
}
|
}
|
||||||
//logf("csw sent, now go back to idle");
|
//logf("csw sent, now go back to idle");
|
||||||
state = WAITING_FOR_COMMAND;
|
state = WAITING_FOR_COMMAND;
|
||||||
usb_drv_recv(usb_endpoint, tb.transfer_buffer, 1024);
|
usb_drv_recv(ep_out, tb.transfer_buffer, 1024);
|
||||||
break;
|
break;
|
||||||
case SENDING_RESULT:
|
case SENDING_RESULT:
|
||||||
if(in==false) {
|
if(dir==USB_DIR_OUT) {
|
||||||
logf("OUT received in SENDING");
|
logf("OUT received in SENDING");
|
||||||
}
|
}
|
||||||
if(status==0) {
|
if(status==0) {
|
||||||
|
@ -509,13 +521,13 @@ void usb_storage_transfer_complete(int ep,bool in,int status,int length)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SENDING_FAILED_RESULT:
|
case SENDING_FAILED_RESULT:
|
||||||
if(in==false) {
|
if(dir==USB_DIR_OUT) {
|
||||||
logf("OUT received in SENDING");
|
logf("OUT received in SENDING");
|
||||||
}
|
}
|
||||||
send_csw(UMS_STATUS_FAIL);
|
send_csw(UMS_STATUS_FAIL);
|
||||||
break;
|
break;
|
||||||
case SENDING_BLOCKS:
|
case SENDING_BLOCKS:
|
||||||
if(in==false) {
|
if(dir==USB_DIR_OUT) {
|
||||||
logf("OUT received in SENDING");
|
logf("OUT received in SENDING");
|
||||||
}
|
}
|
||||||
if(status==0) {
|
if(status==0) {
|
||||||
|
@ -567,8 +579,8 @@ bool usb_storage_control_request(struct usb_ctrlrequest* req)
|
||||||
data toggle bits and endpoint STALL conditions despite
|
data toggle bits and endpoint STALL conditions despite
|
||||||
the Bulk-Only Mass Storage Reset. */
|
the Bulk-Only Mass Storage Reset. */
|
||||||
#if 0
|
#if 0
|
||||||
usb_drv_reset_endpoint(usb_endpoint, false);
|
usb_drv_reset_endpoint(ep_in, false);
|
||||||
usb_drv_reset_endpoint(usb_endpoint, true);
|
usb_drv_reset_endpoint(ep_out, true);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
usb_drv_send(EP_CONTROL, NULL, 0); /* ack */
|
usb_drv_send(EP_CONTROL, NULL, 0); /* ack */
|
||||||
|
@ -972,7 +984,7 @@ static void handle_scsi(struct command_block_wrapper* cbw)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
logf("scsi unknown cmd %x",cbw->command_block[0x0]);
|
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);
|
send_csw(UMS_STATUS_FAIL);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -980,25 +992,25 @@ static void handle_scsi(struct command_block_wrapper* cbw)
|
||||||
|
|
||||||
static void send_block_data(void *data,int size)
|
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;
|
state = SENDING_BLOCKS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void send_command_result(void *data,int size)
|
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;
|
state = SENDING_RESULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void send_command_failed_result(void)
|
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;
|
state = SENDING_FAILED_RESULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void receive_block_data(void *data,int size)
|
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;
|
state = RECEIVING_BLOCKS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1009,7 +1021,7 @@ static void send_csw(int status)
|
||||||
tb.csw->data_residue = 0;
|
tb.csw->data_residue = 0;
|
||||||
tb.csw->status = status;
|
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));
|
sizeof(struct command_status_wrapper));
|
||||||
state = SENDING_CSW;
|
state = SENDING_CSW;
|
||||||
//logf("CSW: %X",status);
|
//logf("CSW: %X",status);
|
||||||
|
|
|
@ -23,12 +23,12 @@
|
||||||
|
|
||||||
#include "usb_ch9.h"
|
#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_set_first_interface(int interface);
|
||||||
int usb_storage_get_config_descriptor(unsigned char *dest,int max_packet_size);
|
int usb_storage_get_config_descriptor(unsigned char *dest,int max_packet_size);
|
||||||
void usb_storage_init_connection(void);
|
void usb_storage_init_connection(void);
|
||||||
void usb_storage_init(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);
|
bool usb_storage_control_request(struct usb_ctrlrequest* req);
|
||||||
#ifdef HAVE_HOTSWAP
|
#ifdef HAVE_HOTSWAP
|
||||||
void usb_storage_notify_hotswap(int volume,bool inserted);
|
void usb_storage_notify_hotswap(int volume,bool inserted);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue