source: mainline/uspace/lib/usb/src/pipes.c@ 2ef036a

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

Add function for getting USB address of a device

  • Property mode set to 100644
File size: 7.2 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 * USB endpoint pipes miscellaneous functions.
34 */
35#include <usb/usb.h>
36#include <usb/pipes.h>
37#include <usb/debug.h>
38#include <usbhc_iface.h>
39#include <usb_iface.h>
40#include <devman.h>
41#include <errno.h>
42#include <assert.h>
43
44/** Tell USB address assigned to given device.
45 *
46 * @param phone Phone to parent device.
47 * @param dev Device in question.
48 * @return USB address or error code.
49 */
50static usb_address_t get_my_address(int phone, ddf_dev_t *dev)
51{
52 sysarg_t address;
53
54 /*
55 * We are sending special value as a handle - zero - to get
56 * handle of the parent function (that handle was used
57 * when registering our device @p dev.
58 */
59 int rc = async_req_2_1(phone, DEV_IFACE_ID(USB_DEV_IFACE),
60 IPC_M_USB_GET_ADDRESS,
61 0, &address);
62
63 if (rc != EOK) {
64 return rc;
65 }
66
67 return (usb_address_t) address;
68}
69
70/** Tell USB interface assigned to given device.
71 *
72 * @param device Device in question.
73 * @return Interface number (negative code means any).
74 */
75int usb_device_get_assigned_interface(ddf_dev_t *device)
76{
77 int parent_phone = devman_parent_device_connect(device->handle,
78 IPC_FLAG_BLOCKING);
79 if (parent_phone < 0) {
80 return -1;
81 }
82
83 sysarg_t iface_no;
84 int rc = async_req_2_1(parent_phone, DEV_IFACE_ID(USB_DEV_IFACE),
85 IPC_M_USB_GET_INTERFACE,
86 device->handle, &iface_no);
87
88 async_hangup(parent_phone);
89
90 if (rc != EOK) {
91 return -1;
92 }
93
94 return (int) iface_no;
95}
96
97/** Tell USB address assigned to given device.
98 *
99 * @param dev_handle Devman handle of the USB device in question.
100 * @return USB address or negative error code.
101 */
102usb_address_t usb_device_get_assigned_address(devman_handle_t dev_handle)
103{
104 int parent_phone = devman_parent_device_connect(dev_handle,
105 IPC_FLAG_BLOCKING);
106 if (parent_phone < 0) {
107 return parent_phone;
108 }
109
110 sysarg_t address;
111
112 int rc = async_req_2_1(parent_phone, DEV_IFACE_ID(USB_DEV_IFACE),
113 IPC_M_USB_GET_ADDRESS,
114 dev_handle, &address);
115
116 if (rc != EOK) {
117 return rc;
118 }
119
120 async_hangup(parent_phone);
121
122 return (usb_address_t) address;
123}
124
125/** Initialize connection to USB device.
126 *
127 * @param connection Connection structure to be initialized.
128 * @param dev Generic device backing the USB device.
129 * @return Error code.
130 */
131int usb_device_connection_initialize_from_device(
132 usb_device_connection_t *connection, ddf_dev_t *dev)
133{
134 assert(connection);
135 assert(dev);
136
137 int rc;
138 devman_handle_t hc_handle;
139 usb_address_t my_address;
140
141 rc = usb_hc_find(dev->handle, &hc_handle);
142 if (rc != EOK) {
143 return rc;
144 }
145
146 int parent_phone = devman_parent_device_connect(dev->handle,
147 IPC_FLAG_BLOCKING);
148 if (parent_phone < 0) {
149 return parent_phone;
150 }
151
152 my_address = get_my_address(parent_phone, dev);
153 if (my_address < 0) {
154 rc = my_address;
155 goto leave;
156 }
157
158 rc = usb_device_connection_initialize(connection,
159 hc_handle, my_address);
160
161leave:
162 async_hangup(parent_phone);
163 return rc;
164}
165
166/** Initialize connection to USB device.
167 *
168 * @param connection Connection structure to be initialized.
169 * @param host_controller_handle Devman handle of host controller device is
170 * connected to.
171 * @param device_address Device USB address.
172 * @return Error code.
173 */
174int usb_device_connection_initialize(usb_device_connection_t *connection,
175 devman_handle_t host_controller_handle, usb_address_t device_address)
176{
177 assert(connection);
178
179 if ((device_address < 0) || (device_address >= USB11_ADDRESS_MAX)) {
180 return EINVAL;
181 }
182
183 connection->hc_handle = host_controller_handle;
184 connection->address = device_address;
185
186 return EOK;
187}
188
189/** Initialize connection to USB device on default address.
190 *
191 * @param dev_connection Device connection structure to be initialized.
192 * @param hc_connection Initialized connection to host controller.
193 * @return Error code.
194 */
195int usb_device_connection_initialize_on_default_address(
196 usb_device_connection_t *dev_connection,
197 usb_hc_connection_t *hc_connection)
198{
199 assert(dev_connection);
200
201 if (hc_connection == NULL) {
202 return EBADMEM;
203 }
204
205 return usb_device_connection_initialize(dev_connection,
206 hc_connection->hc_handle, (usb_address_t) 0);
207}
208
209
210/** Start a session on the endpoint pipe.
211 *
212 * A session is something inside what any communication occurs.
213 * It is expected that sessions would be started right before the transfer
214 * and ended - see usb_endpoint_pipe_end_session() - after the last
215 * transfer.
216 * The reason for this is that session actually opens some communication
217 * channel to the host controller (or to the physical hardware if you
218 * wish) and thus it involves acquiring kernel resources.
219 * Since they are limited, sessions shall not be longer than strictly
220 * necessary.
221 *
222 * @param pipe Endpoint pipe to start the session on.
223 * @return Error code.
224 */
225int usb_endpoint_pipe_start_session(usb_endpoint_pipe_t *pipe)
226{
227 assert(pipe);
228
229 if (usb_endpoint_pipe_is_session_started(pipe)) {
230 return EBUSY;
231 }
232
233 int phone = devman_device_connect(pipe->wire->hc_handle, 0);
234 if (phone < 0) {
235 return phone;
236 }
237
238 pipe->hc_phone = phone;
239
240 return EOK;
241}
242
243
244/** Ends a session on the endpoint pipe.
245 *
246 * @see usb_endpoint_pipe_start_session
247 *
248 * @param pipe Endpoint pipe to end the session on.
249 * @return Error code.
250 */
251int usb_endpoint_pipe_end_session(usb_endpoint_pipe_t *pipe)
252{
253 assert(pipe);
254
255 if (!usb_endpoint_pipe_is_session_started(pipe)) {
256 return ENOENT;
257 }
258
259 int rc = async_hangup(pipe->hc_phone);
260 if (rc != EOK) {
261 return rc;
262 }
263
264 pipe->hc_phone = -1;
265
266 return EOK;
267}
268
269/** Tell whether a session is started (open) on the endpoint pipe.
270 *
271 * The expected usage of this function is in assertions for some
272 * nested functions.
273 *
274 * @param pipe Endpoint pipe in question.
275 * @return Whether @p pipe has opened a session.
276 */
277bool usb_endpoint_pipe_is_session_started(usb_endpoint_pipe_t *pipe)
278{
279 return (pipe->hc_phone >= 0);
280}
281
282/**
283 * @}
284 */
Note: See TracBrowser for help on using the repository browser.