source: mainline/uspace/drv/bus/usb/ehci/endpoint_list.c@ 45cbf897

lfn serial ticket/834-toolchain-update topic/fix-logger-deadlock topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 45cbf897 was 45cbf897, checked in by Jan Vesely <jano.vesely@…>, 11 years ago

ehci, libusbhost: Move malloc32 to libusbhost.

So it can be shared with other HCDs.
Make sure the memory is mapped before returning from malloc32.
Add poison.

Fixes non-cntl transfers for ehci

  • Property mode set to 100644
File size: 5.3 KB
Line 
1/*
2 * Copyright (c) 2014 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
29/** @addtogroup drvusbehci
30 * @{
31 */
32/** @file
33 * @brief EHCI driver transfer list implementation
34 */
35
36#include <assert.h>
37#include <errno.h>
38#include <libarch/barrier.h>
39
40#include <usb/debug.h>
41
42#include "endpoint_list.h"
43
44/** Initialize transfer list structures.
45 *
46 * @param[in] instance Memory place to use.
47 * @param[in] name Name of the new list.
48 * @return Error code
49 *
50 * Allocates memory for internal ed_t structure.
51 */
52int endpoint_list_init(endpoint_list_t *instance, const char *name)
53{
54 assert(instance);
55 instance->name = name;
56 instance->list_head = malloc32(sizeof(qh_t));
57 if (!instance->list_head) {
58 usb_log_error("Failed to allocate list head.\n");
59 return ENOMEM;
60 }
61 qh_init(instance->list_head, NULL);
62
63 list_initialize(&instance->endpoint_list);
64 usb_log_debug2("Transfer list %s setup with ED: %p(%x).\n",
65 name, instance->list_head, addr_to_phys(instance->list_head));
66
67 fibril_mutex_initialize(&instance->guard);
68 return EOK;
69}
70
71void endpoint_list_chain(endpoint_list_t *instance, const endpoint_list_t *next)
72{
73 assert(instance);
74 assert(next);
75 assert(instance->list_head);
76 assert(next->list_head);
77
78 qh_append_qh(instance->list_head, next->list_head);
79}
80
81/** Add endpoint to the end of the list and queue.
82 *
83 * @param[in] instance List to use.
84 * @param[in] endpoint Endpoint to add.
85 *
86 * The endpoint is added to the end of the list and queue.
87 */
88void endpoint_list_append_ep(endpoint_list_t *instance, ehci_endpoint_t *ep)
89{
90 assert(instance);
91 assert(ep);
92 assert(ep->qh);
93 usb_log_debug2("Queue %s: Append endpoint(%p).\n", instance->name, ep);
94
95 fibril_mutex_lock(&instance->guard);
96
97 qh_t *last_qh = NULL;
98 /* Add to the hardware queue. */
99 if (list_empty(&instance->endpoint_list)) {
100 /* There are no active EDs */
101 last_qh = instance->list_head;
102 } else {
103 /* There are active EDs, get the last one */
104 ehci_endpoint_t *last = ehci_endpoint_list_instance(
105 list_last(&instance->endpoint_list));
106 last_qh = last->qh;
107 }
108 assert(last_qh);
109 /* Keep link, this might point to the queue QH, or next chained queue */
110 ep->qh->horizontal = last_qh->horizontal;
111 /* Make sure QH update is written to the memory */
112 write_barrier();
113
114 /* Add QH to the hw queue */
115 qh_append_qh(last_qh, ep->qh);
116 /* Make sure QH is updated */
117 write_barrier();
118 /* Add to the sw list */
119 list_append(&ep->link, &instance->endpoint_list);
120
121 ehci_endpoint_t *first = ehci_endpoint_list_instance(
122 list_first(&instance->endpoint_list));
123 usb_log_debug("HCD EP(%p) added to list %s, first is %p(%p).\n",
124 ep, instance->name, first, first->qh);
125 if (last_qh == instance->list_head) {
126 usb_log_debug2("%s head ED(%p-%x): %x:%x.\n",
127 instance->name, last_qh, addr_to_phys(instance->list_head),
128 last_qh->status, last_qh->horizontal);
129 }
130 fibril_mutex_unlock(&instance->guard);
131}
132
133/** Remove endpoint from the list and queue.
134 *
135 * @param[in] instance List to use.
136 * @param[in] endpoint Endpoint to remove.
137 */
138void endpoint_list_remove_ep(endpoint_list_t *instance, ehci_endpoint_t *ep)
139{
140 assert(instance);
141 assert(instance->list_head);
142 assert(ep);
143 assert(ep->qh);
144
145 fibril_mutex_lock(&instance->guard);
146
147 usb_log_debug2("Queue %s: removing endpoint(%p).\n", instance->name, ep);
148
149 const char *qpos = NULL;
150 qh_t *prev_qh;
151 /* Remove from the hardware queue */
152 if (list_first(&instance->endpoint_list) == &ep->link) {
153 /* I'm the first one here */
154 prev_qh = instance->list_head;
155 qpos = "FIRST";
156 } else {
157 prev_qh = ehci_endpoint_list_instance(ep->link.prev)->qh;
158 qpos = "NOT FIRST";
159 }
160 assert(qh_next(prev_qh) == addr_to_phys(ep->qh));
161 prev_qh->horizontal = ep->qh->horizontal;
162 /* Make sure ED is updated */
163 write_barrier();
164
165 usb_log_debug("HCD EP(%p) removed (%s) from %s, horizontal %x.\n",
166 ep, qpos, instance->name, ep->qh->horizontal);
167
168 /* Remove from the endpoint list */
169 list_remove(&ep->link);
170 fibril_mutex_unlock(&instance->guard);
171}
172/**
173 * @}
174 */
175
Note: See TracBrowser for help on using the repository browser.