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)74 UINT  _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