source: mainline/uspace/lib/usbhost/src/bus.c@ 820d9bc

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

usbhost: refactor include hiearchy

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