1 /*************************************************************************** 2 * Copyright (c) 2024 Microsoft Corporation 3 * 4 * This program and the accompanying materials are made available under the 5 * terms of the MIT License which is available at 6 * https://opensource.org/licenses/MIT. 7 * 8 * SPDX-License-Identifier: MIT 9 **************************************************************************/ 10 11 12 /**************************************************************************/ 13 /**************************************************************************/ 14 /** */ 15 /** USBX Component */ 16 /** */ 17 /** OHCI Controller Driver */ 18 /** */ 19 /**************************************************************************/ 20 /**************************************************************************/ 21 22 23 /* Include necessary system files. */ 24 25 #define UX_SOURCE_CODE 26 27 #include "ux_api.h" 28 #include "ux_hcd_ohci.h" 29 #include "ux_host_stack.h" 30 31 32 /**************************************************************************/ 33 /* */ 34 /* FUNCTION RELEASE */ 35 /* */ 36 /* _ux_hcd_ohci_next_td_clean PORTABLE C */ 37 /* 6.1 */ 38 /* AUTHOR */ 39 /* */ 40 /* Chaoqiong Xiao, Microsoft Corporation */ 41 /* */ 42 /* DESCRIPTION */ 43 /* */ 44 /* This function cleans all the tds attached to a ED. The end of the */ 45 /* TD chain is pointed by the tail TD. */ 46 /* */ 47 /* INPUT */ 48 /* */ 49 /* td Pointer to OHCI TD */ 50 /* */ 51 /* OUTPUT */ 52 /* */ 53 /* None */ 54 /* */ 55 /* CALLS */ 56 /* */ 57 /* _ux_utility_physical_address Get physical address */ 58 /* _ux_utility_virtual_address Get virtual address */ 59 /* */ 60 /* CALLED BY */ 61 /* */ 62 /* OHCI Controller Driver */ 63 /* */ 64 /* RELEASE HISTORY */ 65 /* */ 66 /* DATE NAME DESCRIPTION */ 67 /* */ 68 /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ 69 /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ 70 /* fixed physical and virtual */ 71 /* address conversion, */ 72 /* resulting in version 6.1 */ 73 /* */ 74 /**************************************************************************/ _ux_hcd_ohci_next_td_clean(UX_OHCI_TD * td)75VOID _ux_hcd_ohci_next_td_clean(UX_OHCI_TD *td) 76 { 77 78 UX_OHCI_ED *ed; 79 UX_OHCI_TD *head_td; 80 UX_OHCI_TD *tail_td; 81 ULONG value_td; 82 ULONG value_carry; 83 84 85 /* Obtain the pointer to the ED from the TD. */ 86 ed = td -> ux_ohci_td_ed; 87 88 /* Ensure that the potential Carry bit is maintained in the head ED. */ 89 value_carry = (ULONG)(ed -> ux_ohci_ed_head_td) & UX_OHCI_ED_TOGGLE_CARRY; 90 91 /* Ensure that the potential Halt bit is removed in the head ED. */ 92 value_td = (ULONG) _ux_utility_virtual_address(ed -> ux_ohci_ed_head_td) & UX_OHCI_ED_MASK_TD; 93 head_td = (UX_OHCI_TD *)value_td; 94 95 /* Remove all the tds from this ED and leave the head and tail pointing 96 to the dummy TD. */ 97 tail_td = _ux_utility_virtual_address(ed -> ux_ohci_ed_tail_td); 98 99 /* Free all tds attached to the ED. */ 100 while (head_td != tail_td) 101 { 102 103 /* Mark the current head_td as free. */ 104 head_td -> ux_ohci_td_status = UX_UNUSED; 105 106 /* Update the head TD with the next TD. */ 107 ed -> ux_ohci_ed_head_td = head_td -> ux_ohci_td_next_td; 108 109 /* Now the new head_td is the next TD in the chain. */ 110 head_td = _ux_utility_virtual_address(ed -> ux_ohci_ed_head_td); 111 } 112 113 /* Restore the value carry for next transfers. */ 114 value_td = (ULONG) ed -> ux_ohci_ed_head_td; 115 value_td |= value_carry; 116 ed -> ux_ohci_ed_head_td = (UX_OHCI_TD *) value_td; 117 118 /* Return to caller. */ 119 return; 120 } 121 122