source: mainline/uspace/lib/usbhost/src/iface.c@ d9b2c73

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

libusbhost: Add hcd parameter to batch scheduling and move implementaiotn to hcd.c

  • Property mode set to 100644
File size: 8.7 KB
Line 
1/*
2 * Copyright (c) 2011 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 libusbhost
30 * @{
31 */
32/** @file
33 * @brief HCD DDF interface implementation
34 */
35
36#include <ddf/driver.h>
37#include <errno.h>
38
39#include <usb/debug.h>
40#include <usb/host/endpoint.h>
41#include <usb/host/hcd.h>
42
43/** Calls ep_add_hook upon endpoint registration.
44 * @param ep Endpoint to be registered.
45 * @param arg hcd_t in disguise.
46 * @return Error code.
47 */
48static int register_helper(endpoint_t *ep, void *arg)
49{
50 hcd_t *hcd = arg;
51 assert(ep);
52 assert(hcd);
53 if (hcd->ep_add_hook)
54 return hcd->ep_add_hook(hcd, ep);
55 return EOK;
56}
57
58/** Calls ep_remove_hook upon endpoint removal.
59 * @param ep Endpoint to be unregistered.
60 * @param arg hcd_t in disguise.
61 */
62static void unregister_helper(endpoint_t *ep, void *arg)
63{
64 hcd_t *hcd = arg;
65 assert(ep);
66 assert(hcd);
67 if (hcd->ep_remove_hook)
68 hcd->ep_remove_hook(hcd, ep);
69}
70
71/** Calls ep_remove_hook upon endpoint removal. Prints warning.
72 * @param ep Endpoint to be unregistered.
73 * @param arg hcd_t in disguise.
74 */
75static void unregister_helper_warn(endpoint_t *ep, void *arg)
76{
77 hcd_t *hcd = arg;
78 assert(ep);
79 assert(hcd);
80 usb_log_warning("Endpoint %d:%d %s was left behind, removing.\n",
81 ep->address, ep->endpoint, usb_str_direction(ep->direction));
82 if (hcd->ep_remove_hook)
83 hcd->ep_remove_hook(hcd, ep);
84}
85
86/** Request address interface function.
87 *
88 * @param[in] fun DDF function that was called.
89 * @param[in] address Pointer to preferred USB address.
90 * @param[out] address Place to write a new address.
91 * @param[in] strict Fail if the preferred address is not available.
92 * @param[in] speed Speed to associate with the new default address.
93 * @return Error code.
94 */
95static int request_address(
96 ddf_fun_t *fun, usb_address_t *address, bool strict, usb_speed_t speed)
97{
98 assert(fun);
99 hcd_t *hcd = fun_to_hcd(fun);
100 assert(hcd);
101 assert(address);
102
103 usb_log_debug("Address request: speed: %s, address: %d, strict: %s.\n",
104 usb_str_speed(speed), *address, strict ? "YES" : "NO");
105 return usb_device_manager_request_address(
106 &hcd->dev_manager, address, strict, speed);
107}
108
109/** Bind address interface function.
110 *
111 * @param[in] fun DDF function that was called.
112 * @param[in] address Address of the device
113 * @param[in] handle Devman handle of the device driver.
114 * @return Error code.
115 */
116static int bind_address(
117 ddf_fun_t *fun, usb_address_t address, devman_handle_t handle)
118{
119 assert(fun);
120 hcd_t *hcd = fun_to_hcd(fun);
121 assert(hcd);
122
123 usb_log_debug("Address bind %d-%" PRIun ".\n", address, handle);
124 return usb_device_manager_bind_address(
125 &hcd->dev_manager, address, handle);
126}
127
128/** Find device handle by address interface function.
129 *
130 * @param[in] fun DDF function that was called.
131 * @param[in] address Address in question.
132 * @param[out] handle Where to store device handle if found.
133 * @return Error code.
134 */
135static int find_by_address(ddf_fun_t *fun, usb_address_t address,
136 devman_handle_t *handle)
137{
138 assert(fun);
139 hcd_t *hcd = fun_to_hcd(fun);
140 assert(hcd);
141 return usb_device_manager_get_info_by_address(
142 &hcd->dev_manager, address, handle, NULL);
143}
144
145/** Release address interface function.
146 *
147 * @param[in] fun DDF function that was called.
148 * @param[in] address USB address to be released.
149 * @return Error code.
150 */
151static int release_address(ddf_fun_t *fun, usb_address_t address)
152{
153 assert(fun);
154 hcd_t *hcd = fun_to_hcd(fun);
155 assert(hcd);
156 usb_log_debug("Address release %d.\n", address);
157 usb_endpoint_manager_remove_address(&hcd->ep_manager, address,
158 unregister_helper_warn, hcd);
159 usb_device_manager_release_address(&hcd->dev_manager, address);
160 return EOK;
161}
162
163/** Register endpoint interface function.
164 * @param fun DDF function.
165 * @param address USB address of the device.
166 * @param endpoint USB endpoint number to be registered.
167 * @param transfer_type Endpoint's transfer type.
168 * @param direction USB communication direction the endpoint is capable of.
169 * @param max_packet_size Maximu size of packets the endpoint accepts.
170 * @param interval Preferred timeout between communication.
171 * @return Error code.
172 */
173static int register_endpoint(
174 ddf_fun_t *fun, usb_address_t address, usb_endpoint_t endpoint,
175 usb_transfer_type_t transfer_type, usb_direction_t direction,
176 size_t max_packet_size, unsigned interval)
177{
178 assert(fun);
179 hcd_t *hcd = fun_to_hcd(fun);
180 assert(hcd);
181 const size_t size = max_packet_size;
182 usb_speed_t speed = USB_SPEED_MAX;
183 const int ret = usb_device_manager_get_info_by_address(
184 &hcd->dev_manager, address, NULL, &speed);
185 if (ret != EOK) {
186 return ret;
187 }
188
189 usb_log_debug("Register endpoint %d:%d %s-%s %s %zuB %ums.\n",
190 address, endpoint, usb_str_transfer_type(transfer_type),
191 usb_str_direction(direction), usb_str_speed(speed),
192 max_packet_size, interval);
193
194 return usb_endpoint_manager_add_ep(&hcd->ep_manager, address, endpoint,
195 direction, transfer_type, speed, max_packet_size, size,
196 register_helper, hcd);
197}
198
199/** Unregister endpoint interface function.
200 * @param fun DDF function.
201 * @param address USB address of the endpoint.
202 * @param endpoint USB endpoint number.
203 * @param direction Communication direction of the enpdoint to unregister.
204 * @return Error code.
205 */
206static int unregister_endpoint(
207 ddf_fun_t *fun, usb_address_t address,
208 usb_endpoint_t endpoint, usb_direction_t direction)
209{
210 assert(fun);
211 hcd_t *hcd = fun_to_hcd(fun);
212 assert(hcd);
213 usb_log_debug("Unregister endpoint %d:%d %s.\n",
214 address, endpoint, usb_str_direction(direction));
215 return usb_endpoint_manager_remove_ep(&hcd->ep_manager, address,
216 endpoint, direction, unregister_helper, hcd);
217}
218
219/** Inbound communication interface function.
220 * @param fun DDF function.
221 * @param target Communication target.
222 * @param setup_data Data to use in setup stage (control transfers).
223 * @param data Pointer to data buffer.
224 * @param size Size of the data buffer.
225 * @param callback Function to call on communication end.
226 * @param arg Argument passed to the callback function.
227 * @return Error code.
228 */
229static int usb_read(ddf_fun_t *fun, usb_target_t target, uint64_t setup_data,
230 uint8_t *data, size_t size, usbhc_iface_transfer_in_callback_t callback,
231 void *arg)
232{
233 return hcd_send_batch(fun_to_hcd(fun), fun, target, USB_DIRECTION_IN,
234 data, size, setup_data, callback, NULL, arg, "READ");
235}
236
237/** Outbound communication interface function.
238 * @param fun DDF function.
239 * @param target Communication target.
240 * @param setup_data Data to use in setup stage (control transfers).
241 * @param data Pointer to data buffer.
242 * @param size Size of the data buffer.
243 * @param callback Function to call on communication end.
244 * @param arg Argument passed to the callback function.
245 * @return Error code.
246 */
247static int usb_write(ddf_fun_t *fun, usb_target_t target, uint64_t setup_data,
248 const uint8_t *data, size_t size,
249 usbhc_iface_transfer_out_callback_t callback, void *arg)
250{
251 return hcd_send_batch(fun_to_hcd(fun), fun, target, USB_DIRECTION_OUT,
252 (uint8_t*)data, size, setup_data, NULL, callback, arg, "WRITE");
253}
254
255/** usbhc Interface implementation using hcd_t from libusbhost library. */
256usbhc_iface_t hcd_iface = {
257 .request_address = request_address,
258 .bind_address = bind_address,
259 .get_handle = find_by_address,
260 .release_address = release_address,
261
262 .register_endpoint = register_endpoint,
263 .unregister_endpoint = unregister_endpoint,
264
265 .read = usb_read,
266 .write = usb_write,
267};
268
269/**
270 * @}
271 */
Note: See TracBrowser for help on using the repository browser.