source: mainline/uspace/lib/usbhost/src/bus.c@ 3cbc138

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

Moving things around to improve isolation of responsibilities

Bus interface was simplified, xHCI implementation of address_device was spread into stack of rh → bus → hc and back.

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