forked from yystopf/xiuos
Modify Transfer TRB code in xHCI to apply to XiZi AIOT.
This commit is contained in:
parent
b383f88d7d
commit
5e829d5da0
|
@ -859,6 +859,9 @@ int xhci_usbh_pipe_alloc(usbh_pipe_t *pipe, const struct usbh_endpoint_cfg *ep_c
|
|||
struct usbh_hubport *hport = ep_cfg->hport;
|
||||
struct xhci_endpoint *ppipe = usb_align(XHCI_RING_SIZE, sizeof(struct xhci_endpoint));
|
||||
struct xhci_slot *slot;
|
||||
uintptr_t ring_vir;
|
||||
uintptr_t ring_phy;
|
||||
size_t len;
|
||||
|
||||
if (NULL == ppipe) {
|
||||
return -ENOMEM;
|
||||
|
@ -877,6 +880,19 @@ int xhci_usbh_pipe_alloc(usbh_pipe_t *pipe, const struct usbh_endpoint_cfg *ep_c
|
|||
ppipe->ep_type = ep_cfg->ep_type;
|
||||
ppipe->burst = 0U;
|
||||
|
||||
/* Allocate xHCI ring */
|
||||
len = sizeof(*ppipe->ep_reqs);
|
||||
rc = naive_mmap(&ring_vir, &ring_phy, len, false);
|
||||
if(rc != 0){
|
||||
USB_LOG_ERR("XHCI %s could not allocate xhci device context\n", xhci->name );
|
||||
rc = -ENOMEM;
|
||||
goto failed;
|
||||
}
|
||||
ppipe->ep_reqs_vir = ring_vir;
|
||||
ppipe->ep_reqs_phy = ring_phy;
|
||||
ppipe->ep_reqs = (struct xhci_ring *)ring_vir;
|
||||
memset ( ppipe->ep_reqs, 0, len );
|
||||
|
||||
if (ppipe->address == 0) { /* if try to allocate ctrl ep, open device first */
|
||||
USB_LOG_DBG("allocate device for port-%d \r\n", hport->port);
|
||||
rc = xhci_device_open(xhci, ppipe, &slot_id);
|
||||
|
@ -943,7 +959,66 @@ int xhci_usbh_pipe_free(usbh_pipe_t pipe){
|
|||
|
||||
|
||||
int xhci_usbh_submit_urb(struct usbh_urb *urb){
|
||||
return 0;
|
||||
int ret = 0;
|
||||
if (!urb || !urb->pipe) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
struct xhci_endpoint *ppipe = (struct xhci_endpoint *)urb->pipe;
|
||||
struct xhci_host *xhci = ppipe->xhci;
|
||||
struct usb_setup_packet *setup = urb->setup;
|
||||
size_t flags = usb_osal_enter_critical_section();
|
||||
|
||||
urb->errorcode = -EBUSY;
|
||||
urb->actual_length = 0U;
|
||||
|
||||
ppipe->urb = urb;
|
||||
ppipe->timeout = urb->timeout;
|
||||
if (ppipe->timeout > 0) {
|
||||
ppipe->waiter = true;
|
||||
} else {
|
||||
ppipe->waiter = false;
|
||||
}
|
||||
|
||||
usb_osal_leave_critical_section(flags);
|
||||
switch (ppipe->ep_type) {
|
||||
case USB_ENDPOINT_TYPE_CONTROL:
|
||||
USB_ASSERT(setup);
|
||||
if (setup->bRequest == USB_REQUEST_SET_ADDRESS) {
|
||||
/* Set address command sent during xhci_alloc_pipe. */
|
||||
goto skip_req;
|
||||
}
|
||||
|
||||
USB_LOG_DBG("%s request-%d.\n", __func__, setup->bRequest);
|
||||
xhci_endpoint_message(ppipe, setup, urb->transfer_buffer, urb->transfer_buffer_length);
|
||||
break;
|
||||
case USB_ENDPOINT_TYPE_INTERRUPT:
|
||||
case USB_ENDPOINT_TYPE_BULK:
|
||||
xhci_endpoint_stream(ppipe, urb->transfer_buffer, urb->transfer_buffer_length);
|
||||
break;
|
||||
default:
|
||||
USB_ASSERT(0U);
|
||||
break;
|
||||
}
|
||||
|
||||
/* wait all ring handled by xHc */
|
||||
// int cc = xhci_event_wait(xhci, ppipe, &ppipe->reqs);
|
||||
int cc = xhci_event_wait(xhci, ppipe, ppipe->ep_reqs);
|
||||
if ((cc != XHCI_CMPLT_SUCCESS) &&
|
||||
!((cc == XHCI_CMPLT_TIMEOUT) && (ppipe->ep_type == USB_ENDPOINT_TYPE_INTERRUPT)))
|
||||
{
|
||||
/* ignore transfer timeout for interrupt type */
|
||||
USB_LOG_ERR("%s: xfer failed (cc %d).\n", __func__, cc);
|
||||
ret = -1;
|
||||
urb->errorcode = cc;
|
||||
goto errout_timeout;
|
||||
}
|
||||
|
||||
skip_req:
|
||||
errout_timeout:
|
||||
/* Timeout will run here */
|
||||
usbh_kill_urb(urb);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ Modification: replant and redefine some xhci data structure, so that the cherryU
|
|||
|
||||
2. Date: 2024-08-05
|
||||
Author: AIIT XUOS Lab
|
||||
Modification: Modify Command TRB code to apply to XiZi AIOT.
|
||||
Modification: Modify Command TRB and Transfer TRB code to apply to XiZi AIOT.
|
||||
*************************************************/
|
||||
|
||||
#include "usbh_core.h"
|
||||
|
@ -1884,7 +1884,8 @@ static void xhci_address_device_input ( struct xhci_host *xhci,
|
|||
bit[63:4] tr dequeue pointer
|
||||
bit[0] dequeue cycle state
|
||||
*/
|
||||
ep_ctx->dequeue = CPU_TO_LE64 ( (uint64_t)( (uintptr_t)&endpoint->reqs.ring[0] ) | XHCI_EP_DCS );
|
||||
// ep_ctx->dequeue = CPU_TO_LE64 ( (uint64_t)( (uintptr_t)&endpoint->reqs.ring[0] ) | XHCI_EP_DCS );
|
||||
ep_ctx->dequeue = CPU_TO_LE64 ( (uint64_t)( (uintptr_t)endpoint->ep_reqs_phy ) | XHCI_EP_DCS );
|
||||
ep_ctx->trb_len = CPU_TO_LE16 ( XHCI_EP0_TRB_LEN ); /* bit[15:0] average trb length */
|
||||
}
|
||||
|
||||
|
@ -2229,8 +2230,9 @@ static void xhci_configure_endpoint_input ( struct xhci_host *xhci,
|
|||
ep_ctx->type = endpoint->ctx_type;
|
||||
ep_ctx->burst = endpoint->burst;
|
||||
ep_ctx->mtu = CPU_TO_LE16 ( endpoint->mtu ); /* bit[31:16] max packet size */
|
||||
ep_ctx->dequeue = CPU_TO_LE64 ( (uint64_t)( (uintptr_t)&(endpoint->reqs.ring[0]) ) | XHCI_EP_DCS );
|
||||
|
||||
// ep_ctx->dequeue = CPU_TO_LE64 ( (uint64_t)( (uintptr_t)&(endpoint->reqs.ring[0]) ) | XHCI_EP_DCS );
|
||||
ep_ctx->dequeue = CPU_TO_LE64 ( (uint64_t)( (uintptr_t)endpoint->ep_reqs_phy ) | XHCI_EP_DCS );
|
||||
|
||||
/* TODO: endpoint attached on hub may need different setting here */
|
||||
if (endpoint->ep_type == USB_ENDPOINT_TYPE_BULK) {
|
||||
ep_ctx->trb_len = CPU_TO_LE16 ( 256U ); /* bit[15:0] average trb length */
|
||||
|
@ -2359,15 +2361,16 @@ int xhci_ctrl_endpoint_open ( struct xhci_host *xhci, struct xhci_slot *slot, st
|
|||
ep->ctx_type = XHCI_EP_TYPE_CONTROL;
|
||||
ep->context = ( ( ( void * ) slot->context ) +
|
||||
xhci_device_context_offset ( xhci, ctx ) );
|
||||
ep->reqs.cs = 1; /* cycle state = 1 */
|
||||
// ep->reqs.cs = 1; /* cycle state = 1 */
|
||||
ep->ep_reqs->cs = 1; /* cycle state = 1 */
|
||||
|
||||
USB_LOG_DBG("XHCI %s slot %d endpoint 0x%x ep type %d xhci ep type 0x%x\n",
|
||||
xhci->name, slot->id, ep->address, ep->ep_type,
|
||||
(ep->ctx_type >> 3) );
|
||||
|
||||
USB_LOG_DBG("XHCI %s slot %d ctx %d ring [%08lx,%08lx)\n",
|
||||
xhci->name, slot->id, ctx, ( ep->reqs.ring ),
|
||||
( ( ep->reqs.ring ) + sizeof(ep->reqs.ring) ) );
|
||||
xhci->name, slot->id, ctx, ( ep->ep_reqs->ring ),
|
||||
( ( ep->ep_reqs->ring ) + sizeof(ep->ep_reqs->ring) ) );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -2427,7 +2430,8 @@ int xhci_work_endpoint_open ( struct xhci_host *xhci, struct xhci_slot *slot, st
|
|||
ep->ctx_type = ctx_type;
|
||||
ep->context = ( ( ( void * ) slot->context ) +
|
||||
xhci_device_context_offset ( xhci, ctx ) );
|
||||
ep->reqs.cs = 1; /* cycle state = 1 */
|
||||
// ep->reqs.cs = 1; /* cycle state = 1 */
|
||||
ep->ep_reqs->cs = 1; /* cycle state = 1 */
|
||||
|
||||
USB_LOG_DBG("XHCI %s slot %d endpoint 0x%x ep type %d xhci ep type 0x%x\n",
|
||||
xhci->name, slot->id, ep->address, ep->ep_type,
|
||||
|
@ -2439,8 +2443,8 @@ int xhci_work_endpoint_open ( struct xhci_host *xhci, struct xhci_slot *slot, st
|
|||
}
|
||||
|
||||
USB_LOG_DBG("XHCI %s slot %d ctx %d ring [%08lx,%08lx)\n",
|
||||
xhci->name, slot->id, ctx, ( ep->reqs.ring ),
|
||||
( ( ep->reqs.ring ) + sizeof(ep->reqs.ring) ) );
|
||||
xhci->name, slot->id, ctx, ( ep->ep_reqs->ring ),
|
||||
( ( ep->ep_reqs->ring ) + sizeof(ep->ep_reqs->ring) ) );
|
||||
|
||||
return 0;
|
||||
err_configure_endpoint:
|
||||
|
@ -2504,7 +2508,8 @@ void xhci_endpoint_message ( struct xhci_endpoint *ep,
|
|||
setup->direction = ( input ? XHCI_SETUP_IN : XHCI_SETUP_OUT );
|
||||
}
|
||||
|
||||
xhci_trb_queue(&(ep->reqs), &trb);
|
||||
// xhci_trb_queue(&(ep->reqs), &trb);
|
||||
xhci_trb_queue(ep->ep_reqs, &trb);
|
||||
|
||||
/* Construct data stage TRB, if applicable */
|
||||
if (datalen > 0) {
|
||||
|
@ -2516,7 +2521,8 @@ void xhci_endpoint_message ( struct xhci_endpoint *ep,
|
|||
data->type = XHCI_TRB_DATA; /* bit[15:10] trb type */
|
||||
data->direction = ( input ? XHCI_DATA_IN : XHCI_DATA_OUT ); /* bit[16] Direction, 0 = OUT, 1 = IN */
|
||||
|
||||
xhci_trb_queue(&(ep->reqs), &trb);
|
||||
// xhci_trb_queue(&(ep->reqs), &trb);
|
||||
xhci_trb_queue(ep->ep_reqs, &trb);
|
||||
}
|
||||
|
||||
status = &(trb.status);
|
||||
|
@ -2526,7 +2532,8 @@ void xhci_endpoint_message ( struct xhci_endpoint *ep,
|
|||
status->direction =
|
||||
( ( datalen && input ) ? XHCI_STATUS_OUT : XHCI_STATUS_IN );
|
||||
|
||||
xhci_trb_queue(&(ep->reqs), &trb);
|
||||
// xhci_trb_queue(&(ep->reqs), &trb);
|
||||
xhci_trb_queue(ep->ep_reqs, &trb);
|
||||
|
||||
/* pass command trb to hardware */
|
||||
// DSB();
|
||||
|
@ -2575,7 +2582,8 @@ void xhci_endpoint_stream ( struct xhci_endpoint *ep,
|
|||
normal->type = XHCI_TRB_NORMAL;
|
||||
normal->flags = XHCI_TRB_IOC;
|
||||
|
||||
xhci_trb_queue(&(ep->reqs), trb);
|
||||
// xhci_trb_queue(&(ep->reqs), trb);
|
||||
xhci_trb_queue(ep->ep_reqs, trb);
|
||||
|
||||
/* pass command trb to hardware */
|
||||
// DSB();
|
||||
|
|
|
@ -758,6 +758,10 @@ struct xhci_er_seg {
|
|||
/** An xHCI endpoint */
|
||||
struct xhci_endpoint {
|
||||
struct xhci_ring reqs; /* DO NOT MOVE reqs from structure beg */
|
||||
/** xHCI ring */
|
||||
struct xhci_ring *ep_reqs;
|
||||
uintptr_t ep_reqs_vir;
|
||||
uintptr_t ep_reqs_phy;
|
||||
/** xHCI device */
|
||||
struct xhci_host *xhci;
|
||||
/** xHCI slot */
|
||||
|
|
Loading…
Reference in New Issue