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 /** EHCI 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_ehci.h"
29 #include "ux_host_stack.h"
30
31
32 /**************************************************************************/
33 /* */
34 /* FUNCTION RELEASE */
35 /* */
36 /* _ux_hcd_ehci_request_interrupt_transfer PORTABLE C */
37 /* 6.1 */
38 /* AUTHOR */
39 /* */
40 /* Chaoqiong Xiao, Microsoft Corporation */
41 /* */
42 /* DESCRIPTION */
43 /* */
44 /* This function performs an interrupt transfer request. An interrupt */
45 /* transfer can only be as large as the MaxpacketField in the */
46 /* endpoint descriptor. This was verified at the upper layer and does */
47 /* not need to be reverified here. */
48 /* */
49 /* INPUT */
50 /* */
51 /* hcd_ehci Pointer to EHCI controller */
52 /* transfer_request Pointer to transfer request */
53 /* */
54 /* OUTPUT */
55 /* */
56 /* Completion Status */
57 /* */
58 /* CALLS */
59 /* */
60 /* _ux_hcd_ehci_request_transfer_add Add transfer to ED */
61 /* */
62 /* CALLED BY */
63 /* */
64 /* EHCI Controller Driver */
65 /* */
66 /* RELEASE HISTORY */
67 /* */
68 /* DATE NAME DESCRIPTION */
69 /* */
70 /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
71 /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */
72 /* resulting in version 6.1 */
73 /* */
74 /**************************************************************************/
_ux_hcd_ehci_request_interrupt_transfer(UX_HCD_EHCI * hcd_ehci,UX_TRANSFER * transfer_request)75 UINT _ux_hcd_ehci_request_interrupt_transfer(UX_HCD_EHCI *hcd_ehci, UX_TRANSFER *transfer_request)
76 {
77
78 UX_ENDPOINT *endpoint;
79 UX_EHCI_ED *ed;
80 ULONG pid;
81 ULONG td_component;
82 UINT status;
83
84
85 /* Get the pointer to the endpoint. */
86 endpoint = (UX_ENDPOINT *) transfer_request -> ux_transfer_request_endpoint;
87
88 /* Now get the physical ED attached to this endpoint. */
89 ed = endpoint -> ux_endpoint_ed;
90
91 /* The overlay parameters should be reset now. */
92 ed -> ux_ehci_ed_current_td = UX_NULL;
93 ed -> ux_ehci_ed_queue_element = (UX_EHCI_TD *) UX_EHCI_TD_T;
94 ed -> ux_ehci_ed_alternate_td = (UX_EHCI_TD *) UX_EHCI_QH_T;
95 ed -> ux_ehci_ed_state &= UX_EHCI_QH_TOGGLE;
96 ed -> ux_ehci_ed_bp0 = UX_NULL;
97 ed -> ux_ehci_ed_bp1 = UX_NULL;
98 ed -> ux_ehci_ed_bp2 = UX_NULL;
99 ed -> ux_ehci_ed_bp3 = UX_NULL;
100 ed -> ux_ehci_ed_bp4 = UX_NULL;
101
102 /* Get the correct PID for this transfer. */
103 if ((transfer_request -> ux_transfer_request_type & UX_REQUEST_DIRECTION) == UX_REQUEST_IN)
104 pid = UX_EHCI_PID_IN;
105 else
106 pid = UX_EHCI_PID_OUT;
107
108 /* Add this transfer request to the ED. */
109 status = _ux_hcd_ehci_request_transfer_add(hcd_ehci, ed, 0, pid, 0,
110 transfer_request -> ux_transfer_request_data_pointer,
111 transfer_request -> ux_transfer_request_requested_length,
112 transfer_request);
113
114 /* Ensure we got the TD allocated properly. */
115 if (status == UX_SUCCESS)
116 {
117
118 /* Set the IOC bit in the last TD. */
119 ed -> ux_ehci_ed_last_td -> ux_ehci_td_control |= UX_EHCI_TD_IOC;
120
121 /* Ensure the IOC bit is set before activating the TD. This is necessary
122 for some processors that perform writes out of order as an optimization. */
123 UX_DATA_MEMORY_BARRIER
124
125 /* Activate the first TD linked to the ED. */
126 td_component = (ULONG) ed -> ux_ehci_ed_queue_element;
127 td_component &= ~UX_EHCI_TD_T;
128 ed -> ux_ehci_ed_queue_element = (UX_EHCI_TD *) td_component;
129
130 }
131
132 /* Return completion status. */
133 return(status);
134 }
135
136