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_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);
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue