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:
parent
ad4deec074
commit
f3834a4626
2 changed files with 26 additions and 21 deletions
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue