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_request_interrupt_transfer PORTABLE C */ 38 /* 6.1 */ 39 /* AUTHOR */ 40 /* */ 41 /* Chaoqiong Xiao, Microsoft Corporation */ 42 /* */ 43 /* DESCRIPTION */ 44 /* */ 45 /* This function performs an interrupt transfer request. An interrupt */ 46 /* transfer can only be as large as the MaxpacketField in the */ 47 /* endpoint descriptor. This was verified at a higher layer and does */ 48 /* not need to be reverified here. */ 49 /* */ 50 /* INPUT */ 51 /* */ 52 /* hcd_ohci Pointer to OHCI controller */ 53 /* transfer_request Pointer to transfer request */ 54 /* */ 55 /* OUTPUT */ 56 /* */ 57 /* Completion Status */ 58 /* */ 59 /* CALLS */ 60 /* */ 61 /* _ux_hcd_ohci_regular_td_obtain Get regular TD */ 62 /* _ux_utility_physical_address Get physical address */ 63 /* _ux_utility_virtual_address Get virtual address */ 64 /* */ 65 /* CALLED BY */ 66 /* */ 67 /* OHCI Controller Driver */ 68 /* */ 69 /* RELEASE HISTORY */ 70 /* */ 71 /* DATE NAME DESCRIPTION */ 72 /* */ 73 /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ 74 /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ 75 /* resulting in version 6.1 */ 76 /* */ 77 /**************************************************************************/ _ux_hcd_ohci_request_interrupt_transfer(UX_HCD_OHCI * hcd_ohci,UX_TRANSFER * transfer_request)78UINT _ux_hcd_ohci_request_interrupt_transfer(UX_HCD_OHCI *hcd_ohci, UX_TRANSFER *transfer_request) 79 { 80 81 UX_ENDPOINT *endpoint; 82 UX_OHCI_ED *ed; 83 UX_OHCI_TD *data_td; 84 UX_OHCI_TD *tail_td; 85 86 87 /* Get the pointer to the Endpoint. */ 88 endpoint = (UX_ENDPOINT *) transfer_request -> ux_transfer_request_endpoint; 89 90 /* Now get the physical ED attached to this endpoint. */ 91 ed = endpoint -> ux_endpoint_ed; 92 93 /* Use the TD pointer by ed -> tail for the first TD of this transfer 94 and chain from this one on. */ 95 data_td = _ux_utility_virtual_address(ed -> ux_ohci_ed_tail_td); 96 97 /* Set the direction of the transfer. In USB 1.0, the direction of the Interrupt pipe could 98 only be HOST to DEVICE. In 1.1 bidirectional interrupt endpoints can be allowed. The 99 direction was checked when the endpoint was initialized. */ 100 if ((transfer_request -> ux_transfer_request_type & UX_REQUEST_DIRECTION) == UX_REQUEST_IN) 101 102 data_td -> ux_ohci_td_dw0 = UX_OHCI_TD_IN | UX_OHCI_TD_DEFAULT_DW0; 103 else 104 105 data_td -> ux_ohci_td_dw0 = UX_OHCI_TD_OUT | UX_OHCI_TD_DEFAULT_DW0; 106 107 /* Store the beginning of the buffer address in the TD. */ 108 data_td -> ux_ohci_td_cbp = _ux_utility_physical_address(transfer_request -> ux_transfer_request_data_pointer); 109 110 /* Store the end buffer address in the TD. */ 111 data_td -> ux_ohci_td_be = data_td -> ux_ohci_td_cbp + transfer_request -> ux_transfer_request_requested_length - 1; 112 113 /* Update the length of the transfer for this TD. */ 114 data_td -> ux_ohci_td_length = transfer_request -> ux_transfer_request_requested_length; 115 116 /* Attach the endpoint and transfer_request to the TD. */ 117 data_td -> ux_ohci_td_transfer_request = transfer_request; 118 data_td -> ux_ohci_td_ed = ed; 119 120 /* At this stage, the Head and Tail in the ED are still the same and the OHCI controller 121 will skip this ED until we have hooked the new tail TD. */ 122 tail_td = _ux_hcd_ohci_regular_td_obtain(hcd_ohci); 123 if (tail_td == UX_NULL) 124 return(UX_NO_TD_AVAILABLE); 125 126 /* Attach the tail TD to the last data TD. */ 127 data_td -> ux_ohci_td_next_td = _ux_utility_physical_address(tail_td); 128 129 /* Store the new tail TD. */ 130 ed -> ux_ohci_ed_tail_td = _ux_utility_physical_address(tail_td); 131 132 /* There is no need to wake up the ohci controller on this transfer 133 since periodic transactions will be picked up when the interrupt 134 tree is scanned. */ 135 return(UX_SUCCESS); 136 } 137 138