1 /**************************************************************************/ 2 /* */ 3 /* Copyright (c) Microsoft Corporation. All rights reserved. */ 4 /* */ 5 /* This software is licensed under the Microsoft Software License */ 6 /* Terms for Microsoft Azure RTOS. Full text of the license can be */ 7 /* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ 8 /* and in the root directory of this software. */ 9 /* */ 10 /**************************************************************************/ 11 12 13 /**************************************************************************/ 14 /**************************************************************************/ 15 /** */ 16 /** USBX Component */ 17 /** */ 18 /** OHCI Controller Driver */ 19 /** */ 20 /**************************************************************************/ 21 /**************************************************************************/ 22 23 24 /* Include necessary system files. */ 25 26 #define UX_SOURCE_CODE 27 28 #include "ux_api.h" 29 #include "ux_hcd_ohci.h" 30 #include "ux_host_stack.h" 31 32 33 /**************************************************************************/ 34 /* */ 35 /* FUNCTION RELEASE */ 36 /* */ 37 /* _ux_hcd_ohci_isochronous_endpoint_create PORTABLE C */ 38 /* 6.1.6 */ 39 /* AUTHOR */ 40 /* */ 41 /* Chaoqiong Xiao, Microsoft Corporation */ 42 /* */ 43 /* DESCRIPTION */ 44 /* */ 45 /* This function creates an isochronous endpoint. */ 46 /* */ 47 /* INPUT */ 48 /* */ 49 /* hcd_ohci Pointer to OHCI */ 50 /* endpoint Pointer to endpoint */ 51 /* */ 52 /* OUTPUT */ 53 /* */ 54 /* Completion Status */ 55 /* */ 56 /* CALLS */ 57 /* */ 58 /* _ux_hcd_ohci_ed_obtain Obtain an OHCI ED */ 59 /* _ux_hcd_ohci_isochronous_td_obtain Obtain an OHCI TD */ 60 /* _ux_utility_physical_address Get physical address */ 61 /* _ux_utility_virtual_address Get virtual address */ 62 /* */ 63 /* CALLED BY */ 64 /* */ 65 /* OHCI Controller Driver */ 66 /* */ 67 /* RELEASE HISTORY */ 68 /* */ 69 /* DATE NAME DESCRIPTION */ 70 /* */ 71 /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ 72 /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ 73 /* resulting in version 6.1 */ 74 /* 04-02-2021 Chaoqiong Xiao Modified comment(s), */ 75 /* filled max transfer length, */ 76 /* resulting in version 6.1.6 */ 77 /* */ 78 /**************************************************************************/ _ux_hcd_ohci_isochronous_endpoint_create(UX_HCD_OHCI * hcd_ohci,UX_ENDPOINT * endpoint)79UINT _ux_hcd_ohci_isochronous_endpoint_create(UX_HCD_OHCI *hcd_ohci, UX_ENDPOINT *endpoint) 80 { 81 82 UX_HCD_OHCI_HCCA *ohci_hcca; 83 UX_DEVICE *device; 84 UX_OHCI_ED *ed; 85 UX_OHCI_ED *ed_list; 86 UX_OHCI_ISO_TD *td; 87 88 89 /* Get the pointer to the HCCA. */ 90 ohci_hcca = hcd_ohci -> ux_hcd_ohci_hcca; 91 92 /* Obtain a ED for this new endpoint. This ED will live as long as 93 the endpoint is active and will be the container for the tds. */ 94 ed = _ux_hcd_ohci_ed_obtain(hcd_ohci); 95 if(ed==UX_NULL) 96 return(UX_NO_ED_AVAILABLE); 97 98 /* Obtain a dummy isoch TD for terminating the ED transfer chain. */ 99 td = _ux_hcd_ohci_isochronous_td_obtain(hcd_ohci); 100 if (td == UX_NULL) 101 { 102 ed -> ux_ohci_ed_status = UX_UNUSED; 103 return(UX_NO_TD_AVAILABLE); 104 } 105 106 /* Attach the ED to the endpoint container. */ 107 endpoint -> ux_endpoint_ed = (VOID *) ed; 108 109 /* We need to take into account the nature of the HCD to define the max size 110 of any transfer in the transfer request. */ 111 endpoint -> ux_endpoint_transfer_request.ux_transfer_request_maximum_length = 112 endpoint -> ux_endpoint_descriptor.wMaxPacketSize; 113 114 /* Program the ED for subsequent transfers we need to set the following things: 115 1) Address of the device 116 2) endpoint number 117 3) speed (always full speed for iso) 118 4) format of TD 119 5) maximum packet size */ 120 121 device = endpoint -> ux_endpoint_device; 122 ed -> ux_ohci_ed_dw0 = device -> ux_device_address | UX_OHCI_ED_ISOCHRONOUS | 123 ((ULONG) (endpoint -> ux_endpoint_descriptor.bEndpointAddress & ~UX_ENDPOINT_DIRECTION)) << 7 | 124 ((ULONG) (endpoint -> ux_endpoint_descriptor.wMaxPacketSize)) << 16; 125 126 /* Hook the TD to both the tail and head of the ED. */ 127 ed -> ux_ohci_ed_tail_td = _ux_utility_physical_address(td); 128 ed -> ux_ohci_ed_head_td = _ux_utility_physical_address(td); 129 130 /* Attach the ED to the 1ms interrupt tree. We scan the interrupt tree until the last entry. */ 131 ed_list = _ux_utility_virtual_address(ohci_hcca -> ux_hcd_ohci_hcca_ed[0]); 132 while (ed_list -> ux_ohci_ed_next_ed != UX_NULL) 133 ed_list = _ux_utility_virtual_address(ed_list -> ux_ohci_ed_next_ed); 134 135 /* Now ed_list, points to the last ED, which is in the 1ms entry. */ 136 ed -> ux_ohci_ed_previous_ed = ed_list; 137 ed_list -> ux_ohci_ed_next_ed = _ux_utility_physical_address(ed); 138 139 /* Return success. */ 140 return(UX_SUCCESS); 141 } 142 143