1
0
Fork 0
forked from len0rd/rockbox

emBIOS backports part one: Fix an annoying race condition in the Synopsys OTG driver, and a bit of const correctness.

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@27779 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Michael Sparmann 2010-08-12 08:35:43 +00:00
parent ad4deec074
commit f3834a4626
2 changed files with 26 additions and 21 deletions

View file

@ -33,8 +33,8 @@ void usb_drv_attach(void);
void usb_drv_int(void); /* Call from target INT handler */
void usb_drv_stall(int endpoint, bool stall,bool in);
bool usb_drv_stalled(int endpoint,bool in);
int usb_drv_send(int endpoint, void* ptr, int length);
int usb_drv_send_nonblocking(int endpoint, void* ptr, int length);
int usb_drv_send(int endpoint, const void* ptr, int length);
int usb_drv_send_nonblocking(int endpoint, const void* ptr, int length);
int usb_drv_recv(int endpoint, void* ptr, int length);
void usb_drv_ack(struct usb_ctrlrequest* req);
void usb_drv_set_address(int address);

View file

@ -148,6 +148,8 @@ static void usb_reset(void)
while (GRSTCTL & 1); /* Wait for OTG to ack reset */
while (!(GRSTCTL & 0x80000000)); /* Wait for OTG AHB master idle */
GRXFSIZ = 0x00000200; /* RX FIFO: 512 bytes */
GNPTXFSIZ = 0x02000200; /* Non-periodic TX FIFO: 512 bytes */
GAHBCFG = 0x27; /* OTG AHB config: Unmask ints, burst length 4, DMA on */
GUSBCFG = 0x1408; /* OTG: 16bit PHY and some reserved bits */
@ -155,6 +157,7 @@ static void usb_reset(void)
DCTL = 0x800; /* Soft Reconnect */
DIEPMSK = 0x0D; /* IN EP interrupt mask */
DOEPMSK = 0x0D; /* IN EP interrupt mask */
DAINTMSK = 0xFFFFFFFF; /* Enable interrupts on all endpoints */
GINTMSK = 0xC3000; /* Interrupt mask: IN event, OUT event, bus reset */
reset_endpoints(1);
@ -164,14 +167,16 @@ static void usb_reset(void)
void INT_USB_FUNC(void)
{
int i;
if (GINTSTS & 0x1000) /* bus reset */
uint32_t ints = GINTSTS;
uint32_t epints;
if (ints & 0x1000) /* bus reset */
{
DCFG = 4; /* Address 0 */
reset_endpoints(1);
usb_core_bus_reset();
}
if (GINTSTS & 0x2000) /* enumeration done, we now know the speed */
if (ints & 0x2000) /* enumeration done, we now know the speed */
{
/* Set up the maximum packet sizes accordingly */
uint32_t maxpacket = usb_drv_port_speed() ? 512 : 64;
@ -181,11 +186,11 @@ void INT_USB_FUNC(void)
DOEPCTL4 = (DOEPCTL4 & ~0x000003FF) | maxpacket;
}
if (GINTSTS & 0x40000) /* IN EP event */
for (i = 0; i < 5; i ++)
if (i != 2 && i != 4 && DIEPINT(i))
if (ints & 0x40000) /* IN EP event */
for (i = 0; i < 4; i += i + 1) // 0, 1, 3
if ((epints = DIEPINT(i)))
{
if (DIEPINT(i) & 1) /* Transfer completed */
if (epints & 1) /* Transfer completed */
{
invalidate_dcache();
int bytes = endpoints[i].size - (DIEPTSIZ(i) & 0x3FFFF);
@ -198,9 +203,9 @@ void INT_USB_FUNC(void)
wakeup_signal(&endpoints[i].complete);
}
}
if (DIEPINT(i) & 4) /* AHB error */
if (epints & 4) /* AHB error */
panicf("USB: AHB error on IN EP%d", i);
if (DIEPINT(i) & 8) /* Timeout */
if (epints & 8) /* Timeout */
{
if (endpoints[i].busy)
{
@ -210,14 +215,14 @@ void INT_USB_FUNC(void)
wakeup_signal(&endpoints[i].complete);
}
}
DIEPINT(i) = DIEPINT(i);
DIEPINT(i) = epints;
}
if (GINTSTS & 0x80000) /* OUT EP event */
if (ints & 0x80000) /* OUT EP event */
for (i = 0; i < 5; i += 2)
if (DOEPINT(i))
if ((epints = DOEPINT(i)))
{
if (DOEPINT(i) & 1) /* Transfer completed */
if (epints & 1) /* Transfer completed */
{
invalidate_dcache();
int bytes = endpoints[i].size - (DOEPTSIZ(i) & 0x3FFFF);
@ -230,9 +235,9 @@ void INT_USB_FUNC(void)
wakeup_signal(&endpoints[i].complete);
}
}
if (DOEPINT(i) & 4) /* AHB error */
if (epints & 4) /* AHB error */
panicf("USB: AHB error on OUT EP%d", i);
if (DOEPINT(i) & 8) /* SETUP phase done */
if (epints & 8) /* SETUP phase done */
{
invalidate_dcache();
if (i == 0)
@ -255,10 +260,10 @@ void INT_USB_FUNC(void)
DOEPDMA0 = (uint32_t)&ctrlreq;
DOEPCTL0 |= 0x84000000;
}
DOEPINT(i) = DOEPINT(i);
DOEPINT(i) = epints;
}
GINTSTS = GINTSTS;
GINTSTS = ints;
}
void usb_drv_set_address(int address)
@ -270,7 +275,7 @@ void usb_drv_set_address(int address)
into the USB core, which will then call this dummy function. */
}
static void ep_send(int ep, void *ptr, int length)
static void ep_send(int ep, const void *ptr, int length)
{
endpoints[ep].busy = true;
endpoints[ep].size = length;
@ -313,7 +318,7 @@ static void ep_recv(int ep, void *ptr, int length)
DOEPCTL(ep) |= 0x84000000; /* EPx OUT ENABLE CLEARNAK */
}
int usb_drv_send(int endpoint, void *ptr, int length)
int usb_drv_send(int endpoint, const void *ptr, int length)
{
endpoint &= 0x7f;
endpoints[endpoint].done = false;
@ -323,7 +328,7 @@ int usb_drv_send(int endpoint, void *ptr, int length)
return endpoints[endpoint].rc;
}
int usb_drv_send_nonblocking(int endpoint, void *ptr, int length)
int usb_drv_send_nonblocking(int endpoint, const void *ptr, int length)
{
ep_send(endpoint & 0x7f, ptr, length);
return 0;