source: mainline/uspace/lib/usb/src/hc.c@ 7aaed09

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

usbhc: Export IPC wrapper instead of IPC call numbers.

Hide IPC protocol in one file, instead of multiple client implementations.
Rename 'find_by_address' ⇒ 'get_handle'

  • Property mode set to 100644
File size: 6.3 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 const 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_sess = NULL;
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 async_sess_t *sess = devman_device_connect(EXCHANGE_ATOMIC,
101 connection->hc_handle, 0);
102 if (!sess)
103 return ENOMEM;
104
105 connection->hc_sess = sess;
106 return EOK;
107}
108
109/** Tells whether connection to host controller is opened.
110 *
111 * @param connection Connection to the host controller.
112 * @return Whether connection is opened.
113 */
114bool usb_hc_connection_is_opened(const usb_hc_connection_t *connection)
115{
116 assert(connection);
117 return (connection->hc_sess != NULL);
118}
119
120/** Close connection to the host controller.
121 *
122 * @param connection Connection to the host controller.
123 * @return Error code.
124 */
125int usb_hc_connection_close(usb_hc_connection_t *connection)
126{
127 assert(connection);
128
129 if (!usb_hc_connection_is_opened(connection)) {
130 return ENOENT;
131 }
132
133 int rc = async_hangup(connection->hc_sess);
134 if (rc != EOK) {
135 return rc;
136 }
137
138 connection->hc_sess = NULL;
139
140 return EOK;
141}
142
143/** Get handle of USB device with given address.
144 *
145 * @param[in] connection Opened connection to host controller.
146 * @param[in] address Address of device in question.
147 * @param[out] handle Where to write the device handle.
148 * @return Error code.
149 */
150int usb_hc_get_handle_by_address(usb_hc_connection_t *connection,
151 usb_address_t address, devman_handle_t *handle)
152{
153 if (!usb_hc_connection_is_opened(connection))
154 return ENOENT;
155
156 async_exch_t *exch = async_exchange_begin(connection->hc_sess);
157 if (!exch)
158 return ENOMEM;
159 const int ret = usbhc_get_handle(exch, address, handle);
160 async_exchange_end(exch);
161 return ret;
162}
163
164/** Tell USB address assigned to device with given handle.
165 *
166 * @param dev_handle Devman handle of the USB device in question.
167 * @return USB address or negative error code.
168 */
169usb_address_t usb_get_address_by_handle(devman_handle_t dev_handle)
170{
171 async_sess_t *parent_sess =
172 devman_parent_device_connect(EXCHANGE_ATOMIC, dev_handle,
173 IPC_FLAG_BLOCKING);
174 if (!parent_sess)
175 return ENOMEM;
176
177 async_exch_t *exch = async_exchange_begin(parent_sess);
178 if (!exch) {
179 async_hangup(parent_sess);
180 return ENOMEM;
181 }
182 usb_address_t address;
183 const int ret = usb_get_my_address(exch, &address);
184
185 async_exchange_end(exch);
186 async_hangup(parent_sess);
187
188 if (ret != EOK)
189 return ret;
190
191 return address;
192}
193
194
195/** Get host controller handle by its class index.
196 *
197 * @param sid Service ID of the HC function.
198 * @param hc_handle Where to store the HC handle
199 * (can be NULL for existence test only).
200 * @return Error code.
201 */
202int usb_ddf_get_hc_handle_by_sid(service_id_t sid, devman_handle_t *hc_handle)
203{
204 devman_handle_t handle;
205 int rc;
206
207 rc = devman_fun_sid_to_handle(sid, &handle);
208 if (hc_handle != NULL)
209 *hc_handle = handle;
210
211 return rc;
212}
213
214/** Find host controller handle that is ancestor of given device.
215 *
216 * @param[in] device_handle Device devman handle.
217 * @param[out] hc_handle Where to store handle of host controller
218 * controlling device with @p device_handle handle.
219 * @return Error code.
220 */
221int usb_hc_find(devman_handle_t device_handle, devman_handle_t *hc_handle)
222{
223 async_sess_t *parent_sess =
224 devman_parent_device_connect(EXCHANGE_ATOMIC, device_handle,
225 IPC_FLAG_BLOCKING);
226 if (!parent_sess)
227 return ENOMEM;
228
229 async_exch_t *exch = async_exchange_begin(parent_sess);
230 if (!exch) {
231 async_hangup(parent_sess);
232 return ENOMEM;
233 }
234 const int ret = usb_get_hc_handle(exch, hc_handle);
235
236 async_exchange_end(exch);
237 async_hangup(parent_sess);
238
239 return ret;
240}
241
242/**
243 * @}
244 */
Note: See TracBrowser for help on using the repository browser.