forked from xuos/xiuos
Implanting event ring initialization
This commit is contained in:
parent
181362892a
commit
bed67b388f
|
@ -941,35 +941,83 @@ if ( ( rc = xhci_writeq ( xhci, ( cmds_phy | XHCI_CRCR_RCS ),
|
||||||
static int xhci_event_alloc ( struct xhci_host *xhci ) {
|
static int xhci_event_alloc ( struct xhci_host *xhci ) {
|
||||||
unsigned int count;
|
unsigned int count;
|
||||||
size_t len;
|
size_t len;
|
||||||
|
uintptr_t evts_addr, evts_phy, eseg_addr, eseg_phy;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
/* Allocate event ring */
|
/* Allocate event ring */
|
||||||
|
len = sizeof(*xhci->evts);
|
||||||
|
rc = naive_mmap(&evts_addr, &evts_phy, len, false);
|
||||||
|
|
||||||
|
if(rc != 0){
|
||||||
|
USB_LOG_ERR("XHCI %s could not allocate Event RING\n", xhci->name );
|
||||||
|
rc = -ENOMEM;
|
||||||
|
goto err_alloc_trb;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if 0
|
||||||
xhci->evts = usb_align(XHCI_RING_SIZE, sizeof(*xhci->evts)); /* event ring */
|
xhci->evts = usb_align(XHCI_RING_SIZE, sizeof(*xhci->evts)); /* event ring */
|
||||||
if ( ! xhci->evts ) {
|
if ( ! xhci->evts ) {
|
||||||
rc = -ENOMEM;
|
rc = -ENOMEM;
|
||||||
goto err_alloc_trb;
|
goto err_alloc_trb;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
xhci->evts_addr = evts_addr;
|
||||||
|
xhci->evts_phy = evts_phy;
|
||||||
|
|
||||||
|
xhci->evts = (struct xhci_ring *)evts_addr;
|
||||||
memset(xhci->evts, 0U, sizeof(*xhci->evts));
|
memset(xhci->evts, 0U, sizeof(*xhci->evts));
|
||||||
|
|
||||||
/* Allocate event ring segment table */
|
/* Allocate event ring segment table */
|
||||||
|
|
||||||
|
len = sizeof(*xhci->eseg);
|
||||||
|
rc = naive_mmap(&eseg_addr, &eseg_phy, len, false);
|
||||||
|
if(rc != 0){
|
||||||
|
USB_LOG_ERR("XHCI %s could not allocate Event Segment\n", xhci->name );
|
||||||
|
rc = -ENOMEM;
|
||||||
|
goto err_alloc_segment;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
xhci->eseg = usb_align(XHCI_ALIGMENT, sizeof(*xhci->eseg)); /* event segment */
|
xhci->eseg = usb_align(XHCI_ALIGMENT, sizeof(*xhci->eseg)); /* event segment */
|
||||||
if ( ! xhci->eseg ) {
|
if ( ! xhci->eseg ) {
|
||||||
rc = -ENOMEM;
|
rc = -ENOMEM;
|
||||||
goto err_alloc_segment;
|
goto err_alloc_segment;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
xhci->eseg_addr = eseg_addr;
|
||||||
|
xhci->eseg_phy = eseg_phy;
|
||||||
|
|
||||||
|
xhci->eseg = (struct xhci_er_seg *)eseg_addr;
|
||||||
|
|
||||||
memset(xhci->eseg, 0U, sizeof(*xhci->eseg));
|
memset(xhci->eseg, 0U, sizeof(*xhci->eseg));
|
||||||
xhci->eseg->base = CPU_TO_LE64 ( ( (uintptr_t)xhci->evts ) );
|
xhci->eseg->base = CPU_TO_LE64 ( ( (uintptr_t)xhci->evts ) );
|
||||||
xhci->eseg->count = XHCI_RING_ITEMS; /* items of event ring TRB */
|
xhci->eseg->count = XHCI_RING_ITEMS; /* items of event ring TRB */
|
||||||
|
|
||||||
/* Program event ring registers */
|
/* Program event ring registers */
|
||||||
writel ( 1, xhci->run + XHCI_RUN_ERSTSZ ( 0 ) ); /* bit[15:0] event ring segment table size */
|
// writel ( 1, xhci->run + XHCI_RUN_ERSTSZ ( 0 ) ); /* bit[15:0] event ring segment table size */
|
||||||
|
|
||||||
|
writel ( 1, xhci->run_addr + XHCI_RUN_ERSTSZ ( 0 ) ); /* bit[15:0] event ring segment table size */
|
||||||
|
|
||||||
|
#if 0
|
||||||
if ( ( rc = xhci_writeq ( xhci, (uintptr_t)( xhci->evts ),
|
if ( ( rc = xhci_writeq ( xhci, (uintptr_t)( xhci->evts ),
|
||||||
xhci->run + XHCI_RUN_ERDP ( 0 ) ) ) != 0 ) /* bit[63:4] event ring dequeue pointer */
|
xhci->run + XHCI_RUN_ERDP ( 0 ) ) ) != 0 ) /* bit[63:4] event ring dequeue pointer */
|
||||||
goto err_writeq_erdp;
|
goto err_writeq_erdp;
|
||||||
|
#endif
|
||||||
|
if ( ( rc = xhci_writeq ( xhci, (uintptr_t)( xhci->evts_phy ),
|
||||||
|
xhci->run_addr + XHCI_RUN_ERDP ( 0 ) ) ) != 0 ) /* bit[63:4] event ring dequeue pointer */
|
||||||
|
goto err_writeq_erdp;
|
||||||
|
|
||||||
|
#if 0
|
||||||
if ( ( rc = xhci_writeq ( xhci, (uintptr_t)( xhci->eseg ),
|
if ( ( rc = xhci_writeq ( xhci, (uintptr_t)( xhci->eseg ),
|
||||||
xhci->run + XHCI_RUN_ERSTBA ( 0 ) ) ) != 0 ) /* bit[63:6] event ring segment table base addr */
|
xhci->run + XHCI_RUN_ERSTBA ( 0 ) ) ) != 0 ) /* bit[63:6] event ring segment table base addr */
|
||||||
goto err_writeq_erstba;
|
goto err_writeq_erstba;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if ( ( rc = xhci_writeq ( xhci, (uintptr_t)( xhci->eseg_phy ),
|
||||||
|
xhci->run_addr + XHCI_RUN_ERSTBA ( 0 ) ) ) != 0 ) /* bit[63:6] event ring segment table base addr */
|
||||||
|
goto err_writeq_erstba;
|
||||||
|
|
||||||
xhci->evts->cs = 1; /* cycle state = 1 */
|
xhci->evts->cs = 1; /* cycle state = 1 */
|
||||||
USB_LOG_DBG("XHCI %s event ring [%08lx,%08lx) table [%08lx,%08lx)\n",
|
USB_LOG_DBG("XHCI %s event ring [%08lx,%08lx) table [%08lx,%08lx)\n",
|
||||||
|
@ -980,13 +1028,13 @@ static int xhci_event_alloc ( struct xhci_host *xhci ) {
|
||||||
sizeof ( xhci->eseg[0] ) ) );
|
sizeof ( xhci->eseg[0] ) ) );
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
xhci_writeq ( xhci, 0, xhci->run + XHCI_RUN_ERSTBA ( 0 ) );
|
xhci_writeq ( xhci, 0, xhci->run_addr + XHCI_RUN_ERSTBA ( 0 ) );
|
||||||
err_writeq_erstba:
|
err_writeq_erstba:
|
||||||
xhci_writeq ( xhci, 0, xhci->run + XHCI_RUN_ERDP ( 0 ) );
|
xhci_writeq ( xhci, 0, xhci->run_addr + XHCI_RUN_ERDP ( 0 ) );
|
||||||
err_writeq_erdp:
|
err_writeq_erdp:
|
||||||
usb_free ( xhci->eseg );
|
// usb_free ( xhci->eseg );
|
||||||
err_alloc_segment:
|
err_alloc_segment:
|
||||||
usb_free ( xhci->evts );
|
// usb_free ( xhci->evts );
|
||||||
err_alloc_trb:
|
err_alloc_trb:
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -900,7 +900,19 @@ struct xhci_host {
|
||||||
uintptr_t cmds_phy;
|
uintptr_t cmds_phy;
|
||||||
/** Event ring */
|
/** Event ring */
|
||||||
struct xhci_ring *evts;
|
struct xhci_ring *evts;
|
||||||
|
/*
|
||||||
|
* evts_addr holds the virtual address of the event ring, meanwhile cvts_phy keeps the value that should be writen to Event Ring
|
||||||
|
* Dequeue Pointer Register (XHCI_RUN_ERDP).
|
||||||
|
*/
|
||||||
|
uintptr_t evts_addr;
|
||||||
|
uintptr_t evts_phy;
|
||||||
struct xhci_er_seg *eseg;
|
struct xhci_er_seg *eseg;
|
||||||
|
/*
|
||||||
|
* eseg_addr holds the virtual address of the event segment, meanwhile cseg_phy keeps the value that should be writen to Event Ring
|
||||||
|
* Segment Table Size Register (XHCI_RUN_ERSTBA).
|
||||||
|
*/
|
||||||
|
uintptr_t eseg_addr;
|
||||||
|
uintptr_t eseg_phy;
|
||||||
|
|
||||||
struct xhci_endpoint *cur_cmd_pipe;
|
struct xhci_endpoint *cur_cmd_pipe;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue