source: mainline/uspace/drv/bus/usb/xhci/bus.c@ e6b9182

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since e6b9182 was e6b9182, checked in by Ondřej Hlavatý <aearsis@…>, 8 years ago

WIP usbhost refactoring: ohci completed

Along with that we noticed hcd_t in bus_t is superfluous and it complicates initialization (and breaks isolation), so we removed it. Also, type of the toggle has changed to bool in the functions.

  • Property mode set to 100644
File size: 6.1 KB
Line 
1/*
2 * Copyright (c) 2017 Ondrej Hlavaty <aearsis@eideo.cz>
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 libusbhost
29 * @{
30 */
31/** @file
32 * HC Endpoint management.
33 */
34
35#include <adt/hash_table.h>
36#include <adt/hash.h>
37#include <usb/host/endpoint.h>
38#include <usb/debug.h>
39
40#include <assert.h>
41#include <errno.h>
42#include <macros.h>
43#include <stdbool.h>
44
45#include "bus.h"
46#include "endpoint.h"
47
48/** Element of the hash table. */
49typedef struct {
50 ht_link_t link;
51
52 /** Endpoint */
53 xhci_endpoint_t *endpoint;
54} hashed_endpoint_t;
55
56/** Ops receive generic bus_t pointer. */
57static inline xhci_bus_t *bus_to_xhci_bus(bus_t *bus_base)
58{
59 assert(bus_base);
60 return (xhci_bus_t *) bus_base;
61}
62
63static endpoint_t *create_endpoint(bus_t *base)
64{
65 xhci_bus_t *bus = bus_to_xhci_bus(base);
66
67 xhci_endpoint_t *ep = malloc(sizeof(xhci_endpoint_t));
68 if (!ep)
69 return NULL;
70
71 if (xhci_endpoint_init(ep, bus)) {
72 free(ep);
73 return NULL;
74 }
75
76 return &ep->base;
77}
78
79static void destroy_endpoint(endpoint_t *ep)
80{
81 xhci_endpoint_t *xhci_ep = xhci_endpoint_get(ep);
82
83 xhci_endpoint_fini(xhci_ep);
84 free(xhci_ep);
85}
86
87static int endpoint_find_by_target(xhci_bus_t *bus, usb_target_t target, hashed_endpoint_t **ep)
88{
89 ht_link_t *link = hash_table_find(&bus->endpoints, &target.packed);
90 if (link == NULL)
91 return ENOENT;
92
93 *ep = hash_table_get_inst(link, hashed_endpoint_t, link);
94 return EOK;
95}
96
97static int register_endpoint(bus_t *bus_base, endpoint_t *ep)
98{
99 xhci_bus_t *bus = bus_to_xhci_bus(bus_base);
100 assert(bus);
101
102 hashed_endpoint_t *hashed_ep =
103 (hashed_endpoint_t *) malloc(sizeof(hashed_endpoint_t));
104 if (!hashed_ep)
105 return ENOMEM;
106
107 hashed_ep->endpoint = xhci_endpoint_get(ep);
108 hash_table_insert(&bus->endpoints, &hashed_ep->link);
109
110 return EOK;
111}
112
113static int release_endpoint(bus_t *bus_base, endpoint_t *ep)
114{
115 xhci_bus_t *bus = bus_to_xhci_bus(bus_base);
116 assert(bus);
117
118 hashed_endpoint_t *hashed_ep;
119 int res = endpoint_find_by_target(bus, ep->target, &hashed_ep);
120 if (res != EOK)
121 return res;
122
123 hash_table_remove(&bus->endpoints, &ep->target.packed);
124 free(hashed_ep);
125
126 return EOK;
127}
128
129static endpoint_t* find_endpoint(bus_t *bus_base, usb_target_t target, usb_direction_t direction)
130{
131 xhci_bus_t *bus = bus_to_xhci_bus(bus_base);
132 assert(bus);
133
134 hashed_endpoint_t *hashed_ep;
135 int res = endpoint_find_by_target(bus, target, &hashed_ep);
136 if (res != EOK)
137 return NULL;
138
139 return &hashed_ep->endpoint->base;
140}
141
142static int request_address(bus_t *bus_base, usb_address_t *addr, bool strict, usb_speed_t speed)
143{
144 // TODO: Implement me!
145 return ENOTSUP;
146}
147
148static int get_speed(bus_t *bus_base, usb_address_t address, usb_speed_t *speed)
149{
150 // TODO: Implement me!
151 return ENOTSUP;
152}
153
154static int release_address(bus_t *bus_base, usb_address_t address)
155{
156 // TODO: Implement me!
157 return ENOTSUP;
158}
159
160static int reset_toggle(bus_t *bus_base, usb_target_t target, bool all)
161{
162 // TODO: Implement me!
163 return ENOTSUP;
164}
165
166static size_t count_bw(endpoint_t *ep, size_t size)
167{
168 // TODO: Implement me!
169 return 0;
170}
171
172/* Endpoint ops, optional (have generic fallback) */
173static bool endpoint_get_toggle(endpoint_t *ep)
174{
175 // TODO: Implement me!
176 return ENOTSUP;
177}
178
179static void endpoint_set_toggle(endpoint_t *ep, bool toggle)
180{
181 // TODO: Implement me!
182}
183
184static const bus_ops_t xhci_bus_ops = {
185 .create_endpoint = create_endpoint,
186 .destroy_endpoint = destroy_endpoint,
187
188 .register_endpoint = register_endpoint,
189 .release_endpoint = release_endpoint,
190 .find_endpoint = find_endpoint,
191
192 .request_address = request_address,
193 .get_speed = get_speed,
194 .release_address = release_address,
195 .reset_toggle = reset_toggle,
196
197 .count_bw = count_bw,
198
199 .endpoint_get_toggle = endpoint_get_toggle,
200 .endpoint_set_toggle = endpoint_set_toggle,
201};
202
203static size_t endpoint_ht_hash(const ht_link_t *item)
204{
205 hashed_endpoint_t *ep = hash_table_get_inst(item, hashed_endpoint_t, link);
206 return (size_t) hash_mix32(ep->endpoint->base.target.packed);
207}
208
209static size_t endpoint_ht_key_hash(void *key)
210{
211 return (size_t) hash_mix32(*(uint32_t *)key);
212}
213
214static bool endpoint_ht_key_equal(void *key, const ht_link_t *item)
215{
216 hashed_endpoint_t *ep = hash_table_get_inst(item, hashed_endpoint_t, link);
217 return ep->endpoint->base.target.packed == *(uint32_t *) key;
218}
219
220/** Operations for the endpoint hash table. */
221static hash_table_ops_t endpoint_ht_ops = {
222 .hash = endpoint_ht_hash,
223 .key_hash = endpoint_ht_key_hash,
224 .key_equal = endpoint_ht_key_equal,
225 .equal = NULL,
226 .remove_callback = NULL
227};
228
229int xhci_bus_init(xhci_bus_t *bus)
230{
231 assert(bus);
232
233 bus_init(&bus->base);
234
235 if (!hash_table_create(&bus->endpoints, 0, 0, &endpoint_ht_ops)) {
236 // FIXME: Dealloc base!
237 return ENOMEM;
238 }
239
240 bus->base.ops = xhci_bus_ops;
241 return EOK;
242}
243
244void xhci_bus_fini(xhci_bus_t *bus)
245{
246 hash_table_destroy(&bus->endpoints);
247}
248/**
249 * @}
250 */
Note: See TracBrowser for help on using the repository browser.