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

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since cc7575c was 23e5471, checked in by Jan Vesely <jano.vesely@…>, 12 years ago

ehci: Implement batch commit

  • Property mode set to 100644
File size: 6.7 KB
Line 
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>
38#include <sys/types.h>
39#include <usb/host/endpoint.h>
40
41#include "../utils/malloc32.h"
42#include "link_pointer.h"
43#include "transfer_descriptor.h"
44#include "mem_access.h"
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;
51#define QH_EP_CHAR_RL_MASK 0xf
52#define QH_EP_CHAR_RL_SHIFT 28
53#define QH_EP_CHAR_C_FLAG (1 << 27)
54#define QH_EP_CHAR_MAX_LENGTH_MASK 0x7ff
55#define QH_EP_CHAR_MAX_LENGTH_SHIFT 16
56#define QH_EP_CHAR_MAX_LENGTH_SET(len) \
57 (((len) & QH_EP_CHAR_MAX_LENGTH_MASK) << QH_EP_CHAR_MAX_LENGTH_SHIFT)
58#define QH_EP_CHAR_MAX_LENGTH_GET(val) \
59 (((val) >> QH_EP_CHAR_MAX_LENGTH_SHIFT) & QH_EP_CHAR_MAX_LENGTH_MASK)
60#define QH_EP_CHAR_H_FLAG (1 << 15)
61#define QH_EP_CHAR_DTC_FLAG (1 << 14)
62#define QH_EP_CHAR_EPS_FS (0x0 << 12)
63#define QH_EP_CHAR_EPS_LS (0x1 << 12)
64#define QH_EP_CHAR_EPS_HS (0x2 << 12)
65#define QH_EP_CHAR_EPS_MASK (0x3 << 12)
66#define QH_EP_CHAR_EP_MASK 0xf
67#define QH_EP_CHAR_EP_SHIFT 8
68#define QH_EP_CHAR_EP_SET(num) \
69 (((num) & QH_EP_CHAR_EP_MASK) << QH_EP_CHAR_EP_SHIFT)
70#define QH_EP_CHAR_ADDR_GET(val) \
71 (((val) >> QH_EP_CHAR_ADDR_SHIFT) & QH_EP_CHAR_ADDR_MASK)
72#define QH_EP_CHAR_INACT_FLAG (1 << 7)
73#define QH_EP_CHAR_ADDR_MASK 0x3f
74#define QH_EP_CHAR_ADDR_SHIFT 0
75#define QH_EP_CHAR_ADDR_SET(addr) \
76 (((addr) & QH_EP_CHAR_ADDR_MASK) << QH_EP_CHAR_ADDR_SHIFT)
77#define QH_EP_CHAR_ADDR_GET(val) \
78 (((val) >> QH_EP_CHAR_ADDR_SHIFT) & QH_EP_CHAR_ADDR_MASK)
79
80 volatile uint32_t ep_cap;
81#define QH_EP_CAP_MULTI_MASK 0x3
82#define QH_EP_CAP_MULTI_SHIFT 30
83#define QH_EP_CAP_MULTI_SET(count) \
84 (((count) & QH_EP_CAP_MULTI_MASK) << QH_EP_CAP_MULTI_SHIFT)
85#define QH_EP_CAP_PORT_MASK 0x7f
86#define QH_EP_CAP_PORT_SHIFT 23
87#define QH_EP_CAP_TT_PORT_SET(addr) \
88 (((addr) & QH_EP_CAP_HUB_MASK) << QH_EP_CAP_HUB_SHIFT)
89#define QH_EP_CAP_HUB_MASK 0x7f
90#define QH_EP_CAP_HUB_SHIFT 16
91#define QH_EP_CAP_TT_ADDR_SET(addr) \
92 (((addr) & QH_EP_CAP_HUB_MASK) << QH_EP_CAP_HUB_SHIFT)
93#define QH_EP_CAP_C_MASK_MASK 0xff
94#define QH_EP_CAP_C_MASK_SHIFT 8
95#define QH_EP_CAP_C_MASK_SET(val) \
96 (((val) & QH_EP_CAP_C_MASK_MASK) << QH_EP_CAP_C_MASK_SHIFT)
97#define QH_EP_CAP_S_MASK_MASK 0xff
98#define QH_EP_CAP_S_MASK_SHIFT 0
99#define QH_EP_CAP_S_MASK_SET(val) \
100 (((val) & QH_EP_CAP_S_MASK_MASK) << QH_EP_CAP_S_MASK_SHIFT)
101
102 link_pointer_t current;
103/* Transfer overlay starts here */
104 link_pointer_t next;
105 link_pointer_t alternate;
106#define QH_ALTERNATE_NACK_CNT_MASK 0x7
107#define QH_ALTERNATE_NACK_CNT_SHIFT 1
108
109 volatile uint32_t status;
110#define QH_STATUS_TOGGLE_FLAG (1 << 31)
111#define QH_STATUS_TOTAL_MASK 0x7fff
112#define QH_STATUS_TOTAL_SHIFT 16
113#define QH_STATUS_IOC_FLAG (1 << 15)
114#define QH_STATUS_C_PAGE_MASK 0x7
115#define QH_STATUS_C_PAGE_SHIFT 12
116#define QH_STATUS_CERR_MASK 0x3
117#define QH_STATUS_CERR_SHIFT 10
118#define QH_STATUS_PID_MASK 0x3
119#define QH_STATUS_PID_SHIFT 8
120#define QH_STATUS_ACTIVE_FLAG (1 << 7)
121#define QH_STATUS_HALTED_FLAG (1 << 6)
122#define QH_STATUS_BUFF_ERROR_FLAG (1 << 5)
123#define QH_STATUS_BABBLE_FLAG (1 << 4)
124#define QH_STATUS_TRANS_ERR_FLAG (1 << 3)
125#define QH_STATUS_MISSED_FLAG (1 << 2)
126#define QH_STATUS_SPLIT_FLAG (1 << 1)
127#define QH_STATUS_PING_FLAG (1 << 0)
128
129 volatile uint32_t buffer_pointer[5];
130#define QH_BUFFER_POINTER_MASK 0xfffff000
131/* Only the first buffer pointer */
132#define QH_BUFFER_POINTER_OFFSET_MASK 0xfff
133#define QH_BUFFER_POINTER_OFFSET_SHIFT 0
134/* Only the second buffer pointer */
135#define QH_BUFFER_POINTER_C_MASK_MASK 0xff
136#define QH_BUFFER_POINTER_C_MASK_SHIFFT 0
137/* Only the third buffer pointer */
138#define QH_BUFFER_POINTER_S_MASK 0x7f
139#define QH_BUFFER_POINTER_S_SHIFT 5
140#define QH_BUFFER_POINTER_FTAG_MASK 0x1f
141#define QH_BUFFER_POINTER_FTAG_SHIFT 0
142
143} qh_t;
144
145static inline void qh_append_qh(qh_t *qh, const qh_t *next)
146{
147 assert(qh);
148 assert(next);
149 const uint32_t pa = addr_to_phys(next);
150 assert((pa & LINK_POINTER_ADDRESS_MASK) == pa);
151 EHCI_MEM32_WR(qh->horizontal, LINK_POINTER_QH(pa));
152}
153
154static inline uintptr_t qh_next(const qh_t *qh)
155{
156 assert(qh);
157 return (EHCI_MEM32_RD(qh->horizontal) & LINK_POINTER_ADDRESS_MASK);
158}
159
160static inline bool qh_toggle_from_td(const qh_t *qh)
161{
162 assert(qh);
163 return (EHCI_MEM32_RD(qh->ep_cap) & QH_EP_CHAR_DTC_FLAG);
164}
165
166static inline void qh_toggle_set(qh_t *qh, int toggle)
167{
168 assert(qh);
169 if (toggle)
170 EHCI_MEM32_SET(qh->status, QH_STATUS_TOGGLE_FLAG);
171 else
172 EHCI_MEM32_CLR(qh->status, QH_STATUS_TOGGLE_FLAG);
173}
174
175static inline int qh_toggle_get(const qh_t *qh)
176{
177 assert(qh);
178 return (EHCI_MEM32_RD(qh->status) & QH_STATUS_TOGGLE_FLAG) ? 1 : 0;
179}
180
181static inline bool qh_halted(const qh_t *qh)
182{
183 assert(qh);
184 return (EHCI_MEM32_RD(qh->status) & QH_STATUS_HALTED_FLAG);
185}
186
187static inline void qh_clear_halt(qh_t *qh)
188{
189 assert(qh);
190 EHCI_MEM32_CLR(qh->status, QH_STATUS_HALTED_FLAG);
191}
192
193static inline void qh_set_next_td(qh_t *qh, td_t *td)
194{
195 assert(qh);
196 assert(td);
197 EHCI_MEM32_WR(qh->next, LINK_POINTER_TD(addr_to_phys(td)));
198}
199
200static inline bool qh_transfer_pending(const qh_t *qh)
201{
202 assert(qh);
203 return !(EHCI_MEM32_RD(qh->next) & LINK_POINTER_TERMINATE_FLAG);
204}
205
206
207void qh_init(qh_t *instance, const endpoint_t *ep);
208#endif
209/**
210 * @}
211 */
Note: See TracBrowser for help on using the repository browser.