jz4760: Reformat USB driver a little. Prep work for later changes.

Change-Id: I74d068661ea8a8a59a88f0c2c5a938dcf6fb8b20
This commit is contained in:
Solomon Peachy 2022-05-12 22:59:58 -04:00
parent b9e7075837
commit 7296f30490

View file

@ -54,16 +54,14 @@
OUT = HOST->DEV, (ie we recv) OUT = HOST->DEV, (ie we recv)
*/ */
enum ep_type enum ep_type {
{
ep_control, ep_control,
ep_bulk, ep_bulk,
ep_interrupt, ep_interrupt,
ep_isochronous ep_isochronous
}; };
struct usb_endpoint struct usb_endpoint {
{
const enum ep_type type; const enum ep_type type;
const long fifo_addr; const long fifo_addr;
unsigned short fifo_size; unsigned short fifo_size;
@ -76,8 +74,7 @@ struct usb_endpoint
volatile void *buf; volatile void *buf;
volatile size_t length; volatile size_t length;
union union {
{
volatile size_t sent; volatile size_t sent;
volatile size_t received; volatile size_t received;
}; };
@ -94,8 +91,7 @@ struct usb_endpoint
#define short_not_ok 1 /* only works for mass storage.. */ #define short_not_ok 1 /* only works for mass storage.. */
#define ep_doublebuf(__ep) 0 #define ep_doublebuf(__ep) 0
static union static union {
{
int buf[64 / sizeof(int)]; int buf[64 / sizeof(int)];
struct usb_ctrlrequest request; struct usb_ctrlrequest request;
} ep0_rx; } ep0_rx;
@ -106,7 +102,7 @@ static volatile bool ep0_data_requested = false;
static struct usb_endpoint endpoints[] = static struct usb_endpoint endpoints[] =
{ {
EP_INIT(ep_control, USB_FIFO_EP(0), 64, NULL), EP_INIT(ep_control, USB_FIFO_EP(0), 64, NULL),
EP_INIT(ep_control, USB_FIFO_EP(0), 64, ep0_rx.buf), EP_INIT(ep_control, USB_FIFO_EP(0), 64, NULL),
EP_INIT(ep_bulk, USB_FIFO_EP(1), 512, NULL), EP_INIT(ep_bulk, USB_FIFO_EP(1), 512, NULL),
EP_INIT(ep_bulk, USB_FIFO_EP(1), 512, NULL), EP_INIT(ep_bulk, USB_FIFO_EP(1), 512, NULL),
EP_INIT(ep_interrupt, USB_FIFO_EP(2), 512, NULL), EP_INIT(ep_interrupt, USB_FIFO_EP(2), 512, NULL),
@ -127,19 +123,14 @@ static void readFIFO(struct usb_endpoint *ep, unsigned int size)
register unsigned int s = size >> 2; register unsigned int s = size >> 2;
register unsigned int x; register unsigned int x;
if(size > 0) if(size > 0) {
{ if (((unsigned int)ptr & 3) == 0) {
if( ((unsigned int)ptr & 3) == 0 ) while(s--) {
{
while(s--)
*ptr32++ = REG32(ep->fifo_addr); *ptr32++ = REG32(ep->fifo_addr);
ptr = (unsigned char*)ptr32;
} }
else ptr = (unsigned char*)ptr32;
{ } else {
while(s--) while(s--) {
{
x = REG32(ep->fifo_addr); x = REG32(ep->fifo_addr);
*ptr++ = x & 0xFF; x >>= 8; *ptr++ = x & 0xFF; x >>= 8;
*ptr++ = x & 0xFF; x >>= 8; *ptr++ = x & 0xFF; x >>= 8;
@ -147,12 +138,12 @@ static void readFIFO(struct usb_endpoint *ep, unsigned int size)
*ptr++ = x; *ptr++ = x;
} }
} }
s = size & 3; s = size & 3;
while(s--) while(s--) {
*ptr++ = REG8(ep->fifo_addr); *ptr++ = REG8(ep->fifo_addr);
} }
} }
}
static void writeFIFO(struct usb_endpoint *ep, size_t size) static void writeFIFO(struct usb_endpoint *ep, size_t size)
{ {
@ -163,18 +154,14 @@ static void writeFIFO(struct usb_endpoint *ep, size_t size)
register size_t s = size >> 2; register size_t s = size >> 2;
register unsigned int x; register unsigned int x;
if(size > 0) if (size > 0) {
{ if (((unsigned int)d8 & 3) == 0) {
if( ((unsigned int)d8 & 3) == 0 ) while (s--) {
{
while (s--)
REG32(ep->fifo_addr) = *d32++; REG32(ep->fifo_addr) = *d32++;
d8 = (unsigned char *)d32;
} }
else d8 = (unsigned char *)d32;
{ } else {
while (s--) while (s--) {
{
x = (unsigned int)(*d8++) & 0xff; x = (unsigned int)(*d8++) & 0xff;
x |= ((unsigned int)(*d8++) & 0xff) << 8; x |= ((unsigned int)(*d8++) & 0xff) << 8;
x |= ((unsigned int)(*d8++) & 0xff) << 16; x |= ((unsigned int)(*d8++) & 0xff) << 16;
@ -182,10 +169,8 @@ static void writeFIFO(struct usb_endpoint *ep, size_t size)
REG32(ep->fifo_addr) = x; REG32(ep->fifo_addr) = x;
} }
} }
s = size & 3;
if( (s = size & 3) ) while (s--) {
{
while (s--)
REG8(ep->fifo_addr) = *d8++; REG8(ep->fifo_addr) = *d8++;
} }
} }
@ -195,18 +180,17 @@ static void flushFIFO(struct usb_endpoint *ep)
{ {
logf("%s(%d)", __func__, EP_NUMBER(ep)); logf("%s(%d)", __func__, EP_NUMBER(ep));
switch (ep->type) switch (ep->type) {
{
case ep_control: case ep_control:
break; break;
case ep_bulk: case ep_bulk:
case ep_interrupt: case ep_interrupt:
case ep_isochronous: case ep_isochronous:
if(EP_IS_IN(ep)) if (EP_IS_IN(ep)) {
REG_USB_INCSR |= (USB_INCSR_FF | USB_INCSR_CDT); REG_USB_INCSR |= (USB_INCSR_FF | USB_INCSR_CDT);
else } else {
REG_USB_OUTCSR |= (USB_OUTCSR_FF | USB_OUTCSR_CDT); REG_USB_OUTCSR |= (USB_OUTCSR_FF | USB_OUTCSR_CDT);
}
break; break;
} }
} }
@ -217,9 +201,10 @@ static inline void ep_transfer_completed(struct usb_endpoint* ep)
ep->length = 0; ep->length = 0;
ep->buf = NULL; ep->buf = NULL;
ep->busy = false; ep->busy = false;
if(ep->wait) if (ep->wait) {
semaphore_release(&ep->complete); semaphore_release(&ep->complete);
} }
}
static void EP0_send(void) static void EP0_send(void)
{ {
@ -232,28 +217,27 @@ static void EP0_send(void)
logf("%s(): 0x%x %d %d", __func__, csr0, ep->sent, ep->length); logf("%s(): 0x%x %d %d", __func__, csr0, ep->sent, ep->length);
if(ep->sent == 0) if (ep->sent == 0) {
{
length = MIN(ep->length, ep->fifo_size); length = MIN(ep->length, ep->fifo_size);
REG_USB_CSR0 = (csr0 | USB_CSR0_FLUSHFIFO); REG_USB_CSR0 = (csr0 | USB_CSR0_FLUSHFIFO);
} } else {
else
length = MIN(EP_BUF_LEFT(ep), ep->fifo_size); length = MIN(EP_BUF_LEFT(ep), ep->fifo_size);
}
writeFIFO(ep, length); writeFIFO(ep, length);
ep->sent += length; ep->sent += length;
if(ep->sent >= ep->length) if (ep->sent >= ep->length) {
{
REG_USB_CSR0 = (csr0 | USB_CSR0_INPKTRDY | USB_CSR0_DATAEND); /* Set data end! */ REG_USB_CSR0 = (csr0 | USB_CSR0_INPKTRDY | USB_CSR0_DATAEND); /* Set data end! */
if (!ep->wait) if (!ep->wait) {
usb_core_transfer_complete(EP_CONTROL, USB_DIR_IN, 0, ep->sent); usb_core_transfer_complete(EP_CONTROL, USB_DIR_IN, 0, ep->sent);
}
ep->rc = 0; ep->rc = 0;
ep_transfer_completed(ep); ep_transfer_completed(ep);
} } else {
else
REG_USB_CSR0 = (csr0 | USB_CSR0_INPKTRDY); REG_USB_CSR0 = (csr0 | USB_CSR0_INPKTRDY);
} }
}
static void EP0_handler(void) static void EP0_handler(void)
{ {
@ -270,8 +254,7 @@ static void EP0_handler(void)
/* Check for SentStall: /* Check for SentStall:
This bit is set when a STALL handshake is transmitted. The CPU should clear this bit. This bit is set when a STALL handshake is transmitted. The CPU should clear this bit.
*/ */
if(csr0 & USB_CSR0_SENTSTALL) if (csr0 & USB_CSR0_SENTSTALL) {
{
REG_USB_CSR0 = csr0 & ~USB_CSR0_SENTSTALL; REG_USB_CSR0 = csr0 & ~USB_CSR0_SENTSTALL;
return; return;
} }
@ -281,69 +264,63 @@ static void EP0_handler(void)
An interrupt will be generated and the FIFO flushed at this time. An interrupt will be generated and the FIFO flushed at this time.
The bit is cleared by the CPU writing a 1 to the ServicedSetupEnd bit. The bit is cleared by the CPU writing a 1 to the ServicedSetupEnd bit.
*/ */
if(csr0 & USB_CSR0_SETUPEND) if (csr0 & USB_CSR0_SETUPEND) {
{
csr0 |= USB_CSR0_SVDSETUPEND; csr0 |= USB_CSR0_SVDSETUPEND;
REG_USB_CSR0 = csr0; REG_USB_CSR0 = csr0;
ep0_data_supplied = false; ep0_data_supplied = false;
ep0_data_requested = false; ep0_data_requested = false;
if (ep_send->busy) if (ep_send->busy) {
{
if (!ep_send->wait) if (!ep_send->wait)
usb_core_transfer_complete(EP_CONTROL, USB_DIR_IN, -1, 0); usb_core_transfer_complete(EP_CONTROL, USB_DIR_IN, -1, 0);
ep_transfer_completed(ep_send); ep_transfer_completed(ep_send);
} }
if (ep_recv->busy) if (ep_recv->busy) {
{
usb_core_transfer_complete(EP_CONTROL, USB_DIR_OUT, -1, 0); usb_core_transfer_complete(EP_CONTROL, USB_DIR_OUT, -1, 0);
ep_transfer_completed(ep_recv); ep_transfer_completed(ep_recv);
} }
} }
/* Call relevant routines for endpoint 0 state */ /* Call relevant routines for endpoint 0 state */
if(csr0 & USB_CSR0_OUTPKTRDY) /* There is a packet in the fifo */ if (csr0 & USB_CSR0_OUTPKTRDY) { /* There is a packet in the fifo */
{ if (ep_send->busy) {
if (ep_send->busy) if (!ep_send->wait) {
{
if (!ep_send->wait)
usb_core_transfer_complete(EP_CONTROL, USB_DIR_IN, -1, 0); usb_core_transfer_complete(EP_CONTROL, USB_DIR_IN, -1, 0);
}
ep_transfer_completed(ep_send); ep_transfer_completed(ep_send);
} }
if (ep_recv->busy && ep_recv->buf && ep_recv->length) if (ep_recv->busy && ep_recv->buf && ep_recv->length) {
{
unsigned int size = REG_USB_COUNT0; unsigned int size = REG_USB_COUNT0;
readFIFO(ep_recv, size); readFIFO(ep_recv, size);
ep_recv->received += size; ep_recv->received += size;
if (size < ep_recv->fifo_size || ep_recv->received >= ep_recv->length) if (size < ep_recv->fifo_size || ep_recv->received >= ep_recv->length) {
{
REG_USB_CSR0 = csr0 | USB_CSR0_SVDOUTPKTRDY | USB_CSR0_DATAEND; /* Set data end! */ REG_USB_CSR0 = csr0 | USB_CSR0_SVDOUTPKTRDY | USB_CSR0_DATAEND; /* Set data end! */
usb_core_transfer_complete(EP_CONTROL, USB_DIR_OUT, 0, ep_recv->received); usb_core_transfer_complete(EP_CONTROL, USB_DIR_OUT, 0, ep_recv->received);
ep_transfer_completed(ep_recv); ep_transfer_completed(ep_recv);
} else {
REG_USB_CSR0 = csr0 | USB_CSR0_SVDOUTPKTRDY; /* clear OUTPKTRDY bit */
} }
else REG_USB_CSR0 = csr0 | USB_CSR0_SVDOUTPKTRDY; /* clear OUTPKTRDY bit */ } else if (!ep0_data_supplied) {
}
else if (!ep0_data_supplied)
{
ep_recv->buf = ep0_rx.buf; ep_recv->buf = ep0_rx.buf;
readFIFO(ep_recv, REG_USB_COUNT0); readFIFO(ep_recv, REG_USB_COUNT0);
csr0 |= USB_CSR0_SVDOUTPKTRDY; csr0 |= USB_CSR0_SVDOUTPKTRDY;
if (!ep0_rx.request.wLength) if (!ep0_rx.request.wLength) {
{
csr0 |= USB_CSR0_DATAEND; /* Set data end! */ csr0 |= USB_CSR0_DATAEND; /* Set data end! */
ep0_data_requested = false; ep0_data_requested = false;
ep0_data_supplied = false; ep0_data_supplied = false;
} } else if (ep0_rx.request.bRequestType & USB_DIR_IN) {
else if (ep0_rx.request.bRequestType & USB_DIR_IN)
ep0_data_requested = true; ep0_data_requested = true;
else ep0_data_supplied = true; } else {
ep0_data_supplied = true;
}
REG_USB_CSR0 = csr0; REG_USB_CSR0 = csr0;
usb_core_legacy_control_request(&ep0_rx.request); usb_core_legacy_control_request(&ep0_rx.request);
ep_transfer_completed(ep_recv); ep_transfer_completed(ep_recv);
} }
} }
else if (ep_send->busy) else if (ep_send->busy) {
EP0_send(); EP0_send();
} }
}
/* Does new work */ /* Does new work */
static void EPIN_send(unsigned int endpoint) static void EPIN_send(unsigned int endpoint)
@ -613,8 +590,7 @@ static void EPOUT_ready(unsigned int endpoint)
select_endpoint(endpoint); select_endpoint(endpoint);
csr = REG_USB_OUTCSR; csr = REG_USB_OUTCSR;
if(!ep->busy) if (!ep->busy) {
{
logf("Entered EPOUT handler without work!"); logf("Entered EPOUT handler without work!");
return; return;
} }
@ -717,15 +693,15 @@ static void setup_endpoint(struct usb_endpoint *ep)
select_endpoint(endpoint); select_endpoint(endpoint);
if (ep->busy) if (ep->busy) {
{ if (EP_IS_IN(ep)) {
if(EP_IS_IN(ep))
{
if (ep->wait) if (ep->wait)
semaphore_release(&ep->complete); semaphore_release(&ep->complete);
else usb_core_transfer_complete(endpoint, USB_DIR_IN, -1, 0); else
usb_core_transfer_complete(endpoint, USB_DIR_IN, -1, 0);
} else {
usb_core_transfer_complete(endpoint, USB_DIR_OUT, -1, 0);
} }
else usb_core_transfer_complete(endpoint, USB_DIR_OUT, -1, 0);
} }
ep->busy = false; ep->busy = false;
@ -738,8 +714,7 @@ static void setup_endpoint(struct usb_endpoint *ep)
ep->config = REG_USB_CONFIGDATA; ep->config = REG_USB_CONFIGDATA;
if(EP_IS_IN(ep)) if(EP_IS_IN(ep)) {
{
csr = (USB_INCSR_FF | USB_INCSR_CDT); csr = (USB_INCSR_FF | USB_INCSR_CDT);
csrh = USB_INCSRH_MODE; csrh = USB_INCSRH_MODE;
@ -754,9 +729,7 @@ static void setup_endpoint(struct usb_endpoint *ep)
if (ep->allocated) if (ep->allocated)
REG_USB_INTRINE |= USB_INTR_EP(EP_NUMBER2(ep)); REG_USB_INTRINE |= USB_INTR_EP(EP_NUMBER2(ep));
} } else {
else
{
csr = (USB_OUTCSR_FF | USB_OUTCSR_CDT); csr = (USB_OUTCSR_FF | USB_OUTCSR_CDT);
csrh = 0; csrh = 0;
@ -813,8 +786,7 @@ static void udc_reset(void)
endpoints[0].config = REG_USB_CONFIGDATA; endpoints[0].config = REG_USB_CONFIGDATA;
endpoints[1].config = REG_USB_CONFIGDATA; endpoints[1].config = REG_USB_CONFIGDATA;
if (endpoints[0].busy) if (endpoints[0].busy) {
{
if (endpoints[0].wait) if (endpoints[0].wait)
semaphore_release(&endpoints[0].complete); semaphore_release(&endpoints[0].complete);
else else
@ -896,10 +868,9 @@ bool usb_drv_stalled(int endpoint, bool in)
select_endpoint(endpoint); select_endpoint(endpoint);
if(endpoint == EP_CONTROL) if (endpoint == EP_CONTROL) {
return (REG_USB_CSR0 & USB_CSR0_SENDSTALL) != 0; return (REG_USB_CSR0 & USB_CSR0_SENDSTALL) != 0;
else } else {
{
if (in) if (in)
return (REG_USB_INCSR & USB_INCSR_SENDSTALL) != 0; return (REG_USB_INCSR & USB_INCSR_SENDSTALL) != 0;
else else
@ -915,24 +886,18 @@ void usb_drv_stall(int endpoint, bool stall, bool in)
select_endpoint(endpoint); select_endpoint(endpoint);
if(endpoint == EP_CONTROL) if(endpoint == EP_CONTROL) {
{
if(stall) if(stall)
REG_USB_CSR0 |= USB_CSR0_SENDSTALL; REG_USB_CSR0 |= USB_CSR0_SENDSTALL;
else else
REG_USB_CSR0 &= ~USB_CSR0_SENDSTALL; REG_USB_CSR0 &= ~USB_CSR0_SENDSTALL;
} } else {
else if(in) {
{
if(in)
{
if(stall) if(stall)
REG_USB_INCSR |= USB_INCSR_SENDSTALL; REG_USB_INCSR |= USB_INCSR_SENDSTALL;
else else
REG_USB_INCSR = (REG_USB_INCSR & ~USB_INCSR_SENDSTALL) | USB_INCSR_CDT; REG_USB_INCSR = (REG_USB_INCSR & ~USB_INCSR_SENDSTALL) | USB_INCSR_CDT;
} } else {
else
{
if(stall) if(stall)
REG_USB_OUTCSR |= USB_OUTCSR_SENDSTALL; REG_USB_OUTCSR |= USB_OUTCSR_SENDSTALL;
else else
@ -1097,8 +1062,7 @@ int usb_drv_send_nonblocking(int endpoint, void* ptr, int length)
logf("%s(%d, 0x%x, %d)", __func__, endpoint, (int)ptr, length); logf("%s(%d, 0x%x, %d)", __func__, endpoint, (int)ptr, length);
if (ep->allocated) if (ep->allocated) {
{
usb_drv_send_internal(ep, ptr, length, false); usb_drv_send_internal(ep, ptr, length, false);
return 0; return 0;
} }
@ -1112,8 +1076,7 @@ int usb_drv_send(int endpoint, void* ptr, int length)
logf("%s(%d, 0x%x, %d)", __func__, endpoint, (int)ptr, length); logf("%s(%d, 0x%x, %d)", __func__, endpoint, (int)ptr, length);
if (ep->allocated) if (ep->allocated) {
{
usb_drv_send_internal(ep, ptr, length, true); usb_drv_send_internal(ep, ptr, length, true);
return ep->rc; return ep->rc;
} }
@ -1188,7 +1151,8 @@ void usb_drv_cancel_all_transfers(void)
{ {
logf("%s()", __func__); logf("%s()", __func__);
unsigned int i, flags = disable_irq_save(); unsigned int i;
unsigned int flags = disable_irq_save();
#ifdef USE_USB_DMA #ifdef USE_USB_DMA
/* Disable DMA */ /* Disable DMA */
@ -1204,7 +1168,8 @@ void usb_drv_cancel_all_transfers(void)
usb_core_transfer_complete(i >> 1, USB_DIR_OUT, -1, 0); usb_core_transfer_complete(i >> 1, USB_DIR_OUT, -1, 0);
else if (endpoints[i].wait) else if (endpoints[i].wait)
semaphore_release(&endpoints[i].complete); semaphore_release(&endpoints[i].complete);
else usb_core_transfer_complete(i >> 1, USB_DIR_IN, -1, 0); else
usb_core_transfer_complete(i >> 1, USB_DIR_IN, -1, 0);
} }
if(i != 1) /* ep0 out needs special handling */ if(i != 1) /* ep0 out needs special handling */