|
|
|
@ -199,15 +199,13 @@ void udc_irq(void) |
|
|
|
|
mpc8xx_udc_flush_rx_fifo (); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Scan all RX/Bidirectional Endpoints for RX data. */ |
|
|
|
|
for (epid = 0; epid < MAX_ENDPOINTS; epid++) { |
|
|
|
|
|
|
|
|
|
if (!ep_ref[epid].prx) { |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
rx_cbdp = rx_cbdp_base = ep_ref[epid].prx; |
|
|
|
|
|
|
|
|
|
do { |
|
|
|
|
if (!(rx_cbdp->cbd_sc & RX_BD_E)) { |
|
|
|
|
|
|
|
|
@ -267,13 +265,12 @@ void udc_irq(void) |
|
|
|
|
if(usbp->usbs){ |
|
|
|
|
We could resume here when IDLE is deasserted ! |
|
|
|
|
Not worth doing, so long as we are self powered though. |
|
|
|
|
}*/ |
|
|
|
|
} |
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* udc_endpoint_write
|
|
|
|
|
* |
|
|
|
|
* Write some data to an endpoint |
|
|
|
@ -316,7 +313,8 @@ int udc_endpoint_write(struct usb_endpoint_instance *epi) |
|
|
|
|
mpc8xx_udc_set_nak (epid); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
mpc8xx_udc_init_tx(&udc_device->bus->endpoint_array[ep],epi->tx_urb); |
|
|
|
|
mpc8xx_udc_init_tx (&udc_device->bus->endpoint_array[ep], |
|
|
|
|
epi->tx_urb); |
|
|
|
|
ret = mpc8xx_udc_ep_tx (&udc_device->bus->endpoint_array[ep]); |
|
|
|
|
|
|
|
|
|
/* Remove temporary NAK */ |
|
|
|
@ -346,8 +344,7 @@ static int mpc8xx_udc_assign_urb(int ep, char direction) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (!ep_ref[ep].urb) { |
|
|
|
|
ep_ref[ep].urb = usbd_alloc_urb(udc_device,
|
|
|
|
|
udc_device->bus->endpoint_array); |
|
|
|
|
ep_ref[ep].urb = usbd_alloc_urb (udc_device, udc_device->bus->endpoint_array); |
|
|
|
|
if (!ep_ref[ep].urb) { |
|
|
|
|
goto err; |
|
|
|
|
} |
|
|
|
@ -439,10 +436,12 @@ void udc_setup_ep(struct usb_device_instance *device, unsigned int ep, |
|
|
|
|
if (!(ep_ref[ep].sc & EP_ATTACHED)) { |
|
|
|
|
if (direction) { |
|
|
|
|
mpc8xx_udc_cbd_attach (ep, |
|
|
|
|
epi->tx_packetSize, 0); |
|
|
|
|
epi->tx_packetSize, |
|
|
|
|
0); |
|
|
|
|
} else { |
|
|
|
|
mpc8xx_udc_cbd_attach (ep, |
|
|
|
|
0, epi->rcv_packetSize); |
|
|
|
|
0, |
|
|
|
|
epi->rcv_packetSize); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
usbp->usep[ep] = (ep << 12) | ((ep_attrib) << 8); |
|
|
|
@ -450,8 +449,7 @@ void udc_setup_ep(struct usb_device_instance *device, unsigned int ep, |
|
|
|
|
break; |
|
|
|
|
case USB_ENDPOINT_XFER_ISOC: |
|
|
|
|
default: |
|
|
|
|
serial_printf("Error endpoint attrib %d>3\n", |
|
|
|
|
ep_attrib); |
|
|
|
|
serial_printf ("Error endpoint attrib %d>3\n", ep_attrib); |
|
|
|
|
udc_state = STATE_ERROR; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
@ -504,8 +502,7 @@ void udc_enable(struct usb_device_instance *device) |
|
|
|
|
udc_device = device; |
|
|
|
|
|
|
|
|
|
if (!ep_ref[0].urb) { |
|
|
|
|
ep_ref[0].urb = usbd_alloc_urb(device,
|
|
|
|
|
device->bus->endpoint_array); |
|
|
|
|
ep_ref[0].urb = usbd_alloc_urb (device, device->bus->endpoint_array); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* Register interest in all events except SOF, enable transceiver */ |
|
|
|
@ -735,8 +732,7 @@ static short mpc8xx_udc_handle_txerr() |
|
|
|
|
} else { |
|
|
|
|
if (usbp->usep[ep] & STALL_BITMASK) { |
|
|
|
|
if (!ep) { |
|
|
|
|
usbp->usep[ep]&= |
|
|
|
|
~STALL_BITMASK; |
|
|
|
|
usbp->usep[ep] &= ~STALL_BITMASK; |
|
|
|
|
} |
|
|
|
|
} /* else NAK */ |
|
|
|
|
} |
|
|
|
@ -753,8 +749,7 @@ static short mpc8xx_udc_handle_txerr() |
|
|
|
|
static void mpc8xx_udc_advance_rx (volatile cbd_t ** rx_cbdp, int epid) |
|
|
|
|
{ |
|
|
|
|
if ((*rx_cbdp)->cbd_sc & RX_BD_W) { |
|
|
|
|
*rx_cbdp = (volatile cbd_t*) |
|
|
|
|
(endpoints[epid]->rbase + CFG_IMMR); |
|
|
|
|
*rx_cbdp = (volatile cbd_t *) (endpoints[epid]->rbase + CFG_IMMR); |
|
|
|
|
|
|
|
|
|
} else { |
|
|
|
|
(*rx_cbdp)++; |
|
|
|
@ -810,6 +805,7 @@ static void mpc8xx_udc_flush_tx_fifo(int epid) |
|
|
|
|
static void mpc8xx_udc_flush_rx_fifo () |
|
|
|
|
{ |
|
|
|
|
int i = 0; |
|
|
|
|
|
|
|
|
|
for (i = 0; i < RX_RING_SIZE; i++) { |
|
|
|
|
if (!(rx_cbd[i]->cbd_sc & RX_BD_E)) { |
|
|
|
|
ERR ("buf %p used rx data len = 0x%x sc=0x%x!\n", |
|
|
|
@ -905,7 +901,8 @@ static int mpc8xx_udc_ep_tx (struct usb_endpoint_instance *epi) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
tx_cbdp = (cbd_t *) (endpoints[ep]->tbptr + CFG_IMMR); |
|
|
|
|
while(tx_cbdp->cbd_sc&TX_BD_R){}; |
|
|
|
|
while (tx_cbdp->cbd_sc & TX_BD_R) { |
|
|
|
|
}; |
|
|
|
|
tx_cbdp->cbd_sc = (tx_cbdp->cbd_sc & TX_BD_W); |
|
|
|
|
|
|
|
|
|
pkt_len = urb->actual_length - epi->sent; |
|
|
|
@ -956,8 +953,7 @@ static int mpc8xx_udc_ep_tx (struct usb_endpoint_instance *epi) |
|
|
|
|
|
|
|
|
|
/* TX ACK : USB 2.0 8.7.2, Toggle PID, Advance TX */ |
|
|
|
|
epi->sent += pkt_len; |
|
|
|
|
epi->last = MIN (urb->actual_length - epi->sent,
|
|
|
|
|
epi->tx_packetSize); |
|
|
|
|
epi->last = MIN (urb->actual_length - epi->sent, epi->tx_packetSize); |
|
|
|
|
TOGGLE_TX_PID (ep_ref[ep].pid); |
|
|
|
|
|
|
|
|
|
if (epi->sent >= epi->tx_urb->actual_length) { |
|
|
|
@ -985,14 +981,11 @@ static int mpc8xx_udc_ep_tx (struct usb_endpoint_instance *epi) |
|
|
|
|
*/ |
|
|
|
|
static void mpc8xx_udc_dump_request (struct usb_device_request *request) |
|
|
|
|
{ |
|
|
|
|
DBG( |
|
|
|
|
"bmRequestType:%02x bRequest:%02x wValue:%04x " |
|
|
|
|
DBG ("bmRequestType:%02x bRequest:%02x wValue:%04x " |
|
|
|
|
"wIndex:%04x wLength:%04x ?\n", |
|
|
|
|
request->bmRequestType, |
|
|
|
|
request->bRequest, |
|
|
|
|
request->wValue, |
|
|
|
|
request->wIndex, |
|
|
|
|
request->wLength); |
|
|
|
|
request->wValue, request->wIndex, request->wLength); |
|
|
|
|
|
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
@ -1039,16 +1032,14 @@ static int mpc8xx_udc_ep0_rx_setup (volatile cbd_t * rx_cbdp) |
|
|
|
|
|
|
|
|
|
case USB_REQ_SET_CONFIGURATION: |
|
|
|
|
if (!purb->device_request.wValue) { |
|
|
|
|
|
|
|
|
|
/* Respond at default address */ |
|
|
|
|
usbp->usaddr = 0x00; |
|
|
|
|
mpc8xx_udc_state_transition_down (udc_device->device_state, |
|
|
|
|
STATE_ADDRESSED); |
|
|
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
|
|
/* TODO: Support multiple configurations */ |
|
|
|
|
mpc8xx_udc_state_transition_up(udc_device->device_state,STATE_CONFIGURED); |
|
|
|
|
mpc8xx_udc_state_transition_up (udc_device->device_state, |
|
|
|
|
STATE_CONFIGURED); |
|
|
|
|
for (x = 1; x < MAX_ENDPOINTS; x++) { |
|
|
|
|
if ((udc_device->bus->endpoint_array[x].endpoint_address & USB_ENDPOINT_DIR_MASK) |
|
|
|
|
== USB_DIR_IN) { |
|
|
|
@ -1059,7 +1050,6 @@ static int mpc8xx_udc_ep0_rx_setup (volatile cbd_t * rx_cbdp) |
|
|
|
|
/* Set configuration must unstall endpoints */ |
|
|
|
|
usbp->usep[x] &= ~STALL_BITMASK; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
default: |
|
|
|
@ -1074,6 +1064,7 @@ static int mpc8xx_udc_ep0_rx_setup (volatile cbd_t * rx_cbdp) |
|
|
|
|
mpc8xx_udc_ep_tx (epi); |
|
|
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
|
|
if (purb->actual_length) { |
|
|
|
|
ep_ref[0].pid = TX_BD_PID_DATA1; |
|
|
|
|
mpc8xx_udc_init_tx (epi, purb); |
|
|
|
@ -1084,18 +1075,14 @@ static int mpc8xx_udc_ep0_rx_setup (volatile cbd_t * rx_cbdp) |
|
|
|
|
|
|
|
|
|
if (purb->device_request.wValue == |
|
|
|
|
USB_DESCRIPTOR_TYPE_DEVICE) { |
|
|
|
|
if(le16_to_cpu(purb->device_request.wLength)> |
|
|
|
|
purb->actual_length){ |
|
|
|
|
if (le16_to_cpu (purb->device_request.wLength) |
|
|
|
|
> purb->actual_length) { |
|
|
|
|
/* Send EP0_MAX_PACKET_SIZE bytes
|
|
|
|
|
* unless correct size requested. |
|
|
|
|
*/ |
|
|
|
|
if(purb->actual_length >
|
|
|
|
|
epi->tx_packetSize){ |
|
|
|
|
|
|
|
|
|
purb->actual_length = |
|
|
|
|
epi->tx_packetSize; |
|
|
|
|
if (purb->actual_length > epi->tx_packetSize) { |
|
|
|
|
purb->actual_length = epi->tx_packetSize; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
mpc8xx_udc_ep_tx (epi); |
|
|
|
@ -1335,8 +1322,9 @@ static void mpc8xx_udc_cbd_attach (int ep, uchar tx_size, uchar rx_size) |
|
|
|
|
ep_ref[ep].sc |= EP_ATTACHED; |
|
|
|
|
|
|
|
|
|
DBG ("ep %d rbase 0x%08x rbptr 0x%08x tbase 0x%08x tbptr 0x%08x prx = %p\n", |
|
|
|
|
ep, endpoints[ep]->rbase, endpoints[ep]->rbptr, endpoints[ep]->tbase, |
|
|
|
|
endpoints[ep]->tbptr, ep_ref[ep].prx); |
|
|
|
|
ep, endpoints[ep]->rbase, endpoints[ep]->rbptr, |
|
|
|
|
endpoints[ep]->tbase, endpoints[ep]->tbptr, |
|
|
|
|
ep_ref[ep].prx); |
|
|
|
|
|
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|