diff options
| author | Yuxin Zhou <[email protected]> | 2022-07-26 02:07:18 +0000 |
|---|---|---|
| committer | Yuxin Zhou <[email protected]> | 2022-07-26 02:07:18 +0000 |
| commit | cd55ec74569aa3fbfbd8f02d025a47c5a51a285a (patch) | |
| tree | 916e32c4722afe2b37a776cba65797f6fe1a2d75 /common/usbx_host_controllers/src | |
| parent | 082fd9db09a3669eca3358f10b8837a5c1635c0b (diff) | |
Release 6.1.12v6.1.12_rel
Diffstat (limited to 'common/usbx_host_controllers/src')
8 files changed, 138 insertions, 58 deletions
diff --git a/common/usbx_host_controllers/src/ux_hcd_ehci_hsisochronous_tds_process.c b/common/usbx_host_controllers/src/ux_hcd_ehci_hsisochronous_tds_process.c index f7827a7..2c5fc4d 100755 --- a/common/usbx_host_controllers/src/ux_hcd_ehci_hsisochronous_tds_process.c +++ b/common/usbx_host_controllers/src/ux_hcd_ehci_hsisochronous_tds_process.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_hcd_ehci_hsisochronous_tds_process PORTABLE C */ -/* 6.1.10 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -78,6 +78,9 @@ /* 01-31-2022 Chaoqiong Xiao Modified comment(s), */ /* refined macros names, */ /* resulting in version 6.1.10 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* improved uframe handling, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UX_EHCI_HSISO_TD* _ux_hcd_ehci_hsisochronous_tds_process( @@ -220,9 +223,19 @@ UINT i; fr_td -> ux_ehci_hsiso_td_frload = (UCHAR)(fr_td -> ux_ehci_hsiso_td_frload & ~(1u << frindex)); ed -> ux_ehci_hsiso_ed_frload = (USHORT)(ed -> ux_ehci_hsiso_ed_frload & ~(1u << frindex)); + /* HC processed. */ + ed -> ux_ehci_hsiso_ed_fr_hc ++; + + /* Unlink it from iTD. */ + fr_td -> ux_ehci_hsiso_td_fr_transfer[frindex & 1u] = UX_NULL; + /* Handle the request. */ transfer = ed -> ux_ehci_hsiso_ed_transfer_head; + /* If there is no transfer linked to, just ignore it. */ + if (transfer == UX_NULL) + break; + /* Convert error code to completion code. */ if (control & UX_EHCI_HSISO_STATUS_DATA_BUFFER_ERR) transfer -> ux_transfer_request_completion_code = UX_TRANSFER_BUFFER_OVERFLOW; @@ -241,12 +254,6 @@ UINT i; /* Save to actual length. */ transfer -> ux_transfer_request_actual_length = trans_bytes; - /* HC processed. */ - ed -> ux_ehci_hsiso_ed_fr_hc ++; - - /* Unlink it from iTD. */ - fr_td -> ux_ehci_hsiso_td_fr_transfer[frindex & 1u] = UX_NULL; - /* Unlink it from request list head. */ ed -> ux_ehci_hsiso_ed_transfer_head = transfer -> ux_transfer_request_next_transfer_request; @@ -446,6 +453,14 @@ UINT i; } /* if (ed -> ux_ehci_hsiso_ed_transfer_first_new) */ + /* If there is no transfer, need start again any way. */ + if (ed -> ux_ehci_hsiso_ed_frload == 0) + { + ed -> ux_ehci_hsiso_ed_frstart = 0xFF; + ed -> ux_ehci_hsiso_ed_fr_sw = 0; + ed -> ux_ehci_hsiso_ed_fr_hc = 0; + } + /* Return next iTD in scan list. */ return(next_scan_td); } diff --git a/common/usbx_host_controllers/src/ux_hcd_ehci_request_isochronous_transfer.c b/common/usbx_host_controllers/src/ux_hcd_ehci_request_isochronous_transfer.c index d3df179..bbdf0f9 100644 --- a/common/usbx_host_controllers/src/ux_hcd_ehci_request_isochronous_transfer.c +++ b/common/usbx_host_controllers/src/ux_hcd_ehci_request_isochronous_transfer.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_hcd_ehci_request_isochronous_transfer PORTABLE C */ -/* 6.1.11 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -86,6 +86,9 @@ /* 04-25-2022 Chaoqiong Xiao Modified comment(s), */ /* fixed standalone compile, */ /* resulting in version 6.1.11 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* improved iso start up, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_hcd_ehci_request_isochronous_transfer(UX_HCD_EHCI *hcd_ehci, UX_TRANSFER *transfer_request) @@ -141,6 +144,8 @@ UCHAR start = UX_FALSE; if (ied -> ux_ehci_hsiso_ed_frstart == 0xFF) { ied -> ux_ehci_hsiso_ed_frstart = 0xFE; + ied -> ux_ehci_hsiso_ed_fr_sw = 0; + ied -> ux_ehci_hsiso_ed_fr_hc = 0; start = UX_TRUE; } } diff --git a/common/usbx_host_controllers/src/ux_hcd_ehci_transfer_abort.c b/common/usbx_host_controllers/src/ux_hcd_ehci_transfer_abort.c index f2df19a..24d821d 100755 --- a/common/usbx_host_controllers/src/ux_hcd_ehci_transfer_abort.c +++ b/common/usbx_host_controllers/src/ux_hcd_ehci_transfer_abort.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_hcd_ehci_transfer_abort PORTABLE C */ -/* 6.1.11 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -82,6 +82,9 @@ /* 04-25-2022 Chaoqiong Xiao Modified comment(s), */ /* fixed standalone compile, */ /* resulting in version 6.1.11 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* improved iso abort support, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_hcd_ehci_transfer_abort(UX_HCD_EHCI *hcd_ehci,UX_TRANSFER *transfer_request) @@ -90,10 +93,15 @@ UINT _ux_hcd_ehci_transfer_abort(UX_HCD_EHCI *hcd_ehci,UX_TRANSFER *transfer_re UX_ENDPOINT *endpoint; UX_EHCI_HSISO_ED *ied; UX_EHCI_PERIODIC_LINK_POINTER lp; +UX_EHCI_HSISO_TD *fr_td; UX_TRANSFER **list_head; UX_TRANSFER *transfer; ULONG max_load_count; -ULONG remain_count; +ULONG frindex; +ULONG fr_start; +ULONG fr_req; +ULONG first_new_aborted = 1; + UX_PARAMETER_NOT_USED(hcd_ehci); @@ -145,19 +153,49 @@ ULONG remain_count; (*list_head) == transfer_request) { *list_head = UX_NULL; - remain_count = 0; + + /* Clear controls any way. */ + for (frindex = 0; frindex < 4; frindex ++) + { + + /* Get actual iTD used and clear controls. */ + fr_td = ied -> ux_ehci_hsiso_ed_fr_td[frindex]; + fr_td -> ux_ehci_hsiso_td_control[(frindex << 1)] &= ~UX_EHCI_HSISO_STATUS_ACTIVE; + fr_td -> ux_ehci_hsiso_td_control[(frindex << 1) + 1] &= ~UX_EHCI_HSISO_STATUS_ACTIVE; + fr_td -> ux_ehci_hsiso_td_frload = 0; + fr_td -> ux_ehci_hsiso_td_fr_transfer[0] = UX_NULL; + fr_td -> ux_ehci_hsiso_td_fr_transfer[1] = UX_NULL; + } + + /* Transfer needs restart. */ + ied -> ux_ehci_hsiso_ed_frstart = 0xFF; + ied -> ux_ehci_hsiso_ed_fr_hc = 0; + ied -> ux_ehci_hsiso_ed_fr_sw = 0; + ied -> ux_ehci_hsiso_ed_transfer_tail = UX_NULL; + ied -> ux_ehci_hsiso_ed_transfer_first_new = UX_NULL; + ied -> ux_ehci_hsiso_ed_frload = 0; } else { - /* At least one request remains. */ - remain_count = 1; + /* At least one request remains (no restart). */ + + /* Get the next micro-frame index. */ + fr_start = (ULONG)ied -> ux_ehci_hsiso_ed_fr_hc << ied -> ux_ehci_hsiso_ed_frinterval_shift; + fr_start += ied -> ux_ehci_hsiso_ed_frstart; + fr_start &= 0x7u; + + /* First request micro-frame index offset is 0. */ + fr_req = 0; - /* Remove it and transfers after it. */ + /* Remove the transfer and transfers after it. */ transfer = (*list_head) -> ux_transfer_request_next_transfer_request; while(transfer) { + /* Check next micro-frame index. */ + fr_req += ied -> ux_ehci_hsiso_ed_frinterval; + /* If next is transfer we expect, remove from it. */ if (transfer -> ux_transfer_request_next_transfer_request == transfer_request) { @@ -167,18 +205,32 @@ ULONG remain_count; break; } + /* If that's first new, it means first new is in remained list. */ + if (transfer == ied -> ux_ehci_hsiso_ed_transfer_first_new) + first_new_aborted = 0; + /* Next transfer. */ transfer = transfer -> ux_transfer_request_next_transfer_request; + } + + /* If first new is removed, set to null. */ + if (first_new_aborted) + ied -> ux_ehci_hsiso_ed_transfer_first_new = UX_NULL; - /* Remain plus one. */ - remain_count ++; + /* If some micro-frames are removed, modify control. */ + for (; fr_req < max_load_count; fr_req += ied -> ux_ehci_hsiso_ed_frinterval) + { + frindex = fr_start + fr_req; + frindex &= 0x7u; + + /* Get actual iTD used and clear control. */ + fr_td = ied -> ux_ehci_hsiso_ed_fr_td[frindex >> 1]; + fr_td -> ux_ehci_hsiso_td_frload &= (UCHAR)~(1u << frindex); + fr_td -> ux_ehci_hsiso_td_control[frindex] &= ~UX_EHCI_HSISO_STATUS_ACTIVE; + fr_td -> ux_ehci_hsiso_td_fr_transfer[frindex & 1u] = UX_NULL; } } - /* Wait a while so background transfer completed. */ - if (remain_count < max_load_count) - _ux_utility_delay_ms(1); - /* Release the periodic table. */ _ux_host_mutex_off(&hcd_ehci -> ux_hcd_ehci_periodic_mutex); } diff --git a/common/usbx_host_controllers/src/ux_hcd_ohci_asynchronous_endpoint_create.c b/common/usbx_host_controllers/src/ux_hcd_ohci_asynchronous_endpoint_create.c index 497707c..5918950 100644 --- a/common/usbx_host_controllers/src/ux_hcd_ohci_asynchronous_endpoint_create.c +++ b/common/usbx_host_controllers/src/ux_hcd_ohci_asynchronous_endpoint_create.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_hcd_ohci_asynchronous_endpoint_create PORTABLE C */ -/* 6.1.11 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -75,6 +75,9 @@ /* 04-25-2022 Chaoqiong Xiao Modified comment(s), */ /* fixed an addressing issue, */ /* resulting in version 6.1.11 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed addressing issues, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_hcd_ohci_asynchronous_endpoint_create(UX_HCD_OHCI *hcd_ohci, UX_ENDPOINT *endpoint) @@ -139,7 +142,7 @@ ULONG ohci_register; head_ed = (UX_OHCI_ED *) _ux_hcd_ohci_register_read(hcd_ohci, OHCI_HC_CONTROL_HEAD_ED); ed -> ux_ohci_ed_next_ed = head_ed; - _ux_hcd_ohci_register_write(hcd_ohci, OHCI_HC_CONTROL_HEAD_ED, (ULONG) ed); + _ux_hcd_ohci_register_write(hcd_ohci, OHCI_HC_CONTROL_HEAD_ED, (ULONG) _ux_utility_physical_address(ed)); ohci_register = _ux_hcd_ohci_register_read(hcd_ohci, OHCI_HC_CONTROL); ohci_register |= OHCI_HC_CR_CLE; _ux_hcd_ohci_register_write(hcd_ohci, OHCI_HC_CONTROL, ohci_register); @@ -150,7 +153,7 @@ ULONG ohci_register; head_ed = (UX_OHCI_ED *) _ux_hcd_ohci_register_read(hcd_ohci, OHCI_HC_BULK_HEAD_ED); ed -> ux_ohci_ed_next_ed = head_ed; - _ux_hcd_ohci_register_write(hcd_ohci, OHCI_HC_BULK_HEAD_ED, (ULONG) ed); + _ux_hcd_ohci_register_write(hcd_ohci, OHCI_HC_BULK_HEAD_ED, (ULONG) _ux_utility_physical_address(ed)); ohci_register = _ux_hcd_ohci_register_read(hcd_ohci, OHCI_HC_CONTROL); ohci_register |= OHCI_HC_CR_BLE; _ux_hcd_ohci_register_write(hcd_ohci, OHCI_HC_CONTROL, ohci_register); @@ -165,7 +168,7 @@ ULONG ohci_register; inserted ED. */ if (head_ed != UX_NULL) { - head_ed = _ux_utility_physical_address(head_ed); + head_ed = _ux_utility_virtual_address(head_ed); head_ed -> ux_ohci_ed_previous_ed = ed; } diff --git a/common/usbx_host_controllers/src/ux_hcd_ohci_done_queue_process.c b/common/usbx_host_controllers/src/ux_hcd_ohci_done_queue_process.c index 48bd7d7..4391be1 100644 --- a/common/usbx_host_controllers/src/ux_hcd_ohci_done_queue_process.c +++ b/common/usbx_host_controllers/src/ux_hcd_ohci_done_queue_process.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_hcd_ohci_done_queue_process PORTABLE C */ -/* 6.1.10 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -83,6 +83,9 @@ /* 01-31-2022 Chaoqiong Xiao Modified comment(s), */ /* refined macros names, */ /* resulting in version 6.1.10 */ +/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ +/* fixed an addressing issue, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ VOID _ux_hcd_ohci_done_queue_process(UX_HCD_OHCI *hcd_ohci) @@ -117,7 +120,7 @@ ULONG current_frame; td = next_td; next_td = _ux_utility_virtual_address(td -> ux_ohci_td_next_td); - td -> ux_ohci_td_next_td = previous_td; + td -> ux_ohci_td_next_td = _ux_utility_physical_address(previous_td); previous_td = td; } @@ -333,7 +336,7 @@ ULONG current_frame; td -> ux_ohci_td_status = UX_UNUSED; /* And continue the TD loop. */ - td = td -> ux_ohci_td_next_td; + td = _ux_utility_virtual_address(td -> ux_ohci_td_next_td); } /* The OHCI controller is now ready to receive the next done queue. We need to diff --git a/common/usbx_host_controllers/src/ux_hcd_ohci_initialize.c b/common/usbx_host_controllers/src/ux_hcd_ohci_initialize.c index b8400c2..cfd5078 100644 --- a/common/usbx_host_controllers/src/ux_hcd_ohci_initialize.c +++ b/common/usbx_host_controllers/src/ux_hcd_ohci_initialize.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_hcd_ohci_initialize PORTABLE C */ -/* 6.1.11 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -85,6 +85,9 @@ /* 04-25-2022 Chaoqiong Xiao Modified comment(s), */ /* fixed standalone compile, */ /* resulting in version 6.1.11 */ +/* 07-29-2022 Yajun Xia Modified comment(s), */ +/* fixed OHCI PRSC issue, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_hcd_ohci_initialize(UX_HCD *hcd) @@ -232,6 +235,11 @@ UINT status; hcd -> ux_hcd_nb_root_hubs = UX_MAX_ROOTHUB_PORT; hcd_ohci -> ux_hcd_ohci_nb_root_hubs = hcd -> ux_hcd_nb_root_hubs; + /* Create HCD event flags */ + status = _ux_host_event_flags_create(&hcd_ohci -> ux_hcd_ohci_event_flags_group, "ux_hcd_ohci_event_flags_group"); + if (status != UX_SUCCESS) + return(status); + /* All ports must now be powered to pick up device insertion. */ _ux_hcd_ohci_power_root_hubs(hcd_ohci); diff --git a/common/usbx_host_controllers/src/ux_hcd_ohci_interrupt_handler.c b/common/usbx_host_controllers/src/ux_hcd_ohci_interrupt_handler.c index 7d3486f..5894e57 100644 --- a/common/usbx_host_controllers/src/ux_hcd_ohci_interrupt_handler.c +++ b/common/usbx_host_controllers/src/ux_hcd_ohci_interrupt_handler.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_hcd_ohci_interrupt_handler PORTABLE C */ -/* 6.1.10 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -80,6 +80,9 @@ /* 01-31-2022 Chaoqiong Xiao Modified comment(s), */ /* refined macros names, */ /* resulting in version 6.1.10 */ +/* 07-29-2022 Yajun Xia Modified comment(s), */ +/* fixed OHCI PRSC issue, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ VOID _ux_hcd_ohci_interrupt_handler(VOID) @@ -164,9 +167,14 @@ ULONG port_index; root_hub_thread_wakeup ++; } - /* Clear the root hub interrupt signal. We do not turn off Port Reset status change here. - This will be done when the root hub requests a Port Reset. */ - _ux_hcd_ohci_register_write(hcd_ohci, OHCI_HC_RH_PORT_STATUS + port_index, (OHCI_HC_PS_CSC | OHCI_HC_PS_PESC | OHCI_HC_PS_PSSC | OHCI_HC_PS_OCIC )); + if (ohci_register_port_status & OHCI_HC_PS_PRSC) + { + _ux_host_event_flags_set(&hcd_ohci -> ux_hcd_ohci_event_flags_group, UX_OHCI_PRSC_EVENT, UX_OR); + } + + /* Clear the root hub interrupt signal. */ + _ux_hcd_ohci_register_write(hcd_ohci, OHCI_HC_RH_PORT_STATUS + port_index, + (OHCI_HC_PS_CSC | OHCI_HC_PS_PESC | OHCI_HC_PS_PSSC | OHCI_HC_PS_OCIC | OHCI_HC_PS_PRSC)); } /* We only wake up the root hub thread if there has been device insertion/extraction. */ diff --git a/common/usbx_host_controllers/src/ux_hcd_ohci_port_reset.c b/common/usbx_host_controllers/src/ux_hcd_ohci_port_reset.c index 654347a..42ecc3b 100644 --- a/common/usbx_host_controllers/src/ux_hcd_ohci_port_reset.c +++ b/common/usbx_host_controllers/src/ux_hcd_ohci_port_reset.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_hcd_ohci_port_reset PORTABLE C */ -/* 6.1 */ +/* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -70,14 +70,17 @@ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ +/* 07-29-2022 Yajun Xia Modified comment(s), */ +/* fixed OHCI PRSC issue, */ +/* resulting in version 6.1.12 */ /* */ /**************************************************************************/ UINT _ux_hcd_ohci_port_reset(UX_HCD_OHCI *hcd_ohci, ULONG port_index) { ULONG ohci_register_port_status; -UINT index_loop; - +UINT status; +ULONG actual_flags = 0; /* Check to see if this port is valid on this controller. */ if (hcd_ohci -> ux_hcd_ohci_nb_root_hubs < port_index) @@ -112,29 +115,12 @@ UINT index_loop; /* Now we can safely issue a RESET command to this port. */ _ux_hcd_ohci_register_write(hcd_ohci, OHCI_HC_RH_PORT_STATUS + port_index, OHCI_HC_PS_PRS); - /* Normally, a port reset lasts for around 10ms. When the reset is completed - the controller will set the PRSC bit. We need to invert this bit by rewriting - a 1 to the PRSC field. */ - for (index_loop = 0; index_loop < UX_OHCI_PORT_RESET_RETRY; index_loop++) - { - - /* Perform the necessary delay to let the port reset properly. */ - _ux_utility_delay_ms(UX_OHCI_PORT_RESET_DELAY); - - /* Read the root HUB status change register. */ - ohci_register_port_status = _ux_hcd_ohci_register_read(hcd_ohci, OHCI_HC_RH_PORT_STATUS + port_index); - - /* Reset completed? */ - if (ohci_register_port_status & OHCI_HC_PS_PRSC) - { - - /* The reset phase is complete, rewrite that bit to clear it and - return to the root HUB driver. */ - _ux_hcd_ohci_register_write(hcd_ohci, OHCI_HC_RH_PORT_STATUS + port_index, OHCI_HC_PS_PRSC); - - /* Return successful completion. */ - return(UX_SUCCESS); - } + /* Wait for the port reset complete event */ + status = _ux_host_event_flags_get(&hcd_ohci -> ux_hcd_ohci_event_flags_group, + (UX_OHCI_PRSC_EVENT), UX_OR_CLEAR, &actual_flags, + UX_MS_TO_TICK(UX_OHCI_PRSC_EVENT_TIMEOUT)); + if ((status != UX_NO_EVENTS) && (actual_flags & UX_OHCI_PRSC_EVENT)) { + return(UX_SUCCESS); } /* If trace is enabled, insert this event into the trace buffer. */ |
