source: mainline/uspace/drv/bus/usb/ehci/hw_struct/queue_head.h

Last change on this file was 09ab0a9a, checked in by Jiri Svoboda <jiri@…>, 7 years ago

Fix vertical spacing with new Ccheck revision.

  • Property mode set to 100644
File size: 7.1 KB
RevLine 
[6576019]1/*
2 * Copyright (c) 2013 Jan Vesely
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28/** @addtogroup drvusbehci
29 * @{
30 */
31/** @file
32 * @brief EHCI driver
33 */
34#ifndef DRV_EHCI_HW_STRUCT_QH_H
35#define DRV_EHCI_HW_STRUCT_QH_H
36
37#include <assert.h>
[8d2dd7f2]38#include <stdint.h>
[a24d6825]39#include <usb/host/endpoint.h>
[45cbf897]40#include <usb/host/utils/malloc32.h>
[6576019]41
42#include "link_pointer.h"
[23e5471]43#include "transfer_descriptor.h"
[3de7a62]44#include "mem_access.h"
[6576019]45
46/** This structure is defined in EHCI design guide p. 46 */
47typedef struct queue_head {
48 link_pointer_t horizontal;
49
50 volatile uint32_t ep_char;
[904b1bc]51 volatile uint32_t ep_cap;
52
53 link_pointer_t current;
54 /* Transfer overlay starts here */
55 link_pointer_t next;
56 link_pointer_t alternate;
57 volatile uint32_t status;
58 volatile uint32_t buffer_pointer[5];
59
60 /* 64 bit struct only */
61 volatile uint32_t extended_bp[5];
62} __attribute__((packed, aligned(32))) qh_t;
63
64/*
65 * qh_t.ep_char
66 */
[6576019]67#define QH_EP_CHAR_RL_MASK 0xf
68#define QH_EP_CHAR_RL_SHIFT 28
69#define QH_EP_CHAR_C_FLAG (1 << 27)
[a24d6825]70#define QH_EP_CHAR_MAX_LENGTH_MASK 0x7ff
71#define QH_EP_CHAR_MAX_LENGTH_SHIFT 16
72#define QH_EP_CHAR_MAX_LENGTH_SET(len) \
73 (((len) & QH_EP_CHAR_MAX_LENGTH_MASK) << QH_EP_CHAR_MAX_LENGTH_SHIFT)
74#define QH_EP_CHAR_MAX_LENGTH_GET(val) \
75 (((val) >> QH_EP_CHAR_MAX_LENGTH_SHIFT) & QH_EP_CHAR_MAX_LENGTH_MASK)
[6576019]76#define QH_EP_CHAR_H_FLAG (1 << 15)
77#define QH_EP_CHAR_DTC_FLAG (1 << 14)
[a24d6825]78#define QH_EP_CHAR_EPS_FS (0x0 << 12)
79#define QH_EP_CHAR_EPS_LS (0x1 << 12)
80#define QH_EP_CHAR_EPS_HS (0x2 << 12)
81#define QH_EP_CHAR_EPS_MASK (0x3 << 12)
[6576019]82#define QH_EP_CHAR_EP_MASK 0xf
83#define QH_EP_CHAR_EP_SHIFT 8
[a24d6825]84#define QH_EP_CHAR_EP_SET(num) \
85 (((num) & QH_EP_CHAR_EP_MASK) << QH_EP_CHAR_EP_SHIFT)
86#define QH_EP_CHAR_ADDR_GET(val) \
87 (((val) >> QH_EP_CHAR_ADDR_SHIFT) & QH_EP_CHAR_ADDR_MASK)
[6576019]88#define QH_EP_CHAR_INACT_FLAG (1 << 7)
89#define QH_EP_CHAR_ADDR_MASK 0x3f
90#define QH_EP_CHAR_ADDR_SHIFT 0
[a24d6825]91#define QH_EP_CHAR_ADDR_SET(addr) \
92 (((addr) & QH_EP_CHAR_ADDR_MASK) << QH_EP_CHAR_ADDR_SHIFT)
93#define QH_EP_CHAR_ADDR_GET(val) \
94 (((val) >> QH_EP_CHAR_ADDR_SHIFT) & QH_EP_CHAR_ADDR_MASK)
[6576019]95
[904b1bc]96/*
97 * qh_t.ep_cap
98 */
[6576019]99#define QH_EP_CAP_MULTI_MASK 0x3
100#define QH_EP_CAP_MULTI_SHIFT 30
[a24d6825]101#define QH_EP_CAP_MULTI_SET(count) \
102 (((count) & QH_EP_CAP_MULTI_MASK) << QH_EP_CAP_MULTI_SHIFT)
[6576019]103#define QH_EP_CAP_PORT_MASK 0x7f
104#define QH_EP_CAP_PORT_SHIFT 23
[a24d6825]105#define QH_EP_CAP_TT_PORT_SET(addr) \
106 (((addr) & QH_EP_CAP_HUB_MASK) << QH_EP_CAP_HUB_SHIFT)
[6576019]107#define QH_EP_CAP_HUB_MASK 0x7f
108#define QH_EP_CAP_HUB_SHIFT 16
[a24d6825]109#define QH_EP_CAP_TT_ADDR_SET(addr) \
110 (((addr) & QH_EP_CAP_HUB_MASK) << QH_EP_CAP_HUB_SHIFT)
[6576019]111#define QH_EP_CAP_C_MASK_MASK 0xff
112#define QH_EP_CAP_C_MASK_SHIFT 8
[a24d6825]113#define QH_EP_CAP_C_MASK_SET(val) \
114 (((val) & QH_EP_CAP_C_MASK_MASK) << QH_EP_CAP_C_MASK_SHIFT)
[6576019]115#define QH_EP_CAP_S_MASK_MASK 0xff
[a24d6825]116#define QH_EP_CAP_S_MASK_SHIFT 0
117#define QH_EP_CAP_S_MASK_SET(val) \
118 (((val) & QH_EP_CAP_S_MASK_MASK) << QH_EP_CAP_S_MASK_SHIFT)
[6576019]119
[904b1bc]120/*
121 * qh_t.alternate
122 */
[6576019]123#define QH_ALTERNATE_NACK_CNT_MASK 0x7
124#define QH_ALTERNATE_NACK_CNT_SHIFT 1
125
[904b1bc]126/*
127 * qh_t.status
128 */
[6576019]129#define QH_STATUS_TOGGLE_FLAG (1 << 31)
130#define QH_STATUS_TOTAL_MASK 0x7fff
131#define QH_STATUS_TOTAL_SHIFT 16
132#define QH_STATUS_IOC_FLAG (1 << 15)
133#define QH_STATUS_C_PAGE_MASK 0x7
134#define QH_STATUS_C_PAGE_SHIFT 12
135#define QH_STATUS_CERR_MASK 0x3
136#define QH_STATUS_CERR_SHIFT 10
137#define QH_STATUS_PID_MASK 0x3
138#define QH_STATUS_PID_SHIFT 8
139#define QH_STATUS_ACTIVE_FLAG (1 << 7)
140#define QH_STATUS_HALTED_FLAG (1 << 6)
141#define QH_STATUS_BUFF_ERROR_FLAG (1 << 5)
142#define QH_STATUS_BABBLE_FLAG (1 << 4)
143#define QH_STATUS_TRANS_ERR_FLAG (1 << 3)
144#define QH_STATUS_MISSED_FLAG (1 << 2)
145#define QH_STATUS_SPLIT_FLAG (1 << 1)
146#define QH_STATUS_PING_FLAG (1 << 0)
147
[904b1bc]148/*
149 * qh_t.buffer_pointer
150 */
[6576019]151#define QH_BUFFER_POINTER_MASK 0xfffff000
152/* Only the first buffer pointer */
153#define QH_BUFFER_POINTER_OFFSET_MASK 0xfff
154#define QH_BUFFER_POINTER_OFFSET_SHIFT 0
155/* Only the second buffer pointer */
156#define QH_BUFFER_POINTER_C_MASK_MASK 0xff
157#define QH_BUFFER_POINTER_C_MASK_SHIFFT 0
158/* Only the third buffer pointer */
159#define QH_BUFFER_POINTER_S_MASK 0x7f
160#define QH_BUFFER_POINTER_S_SHIFT 5
161#define QH_BUFFER_POINTER_FTAG_MASK 0x1f
162#define QH_BUFFER_POINTER_FTAG_SHIFT 0
163
[3de7a62]164static inline void qh_append_qh(qh_t *qh, const qh_t *next)
165{
166 assert(qh);
167 assert(next);
168 const uint32_t pa = addr_to_phys(next);
169 assert((pa & LINK_POINTER_ADDRESS_MASK) == pa);
170 EHCI_MEM32_WR(qh->horizontal, LINK_POINTER_QH(pa));
171}
172
173static inline uintptr_t qh_next(const qh_t *qh)
174{
175 assert(qh);
[42de21a]176 return (EHCI_MEM32_RD(qh->horizontal) & LINK_POINTER_ADDRESS_MASK);
[3de7a62]177}
178
[42de21a]179static inline bool qh_toggle_from_td(const qh_t *qh)
180{
181 assert(qh);
182 return (EHCI_MEM32_RD(qh->ep_cap) & QH_EP_CHAR_DTC_FLAG);
183}
184
185static inline void qh_toggle_set(qh_t *qh, int toggle)
186{
187 assert(qh);
188 if (toggle)
189 EHCI_MEM32_SET(qh->status, QH_STATUS_TOGGLE_FLAG);
190 else
191 EHCI_MEM32_CLR(qh->status, QH_STATUS_TOGGLE_FLAG);
192}
193
194static inline int qh_toggle_get(const qh_t *qh)
195{
196 assert(qh);
197 return (EHCI_MEM32_RD(qh->status) & QH_STATUS_TOGGLE_FLAG) ? 1 : 0;
198}
199
[6602e97]200static inline bool qh_halted(const qh_t *qh)
201{
202 assert(qh);
203 return (EHCI_MEM32_RD(qh->status) & QH_STATUS_HALTED_FLAG);
204}
205
[a752c78c]206static inline void qh_clear_halt(qh_t *qh)
[6602e97]207{
208 assert(qh);
[a752c78c]209 EHCI_MEM32_CLR(qh->status, QH_STATUS_HALTED_FLAG);
[6602e97]210}
211
[35c37fc]212static inline void qh_set_next_td(qh_t *qh, uintptr_t td)
[23e5471]213{
214 assert(qh);
215 assert(td);
[35c37fc]216 EHCI_MEM32_WR(qh->next, LINK_POINTER_TD(td));
[23e5471]217}
218
[5c830587]219static inline bool qh_transfer_active(const qh_t *qh)
220{
221 assert(qh);
222 return (EHCI_MEM32_RD(qh->status) & QH_STATUS_ACTIVE_FLAG);
223}
224
[6602e97]225static inline bool qh_transfer_pending(const qh_t *qh)
226{
227 assert(qh);
228 return !(EHCI_MEM32_RD(qh->next) & LINK_POINTER_TERMINATE_FLAG);
229}
230
[904b1bc]231extern void qh_init(qh_t *instance, const endpoint_t *ep);
[42de21a]232
[6576019]233#endif
234/**
235 * @}
236 */
Note: See TracBrowser for help on using the repository browser.