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 /** Host Simulator Controller Driver */ 18 /** */ 19 /**************************************************************************/ 20 /**************************************************************************/ 21 22 #define UX_SOURCE_CODE 23 24 25 /* Include necessary system files. */ 26 27 #include "ux_api.h" 28 #include "ux_hcd_sim_host.h" 29 30 31 /**************************************************************************/ 32 /* */ 33 /* FUNCTION RELEASE */ 34 /* */ 35 /* _ux_hcd_sim_host_request_interrupt_transfer PORTABLE C */ 36 /* 6.1 */ 37 /* AUTHOR */ 38 /* */ 39 /* Chaoqiong Xiao, Microsoft Corporation */ 40 /* */ 41 /* DESCRIPTION */ 42 /* */ 43 /* This function performs an interrupt transfer request. An interrupt */ 44 /* transfer can only be as large as the Maxpacket Field in the */ 45 /* endpoint descriptor. This was verified at the USB layer and does */ 46 /* not need to be reverified here. */ 47 /* */ 48 /* INPUT */ 49 /* */ 50 /* hcd_sim_host Pointer to host controller */ 51 /* transfer_request Pointer to transfer request */ 52 /* */ 53 /* OUTPUT */ 54 /* */ 55 /* Completion Status */ 56 /* */ 57 /* CALLS */ 58 /* */ 59 /* _ux_hcd_sim_host_regular_td_obtain Obtain regular TD */ 60 /* */ 61 /* CALLED BY */ 62 /* */ 63 /* Host Simulator Controller Driver */ 64 /* */ 65 /* RELEASE HISTORY */ 66 /* */ 67 /* DATE NAME DESCRIPTION */ 68 /* */ 69 /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ 70 /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ 71 /* resulting in version 6.1 */ 72 /* */ 73 /**************************************************************************/ _ux_hcd_sim_host_request_interrupt_transfer(UX_HCD_SIM_HOST * hcd_sim_host,UX_TRANSFER * transfer_request)74UINT _ux_hcd_sim_host_request_interrupt_transfer(UX_HCD_SIM_HOST *hcd_sim_host, UX_TRANSFER *transfer_request) 75 { 76 77 UX_ENDPOINT *endpoint; 78 UX_HCD_SIM_HOST_ED *ed; 79 UX_HCD_SIM_HOST_TD *data_td; 80 UX_HCD_SIM_HOST_TD *tail_td; 81 82 83 /* Get the pointer to the Endpoint. */ 84 endpoint = (UX_ENDPOINT *) transfer_request -> ux_transfer_request_endpoint; 85 86 /* Now get the physical ED attached to this endpoint. */ 87 ed = endpoint -> ux_endpoint_ed; 88 89 /* Use the TD pointer by ed -> tail for the first TD of this transfer 90 and chain from this one on. */ 91 data_td = ed -> ux_sim_host_ed_tail_td; 92 93 /* Set the direction of the transfer. */ 94 if ((transfer_request -> ux_transfer_request_type & UX_REQUEST_DIRECTION) == UX_REQUEST_IN) 95 data_td -> ux_sim_host_td_direction = UX_HCD_SIM_HOST_TD_IN; 96 else 97 data_td -> ux_sim_host_td_direction = UX_HCD_SIM_HOST_TD_OUT; 98 99 /* Mark the TD with the DATA phase. */ 100 data_td -> ux_sim_host_td_status |= UX_HCD_SIM_HOST_TD_DATA_PHASE; 101 102 /* The Toggle value is in the ED. */ 103 data_td -> ux_sim_host_td_toggle = UX_HCD_SIM_HOST_TD_TOGGLE_FROM_ED; 104 105 /* Store the beginning of the buffer address in the TD. */ 106 data_td -> ux_sim_host_td_buffer = transfer_request -> ux_transfer_request_data_pointer; 107 108 /* Update the length of the transfer for this TD. */ 109 data_td -> ux_sim_host_td_length = transfer_request -> ux_transfer_request_requested_length; 110 111 /* Attach the endpoint and transfer request to the TD. */ 112 data_td -> ux_sim_host_td_transfer_request = transfer_request; 113 data_td -> ux_sim_host_td_ed = ed; 114 115 /* At this stage, the Head and Tail in the ED are still the same and 116 the host simulator controller will skip this ED until we have hooked the new 117 tail TD. */ 118 tail_td = _ux_hcd_sim_host_regular_td_obtain(hcd_sim_host); 119 if (tail_td == UX_NULL) 120 return(UX_NO_TD_AVAILABLE); 121 122 /* Attach the tail TD to the last data TD. */ 123 data_td -> ux_sim_host_td_next_td = tail_td; 124 125 /* Store the new tail TD. */ 126 ed -> ux_sim_host_ed_tail_td = tail_td; 127 128 /* Now we can tell the scheduler to wake up. */ 129 hcd_sim_host -> ux_hcd_sim_host_queue_empty = UX_FALSE; 130 131 /* There is no need to wake up the sim_host controller on this transfer 132 since periodic transactions will be picked up when the interrupt 133 tree is scanned. */ 134 return(UX_SUCCESS); 135 } 136 137