usb-s3c6400x: start factorization
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@31506 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
ba03cb4aea
commit
12b70597a6
2 changed files with 55 additions and 95 deletions
|
@ -39,17 +39,6 @@
|
|||
static const uint8_t in_ep_list[] = {0, 1, 3, 5};
|
||||
static const uint8_t out_ep_list[] = {0, 2, 4};
|
||||
|
||||
/* store per endpoint, per direction, information */
|
||||
struct ep_type
|
||||
{
|
||||
unsigned int size; /* length of the data buffer */
|
||||
struct semaphore complete; /* wait object */
|
||||
int8_t status; /* completion status (0 for success) */
|
||||
bool active; /* true is endpoint has been requested (true for EP0) */
|
||||
bool done; /* transfer completed */
|
||||
bool busy; /* true is a transfer is pending */
|
||||
};
|
||||
|
||||
/* state of EP0 (to correctly schedule setup packet enqueing) */
|
||||
enum ep0state
|
||||
{
|
||||
|
@ -423,7 +412,7 @@ void usb_drv_cancel_all_transfers()
|
|||
cancel_all_transfers(false);
|
||||
}
|
||||
|
||||
static void usb_drv_transfer(int ep, void *ptr, int len, bool out)
|
||||
static void ep_transfer(int ep, void *ptr, int len, bool out)
|
||||
{
|
||||
/* disable interrupts to avoid any race */
|
||||
int oldlevel = disable_irq_save();
|
||||
|
@ -458,51 +447,20 @@ static void usb_drv_transfer(int ep, void *ptr, int len, bool out)
|
|||
restore_irq(oldlevel);
|
||||
}
|
||||
|
||||
int usb_drv_recv(int ep, void *ptr, int len)
|
||||
{
|
||||
usb_drv_transfer(EP_NUM(ep), ptr, len, true);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int usb_drv_send(int ep, void *ptr, int len)
|
||||
{
|
||||
ep = EP_NUM(ep);
|
||||
struct ep_type *endpoint = &endpoints[ep][1];
|
||||
endpoint->done = false;
|
||||
usb_drv_transfer(ep, ptr, len, false);
|
||||
ep_transfer(ep, ptr, len, false);
|
||||
while (endpoint->busy && !endpoint->done)
|
||||
semaphore_wait(&endpoint->complete, TIMEOUT_BLOCK);
|
||||
return endpoint->status;
|
||||
}
|
||||
|
||||
int usb_drv_send_nonblocking(int ep, void *ptr, int len)
|
||||
{
|
||||
usb_drv_transfer(EP_NUM(ep), ptr, len, false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void usb_drv_set_test_mode(int mode)
|
||||
{
|
||||
/* there is a perfect matching between usb test mode code
|
||||
* and the register field value */
|
||||
DCTL = (DCTL & ~bitm(DCTL, tstctl)) | (mode << DCTL_tstctl_bitp);
|
||||
}
|
||||
|
||||
void usb_drv_set_address(int address)
|
||||
{
|
||||
(void) address;
|
||||
}
|
||||
|
||||
void usb_drv_stall(int ep, bool stall, bool in)
|
||||
{
|
||||
if (stall)
|
||||
DEPCTL(ep, !in) |= DEPCTL_stall;
|
||||
else
|
||||
DEPCTL(ep, !in) &= ~DEPCTL_stall;
|
||||
}
|
||||
|
||||
bool usb_drv_stalled(int ep, bool in)
|
||||
{
|
||||
return DEPCTL(ep, !in) & DEPCTL_stall;
|
||||
}
|
||||
|
|
|
@ -35,20 +35,56 @@
|
|||
#include <inttypes.h>
|
||||
#include "power.h"
|
||||
|
||||
/* store per endpoint, per direction, information */
|
||||
struct ep_type
|
||||
{
|
||||
unsigned int size; /* length of the data buffer */
|
||||
struct semaphore complete; /* wait object */
|
||||
int8_t status; /* completion status (0 for success) */
|
||||
bool active; /* true is endpoint has been requested (true for EP0) */
|
||||
bool done; /* transfer completed */
|
||||
bool busy; /* true is a transfer is pending */
|
||||
};
|
||||
|
||||
bool usb_drv_stalled(int endpoint, bool in)
|
||||
{
|
||||
return DEPCTL(endpoint, !in) & DEPCTL_stall;
|
||||
}
|
||||
|
||||
void usb_drv_stall(int endpoint, bool stall, bool in)
|
||||
{
|
||||
if (stall)
|
||||
DEPCTL(endpoint, !in) |= DEPCTL_stall;
|
||||
else
|
||||
DEPCTL(endpoint, !in) &= ~DEPCTL_stall;
|
||||
}
|
||||
|
||||
void usb_drv_set_address(int address)
|
||||
{
|
||||
(void)address;
|
||||
/* Ignored intentionally, because the controller requires us to set the
|
||||
new address before sending the response for some reason. So we'll
|
||||
already set it when the control request arrives, before passing that
|
||||
into the USB core, which will then call this dummy function. */
|
||||
}
|
||||
|
||||
static void ep_transfer(int ep, void *ptr, int length, bool out);
|
||||
int usb_drv_send_nonblocking(int endpoint, void *ptr, int length)
|
||||
{
|
||||
ep_transfer(EP_NUM(endpoint), ptr, length, false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int usb_drv_recv(int endpoint, void* ptr, int length)
|
||||
{
|
||||
ep_transfer(EP_NUM(endpoint), ptr, length, true);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if CONFIG_CPU == AS3525v2 /* FIXME FIXME FIXME */
|
||||
# include "as3525/usb-drv-as3525v2.c"
|
||||
#else
|
||||
|
||||
struct ep_type
|
||||
{
|
||||
bool active;
|
||||
bool busy;
|
||||
bool done;
|
||||
int rc;
|
||||
int size;
|
||||
struct semaphore complete;
|
||||
} ;
|
||||
|
||||
static struct ep_type endpoints[USB_NUM_ENDPOINTS];
|
||||
|
||||
/* USB control requests may be up to 64 bytes in size.
|
||||
|
@ -58,10 +94,10 @@ static struct ep_type endpoints[USB_NUM_ENDPOINTS];
|
|||
e.g. write descriptor requests (which are rejected by us, but the
|
||||
payload is transferred anyway) do not cause memory corruption.
|
||||
Fixes FS#12310. -- Michael Sparmann (theseven) */
|
||||
static struct
|
||||
static union
|
||||
{
|
||||
struct usb_ctrlrequest header; /* 8 bytes */
|
||||
unsigned char payload[64 - sizeof(struct usb_ctrlrequest)];
|
||||
unsigned char payload[64];
|
||||
} ctrlreq USB_DEVBSS_ATTR;
|
||||
|
||||
int usb_drv_port_speed(void)
|
||||
|
@ -76,7 +112,7 @@ static void reset_endpoints(int reinit)
|
|||
{
|
||||
if (reinit) endpoints[i].active = false;
|
||||
endpoints[i].busy = false;
|
||||
endpoints[i].rc = -1;
|
||||
endpoints[i].status = -1;
|
||||
endpoints[i].done = true;
|
||||
semaphore_release(&endpoints[i].complete);
|
||||
}
|
||||
|
@ -184,7 +220,7 @@ static void handle_ep_int(bool out)
|
|||
if (endpoints[ep].busy)
|
||||
{
|
||||
endpoints[ep].busy = false;
|
||||
endpoints[ep].rc = 0;
|
||||
endpoints[ep].status = 0;
|
||||
endpoints[ep].done = true;
|
||||
usb_core_transfer_complete(ep, out ? USB_DIR_OUT : USB_DIR_IN, 0, bytes);
|
||||
semaphore_release(&endpoints[ep].complete);
|
||||
|
@ -199,7 +235,7 @@ static void handle_ep_int(bool out)
|
|||
if (endpoints[ep].busy)
|
||||
{
|
||||
endpoints[ep].busy = false;
|
||||
endpoints[ep].rc = 1;
|
||||
endpoints[ep].status = 1;
|
||||
endpoints[ep].done = true;
|
||||
semaphore_release(&endpoints[ep].complete);
|
||||
}
|
||||
|
@ -261,16 +297,7 @@ void INT_USB_FUNC(void)
|
|||
GINTSTS = ints;
|
||||
}
|
||||
|
||||
void usb_drv_set_address(int address)
|
||||
{
|
||||
(void)address;
|
||||
/* Ignored intentionally, because the controller requires us to set the
|
||||
new address before sending the response for some reason. So we'll
|
||||
already set it when the control request arrives, before passing that
|
||||
into the USB core, which will then call this dummy function. */
|
||||
}
|
||||
|
||||
static void ep_transfer(int ep, void *ptr, int length, int out)
|
||||
static void ep_transfer(int ep, void *ptr, int length, bool out)
|
||||
{
|
||||
endpoints[ep].busy = true;
|
||||
endpoints[ep].size = length;
|
||||
|
@ -294,19 +321,7 @@ int usb_drv_send(int endpoint, void *ptr, int length)
|
|||
ep_transfer(endpoint, ptr, length, false);
|
||||
while (!endpoints[endpoint].done && endpoints[endpoint].busy)
|
||||
semaphore_wait(&endpoints[endpoint].complete, TIMEOUT_BLOCK);
|
||||
return endpoints[endpoint].rc;
|
||||
}
|
||||
|
||||
int usb_drv_send_nonblocking(int endpoint, void *ptr, int length)
|
||||
{
|
||||
ep_transfer(EP_NUM(endpoint), ptr, length, false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int usb_drv_recv(int endpoint, void* ptr, int length)
|
||||
{
|
||||
ep_transfer(EP_NUM(endpoint), ptr, length, true);
|
||||
return 0;
|
||||
return endpoints[endpoint].status;
|
||||
}
|
||||
|
||||
void usb_drv_cancel_all_transfers(void)
|
||||
|
@ -321,19 +336,6 @@ void usb_drv_set_test_mode(int mode)
|
|||
(void)mode;
|
||||
}
|
||||
|
||||
bool usb_drv_stalled(int endpoint, bool in)
|
||||
{
|
||||
return DEPCTL(endpoint, !in) & DEPCTL_stall;
|
||||
}
|
||||
|
||||
void usb_drv_stall(int endpoint, bool stall, bool in)
|
||||
{
|
||||
if (stall)
|
||||
DEPCTL(endpoint, !in) |= DEPCTL_stall;
|
||||
else
|
||||
DEPCTL(endpoint, !in) &= ~DEPCTL_stall;
|
||||
}
|
||||
|
||||
void usb_drv_init(void)
|
||||
{
|
||||
for (unsigned i = 0; i < sizeof(endpoints)/sizeof(struct ep_type); i++)
|
||||
|
|
Loading…
Reference in a new issue