source: mainline/uspace/lib/usb/src/hc.c@ 083adbc

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 083adbc was e8f826b, checked in by Vojtech Horky <vojtechhorky@…>, 15 years ago

Merged headers in libusb

  • Property mode set to 100644
File size: 6.5 KB
Line 
1/*
2 * Copyright (c) 2011 Vojtech Horky
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 libusb
30 * @{
31 */
32/** @file
33 * General communication with host controller driver (implementation).
34 */
35#include <devman.h>
36#include <async.h>
37#include <dev_iface.h>
38#include <usb_iface.h>
39#include <usbhc_iface.h>
40#include <usb/hc.h>
41#include <usb/debug.h>
42#include <errno.h>
43#include <assert.h>
44
45/** Initialize connection to USB host controller.
46 *
47 * @param connection Connection to be initialized.
48 * @param device Device connecting to the host controller.
49 * @return Error code.
50 */
51int usb_hc_connection_initialize_from_device(usb_hc_connection_t *connection,
52 ddf_dev_t *device)
53{
54 assert(connection);
55
56 if (device == NULL) {
57 return EBADMEM;
58 }
59
60 devman_handle_t hc_handle;
61 int rc = usb_hc_find(device->handle, &hc_handle);
62 if (rc != EOK) {
63 return rc;
64 }
65
66 rc = usb_hc_connection_initialize(connection, hc_handle);
67
68 return rc;
69}
70
71/** Manually initialize connection to USB host controller.
72 *
73 * @param connection Connection to be initialized.
74 * @param hc_handle Devman handle of the host controller.
75 * @return Error code.
76 */
77int usb_hc_connection_initialize(usb_hc_connection_t *connection,
78 devman_handle_t hc_handle)
79{
80 assert(connection);
81
82 connection->hc_handle = hc_handle;
83 connection->hc_phone = -1;
84
85 return EOK;
86}
87
88/** Open connection to host controller.
89 *
90 * @param connection Connection to the host controller.
91 * @return Error code.
92 */
93int usb_hc_connection_open(usb_hc_connection_t *connection)
94{
95 assert(connection);
96
97 if (usb_hc_connection_is_opened(connection)) {
98 return EBUSY;
99 }
100
101 int phone = devman_device_connect(connection->hc_handle, 0);
102 if (phone < 0) {
103 return phone;
104 }
105
106 connection->hc_phone = phone;
107
108 return EOK;
109}
110
111/** Tells whether connection to host controller is opened.
112 *
113 * @param connection Connection to the host controller.
114 * @return Whether connection is opened.
115 */
116bool usb_hc_connection_is_opened(const usb_hc_connection_t *connection)
117{
118 assert(connection);
119
120 return (connection->hc_phone >= 0);
121}
122
123/** Close connection to the host controller.
124 *
125 * @param connection Connection to the host controller.
126 * @return Error code.
127 */
128int usb_hc_connection_close(usb_hc_connection_t *connection)
129{
130 assert(connection);
131
132 if (!usb_hc_connection_is_opened(connection)) {
133 return ENOENT;
134 }
135
136 int rc = async_hangup(connection->hc_phone);
137 if (rc != EOK) {
138 return rc;
139 }
140
141 connection->hc_phone = -1;
142
143 return EOK;
144}
145
146/** Get handle of USB device with given address.
147 *
148 * @param[in] connection Opened connection to host controller.
149 * @param[in] address Address of device in question.
150 * @param[out] handle Where to write the device handle.
151 * @return Error code.
152 */
153int usb_hc_get_handle_by_address(usb_hc_connection_t *connection,
154 usb_address_t address, devman_handle_t *handle)
155{
156 if (!usb_hc_connection_is_opened(connection)) {
157 return ENOENT;
158 }
159
160 sysarg_t tmp;
161 int rc = async_req_2_1(connection->hc_phone,
162 DEV_IFACE_ID(USBHC_DEV_IFACE),
163 IPC_M_USBHC_GET_HANDLE_BY_ADDRESS,
164 address, &tmp);
165 if ((rc == EOK) && (handle != NULL)) {
166 *handle = tmp;
167 }
168
169 return rc;
170}
171
172/** Tell USB address assigned to device with given handle.
173 *
174 * @param dev_handle Devman handle of the USB device in question.
175 * @return USB address or negative error code.
176 */
177usb_address_t usb_hc_get_address_by_handle(devman_handle_t dev_handle)
178{
179 int parent_phone = devman_parent_device_connect(dev_handle,
180 IPC_FLAG_BLOCKING);
181 if (parent_phone < 0) {
182 return parent_phone;
183 }
184
185 sysarg_t address;
186
187 int rc = async_req_2_1(parent_phone, DEV_IFACE_ID(USB_DEV_IFACE),
188 IPC_M_USB_GET_ADDRESS,
189 dev_handle, &address);
190
191 if (rc != EOK) {
192 return rc;
193 }
194
195 async_hangup(parent_phone);
196
197 return (usb_address_t) address;
198}
199
200
201/** Get host controller handle by its class index.
202 *
203 * @param class_index Class index for the host controller.
204 * @param hc_handle Where to store the HC handle
205 * (can be NULL for existence test only).
206 * @return Error code.
207 */
208int usb_ddf_get_hc_handle_by_class(size_t class_index,
209 devman_handle_t *hc_handle)
210{
211 char *class_index_str;
212 devman_handle_t hc_handle_tmp;
213 int rc;
214
215 rc = asprintf(&class_index_str, "%zu", class_index);
216 if (rc < 0) {
217 return ENOMEM;
218 }
219 rc = devman_device_get_handle_by_class("usbhc", class_index_str,
220 &hc_handle_tmp, 0);
221 free(class_index_str);
222 if (rc != EOK) {
223 return rc;
224 }
225
226 if (hc_handle != NULL) {
227 *hc_handle = hc_handle_tmp;
228 }
229
230 return EOK;
231}
232
233/** Find host controller handle that is ancestor of given device.
234 *
235 * @param[in] device_handle Device devman handle.
236 * @param[out] hc_handle Where to store handle of host controller
237 * controlling device with @p device_handle handle.
238 * @return Error code.
239 */
240int usb_hc_find(devman_handle_t device_handle, devman_handle_t *hc_handle)
241{
242 int parent_phone = devman_parent_device_connect(device_handle,
243 IPC_FLAG_BLOCKING);
244 if (parent_phone < 0) {
245 return parent_phone;
246 }
247
248 devman_handle_t h;
249 int rc = async_req_1_1(parent_phone, DEV_IFACE_ID(USB_DEV_IFACE),
250 IPC_M_USB_GET_HOST_CONTROLLER_HANDLE, &h);
251
252 async_hangup(parent_phone);
253
254 if (rc != EOK) {
255 return rc;
256 }
257
258 if (hc_handle != NULL) {
259 *hc_handle = h;
260 }
261
262 return EOK;
263}
264
265/**
266 * @}
267 */
Note: See TracBrowser for help on using the repository browser.