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