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_int(void); /* Call from target INT handler */
void usb_drv_stall(int endpoint, bool stall,bool in); void usb_drv_stall(int endpoint, bool stall,bool in);
bool usb_drv_stalled(int endpoint,bool in); bool usb_drv_stalled(int endpoint,bool in);
int usb_drv_send(int endpoint, void* ptr, int length); int usb_drv_send(int endpoint, const void* ptr, int length);
int usb_drv_send_nonblocking(int endpoint, 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); int usb_drv_recv(int endpoint, void* ptr, int length);
void usb_drv_ack(struct usb_ctrlrequest* req); void usb_drv_ack(struct usb_ctrlrequest* req);
void usb_drv_set_address(int address); 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 & 1); /* Wait for OTG to ack reset */
while (!(GRSTCTL & 0x80000000)); /* Wait for OTG AHB master idle */ 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 */ GAHBCFG = 0x27; /* OTG AHB config: Unmask ints, burst length 4, DMA on */
GUSBCFG = 0x1408; /* OTG: 16bit PHY and some reserved bits */ GUSBCFG = 0x1408; /* OTG: 16bit PHY and some reserved bits */
@ -155,6 +157,7 @@ static void usb_reset(void)
DCTL = 0x800; /* Soft Reconnect */ DCTL = 0x800; /* Soft Reconnect */
DIEPMSK = 0x0D; /* IN EP interrupt mask */ DIEPMSK = 0x0D; /* IN EP interrupt mask */
DOEPMSK = 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 */ GINTMSK = 0xC3000; /* Interrupt mask: IN event, OUT event, bus reset */
reset_endpoints(1); reset_endpoints(1);
@ -164,14 +167,16 @@ static void usb_reset(void)
void INT_USB_FUNC(void) void INT_USB_FUNC(void)
{ {
int i; int i;
if (GINTSTS & 0x1000) /* bus reset */ uint32_t ints = GINTSTS;
uint32_t epints;
if (ints & 0x1000) /* bus reset */
{ {
DCFG = 4; /* Address 0 */ DCFG = 4; /* Address 0 */
reset_endpoints(1); reset_endpoints(1);
usb_core_bus_reset(); 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 */ /* Set up the maximum packet sizes accordingly */
uint32_t maxpacket = usb_drv_port_speed() ? 512 : 64; uint32_t maxpacket = usb_drv_port_speed() ? 512 : 64;
@ -181,11 +186,11 @@ void INT_USB_FUNC(void)
DOEPCTL4 = (DOEPCTL4 & ~0x000003FF) | maxpacket; DOEPCTL4 = (DOEPCTL4 & ~0x000003FF) | maxpacket;
} }
if (GINTSTS & 0x40000) /* IN EP event */ if (ints & 0x40000) /* IN EP event */
for (i = 0; i < 5; i ++) for (i = 0; i < 4; i += i + 1) // 0, 1, 3
if (i != 2 && i != 4 && DIEPINT(i)) if ((epints = DIEPINT(i)))
{ {
if (DIEPINT(i) & 1) /* Transfer completed */ if (epints & 1) /* Transfer completed */
{ {
invalidate_dcache(); invalidate_dcache();
int bytes = endpoints[i].size - (DIEPTSIZ(i) & 0x3FFFF); int bytes = endpoints[i].size - (DIEPTSIZ(i) & 0x3FFFF);
@ -198,9 +203,9 @@ void INT_USB_FUNC(void)
wakeup_signal(&endpoints[i].complete); 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); panicf("USB: AHB error on IN EP%d", i);
if (DIEPINT(i) & 8) /* Timeout */ if (epints & 8) /* Timeout */
{ {
if (endpoints[i].busy) if (endpoints[i].busy)
{ {
@ -210,14 +215,14 @@ void INT_USB_FUNC(void)
wakeup_signal(&endpoints[i].complete); 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) 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(); invalidate_dcache();
int bytes = endpoints[i].size - (DOEPTSIZ(i) & 0x3FFFF); int bytes = endpoints[i].size - (DOEPTSIZ(i) & 0x3FFFF);
@ -230,9 +235,9 @@ void INT_USB_FUNC(void)
wakeup_signal(&endpoints[i].complete); 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); panicf("USB: AHB error on OUT EP%d", i);
if (DOEPINT(i) & 8) /* SETUP phase done */ if (epints & 8) /* SETUP phase done */
{ {
invalidate_dcache(); invalidate_dcache();
if (i == 0) if (i == 0)
@ -255,10 +260,10 @@ void INT_USB_FUNC(void)
DOEPDMA0 = (uint32_t)&ctrlreq; DOEPDMA0 = (uint32_t)&ctrlreq;
DOEPCTL0 |= 0x84000000; DOEPCTL0 |= 0x84000000;
} }
DOEPINT(i) = DOEPINT(i); DOEPINT(i) = epints;
} }
GINTSTS = GINTSTS; GINTSTS = ints;
} }
void usb_drv_set_address(int address) 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. */ 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].busy = true;
endpoints[ep].size = length; 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 */ 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; endpoint &= 0x7f;
endpoints[endpoint].done = false; endpoints[endpoint].done = false;
@ -323,7 +328,7 @@ int usb_drv_send(int endpoint, void *ptr, int length)
return endpoints[endpoint].rc; 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); ep_send(endpoint & 0x7f, ptr, length);
return 0; return 0;