source: mainline/uspace/lib/usbhost/src/bus.c@ 56db65d

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

usbhost: provide usb_endpoint_desc_t to bus when registering endpoint

This finishes the path of arbitrary information fetched from device all the way down to registering the endpoint in the bus.

  • Property mode set to 100644
File size: 5.7 KB
RevLine 
[41924f30]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
29/** @addtogroup libusbhost
30 * @{
31 */
32/** @file
33 *
34 */
35
36#include <usb/host/bus.h>
37#include <usb/host/endpoint.h>
[20eaa82]38#include <ddf/driver.h>
[41924f30]39
40#include <mem.h>
41#include <errno.h>
[20eaa82]42#include <stdio.h>
[41924f30]43
44/**
45 * Initializes the bus structure.
46 */
[20eaa82]47void bus_init(bus_t *bus, size_t device_size)
[41924f30]48{
[20eaa82]49 assert(bus);
50 assert(device_size >= sizeof(device_t));
[41924f30]51 memset(bus, 0, sizeof(bus_t));
52
53 fibril_mutex_initialize(&bus->guard);
[20eaa82]54 bus->device_size = device_size;
55}
56
57int device_init(device_t *dev)
58{
59 memset(dev, 0, sizeof(*dev));
60
61 link_initialize(&dev->link);
62 list_initialize(&dev->devices);
63 fibril_mutex_initialize(&dev->guard);
64
65 return EOK;
66}
67
[56db65d]68int bus_add_ep(bus_t *bus, device_t *device, const usb_endpoint_desc_t *desc)
[20eaa82]69{
70 assert(bus);
71 assert(device);
72
73 /* Temporary reference */
74 endpoint_t *ep = bus_create_endpoint(bus);
75 if (!ep)
76 return ENOMEM;
77
78 ep->device = device;
[56db65d]79 const int err = bus_register_endpoint(bus, ep, desc);
[20eaa82]80
81 /* drop Temporary reference */
82 endpoint_del_ref(ep);
83
84 return err;
85}
86
[327f147]87int bus_remove_ep(bus_t *bus, device_t *dev, usb_target_t target, usb_direction_t dir)
[20eaa82]88{
89 assert(bus);
[327f147]90 endpoint_t *ep = bus_find_endpoint(bus, dev, target, dir);
[20eaa82]91 if (!ep)
92 return ENOENT;
93
[ee794529]94 return bus_unregister_endpoint(bus, ep);
[20eaa82]95}
96
97int device_set_default_name(device_t *dev)
98{
99 assert(dev);
100 assert(dev->fun);
101
102 char buf[10] = { 0 }; /* usbxyz-ss */
103 snprintf(buf, sizeof(buf) - 1, "usb%u-%cs",
104 dev->address, usb_str_speed(dev->speed)[0]);
105
106 return ddf_fun_set_name(dev->fun, buf);
107}
108
109int bus_enumerate_device(bus_t *bus, hcd_t *hcd, device_t *dev)
110{
111 assert(bus);
112 assert(hcd);
113 assert(dev);
114
115 if (!bus->ops.enumerate_device)
116 return ENOTSUP;
117
118 fibril_mutex_lock(&bus->guard);
119 const int r = bus->ops.enumerate_device(bus, hcd, dev);
120 fibril_mutex_unlock(&bus->guard);
121 return r;
122}
123
124int bus_remove_device(bus_t *bus, hcd_t *hcd, device_t *dev)
125{
126 assert(bus);
127 assert(dev);
128
129 if (!bus->ops.remove_device)
130 return ENOTSUP;
131
132 fibril_mutex_lock(&bus->guard);
133 const int r = bus->ops.remove_device(bus, hcd, dev);
134 fibril_mutex_unlock(&bus->guard);
135 return r;
[41924f30]136}
137
138endpoint_t *bus_create_endpoint(bus_t *bus)
139{
140 assert(bus);
141
142 fibril_mutex_lock(&bus->guard);
143 endpoint_t *ep = bus->ops.create_endpoint(bus);
144 if (ep) {
145 /* Exporting reference */
146 endpoint_add_ref(ep);
147 }
148 fibril_mutex_unlock(&bus->guard);
149
150 return ep;
151}
152
[56db65d]153int bus_register_endpoint(bus_t *bus, endpoint_t *ep, const usb_endpoint_desc_t *desc)
[41924f30]154{
155 assert(bus);
156 assert(ep);
157
158 /* Bus reference */
159 endpoint_add_ref(ep);
160
161 fibril_mutex_lock(&bus->guard);
[56db65d]162 const int r = bus->ops.register_endpoint(bus, ep, desc);
[41924f30]163 fibril_mutex_unlock(&bus->guard);
164
165 return r;
166}
167
[ee794529]168int bus_unregister_endpoint(bus_t *bus, endpoint_t *ep)
[41924f30]169{
170 assert(bus);
171 assert(ep);
172
173 fibril_mutex_lock(&bus->guard);
[ee794529]174 const int r = bus->ops.unregister_endpoint(bus, ep);
[41924f30]175 fibril_mutex_unlock(&bus->guard);
176
[4594baa]177 if (r)
178 return r;
179
[41924f30]180 /* Bus reference */
181 endpoint_del_ref(ep);
182
183 return EOK;
184}
185
186/** Searches for an endpoint. Returns a reference.
187 */
[327f147]188endpoint_t *bus_find_endpoint(bus_t *bus, device_t *device, usb_target_t endpoint, usb_direction_t dir)
[41924f30]189{
190 assert(bus);
191
192 fibril_mutex_lock(&bus->guard);
[327f147]193 endpoint_t *ep = bus->ops.find_endpoint(bus, device, endpoint, dir);
[41924f30]194 if (ep) {
195 /* Exporting reference */
196 endpoint_add_ref(ep);
197 }
198
199 fibril_mutex_unlock(&bus->guard);
200 return ep;
201}
202
203int bus_request_address(bus_t *bus, usb_address_t *hint, bool strict, usb_speed_t speed)
204{
205 assert(bus);
206
207 if (!bus->ops.request_address)
208 return ENOTSUP;
209
210 fibril_mutex_lock(&bus->guard);
211 const int r = bus->ops.request_address(bus, hint, strict, speed);
212 fibril_mutex_unlock(&bus->guard);
213 return r;
214}
215
216int bus_release_address(bus_t *bus, usb_address_t address)
217{
218 assert(bus);
219
220 if (!bus->ops.release_address)
221 return ENOTSUP;
222
223 fibril_mutex_lock(&bus->guard);
224 const int r = bus->ops.release_address(bus, address);
225 fibril_mutex_unlock(&bus->guard);
226 return r;
227}
228
229int bus_reset_toggle(bus_t *bus, usb_target_t target, bool all)
230{
231 assert(bus);
232
233 if (!bus->ops.reset_toggle)
234 return ENOTSUP;
235
236 fibril_mutex_lock(&bus->guard);
237 const int r = bus->ops.reset_toggle(bus, target, all);
238 fibril_mutex_unlock(&bus->guard);
239 return r;
240}
241
242size_t bus_count_bw(endpoint_t *ep, size_t size)
243{
244 assert(ep);
245
246 fibril_mutex_lock(&ep->guard);
247 const size_t bw = ep->bus->ops.count_bw(ep, size);
248 fibril_mutex_unlock(&ep->guard);
249 return bw;
250}
251
252/**
253 * @}
254 */
Note: See TracBrowser for help on using the repository browser.