Changeset 50ba203 in mainline for uspace/lib
- Timestamp:
- 2011-02-20T15:46:48Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 6bb83c7
- Parents:
- d81ef61c (diff), 0c00dac (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)links above to see all the changes relative to each parent. - Location:
- uspace/lib
- Files:
-
- 6 added
- 5 deleted
- 20 edited
- 1 moved
-
c/generic/async.c (modified) (1 diff)
-
c/generic/str_error.c (modified) (2 diffs)
-
c/include/async.h (modified) (1 diff)
-
c/include/errno.h (modified) (1 diff)
-
drv/generic/remote_usbhc.c (modified) (22 diffs)
-
drv/include/usbhc_iface.h (modified) (6 diffs)
-
usb/Makefile (modified) (1 diff)
-
usb/include/usb/addrkeep.h (modified) (1 diff, 1 prop)
-
usb/include/usb/classes/hid.h (modified) (1 diff)
-
usb/include/usb/classes/hub.h (modified) (3 diffs)
-
usb/include/usb/hcdhubd.h (deleted)
-
usb/include/usb/hub.h (moved) (moved from uspace/lib/usb/include/usb/hcd.h ) (2 diffs)
-
usb/include/usb/pipes.h (modified) (6 diffs)
-
usb/include/usb/recognise.h (added)
-
usb/include/usb/usb.h (modified) (1 diff)
-
usb/include/usb/usbdevice.h (added)
-
usb/include/usb/usbdrv.h (modified) (1 diff)
-
usb/src/addrkeep.c (modified) (1 diff)
-
usb/src/dump.c (modified) (1 diff)
-
usb/src/hcdhubd.c (deleted)
-
usb/src/hcdrv.c (deleted)
-
usb/src/hub.c (added)
-
usb/src/localdrv.c (deleted)
-
usb/src/pipes.c (modified) (4 diffs)
-
usb/src/pipesinit.c (added)
-
usb/src/pipesio.c (added)
-
usb/src/recognise.c (modified) (15 diffs)
-
usb/src/remotedrv.c (deleted)
-
usb/src/usb.c (modified) (1 diff)
-
usb/src/usbdevice.c (added)
-
usb/src/usbdrv.c (modified) (11 diffs)
-
usbvirt/Makefile (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/async.c
rd81ef61c r50ba203 1567 1567 } 1568 1568 1569 /** Start IPC_M_DATA_READ using the async framework. 1570 * 1571 * @param phoneid Phone that will be used to contact the receiving side. 1572 * @param dst Address of the beginning of the destination buffer. 1573 * @param size Size of the destination buffer (in bytes). 1574 * @param dataptr Storage of call data (arg 2 holds actual data size). 1575 * @return Hash of the sent message or 0 on error. 1576 */ 1577 aid_t async_data_read(int phoneid, void *dst, size_t size, ipc_call_t *dataptr) 1578 { 1579 return async_send_2(phoneid, IPC_M_DATA_READ, (sysarg_t) dst, 1580 (sysarg_t) size, dataptr); 1581 } 1582 1569 1583 /** Wrapper for IPC_M_DATA_READ calls using the async framework. 1570 1584 * -
uspace/lib/c/generic/str_error.c
rd81ef61c r50ba203 33 33 */ 34 34 35 #include <errno.h> 35 36 #include <str_error.h> 36 37 #include <stdio.h> … … 63 64 static fibril_local char noerr[NOERR_LEN]; 64 65 65 const char *str_error(const int e rrno)66 const char *str_error(const int e) 66 67 { 67 if ((e rrno <= 0) && (errno>= MIN_ERRNO))68 return err_desc[-e rrno];68 if ((e <= 0) && (e >= MIN_ERRNO)) 69 return err_desc[-e]; 69 70 70 snprintf(noerr, NOERR_LEN, "Unkown error code %d", errno); 71 /* Ad hoc descriptions of error codes interesting for USB. */ 72 switch (e) { 73 case EBADCHECKSUM: 74 return "Bad checksum"; 75 case EAGAIN: 76 return "Resource temporarily unavailable"; 77 default: 78 break; 79 } 80 81 snprintf(noerr, NOERR_LEN, "Unkown error code %d", e); 71 82 return noerr; 72 83 } -
uspace/lib/c/include/async.h
rd81ef61c r50ba203 340 340 (arg4), (answer)) 341 341 342 extern aid_t async_data_read(int, void *, size_t, ipc_call_t *); 342 343 extern int async_data_read_start(int, void *, size_t); 343 344 extern bool async_data_read_receive(ipc_callid_t *, size_t *); -
uspace/lib/c/include/errno.h
rd81ef61c r50ba203 56 56 #define EMLINK (-266) 57 57 58 /** Bad checksum. */ 59 #define EBADCHECKSUM (-300) 60 58 61 /** An API function is called while another blocking function is in progress. */ 59 62 #define EINPROGRESS (-10036) -
uspace/lib/drv/generic/remote_usbhc.c
rd81ef61c r50ba203 40 40 41 41 #define USB_MAX_PAYLOAD_SIZE 1020 42 #define HACK_MAX_PACKET_SIZE 8 43 #define HACK_MAX_PACKET_SIZE_INTERRUPT_IN 4 42 44 43 45 static void remote_usbhc_get_address(device_t *, void *, ipc_callid_t, ipc_call_t *); 44 static void remote_usbhc_get_buffer(device_t *, void *, ipc_callid_t, ipc_call_t *);45 46 static void remote_usbhc_interrupt_out(device_t *, void *, ipc_callid_t, ipc_call_t *); 46 47 static void remote_usbhc_interrupt_in(device_t *, void *, ipc_callid_t, ipc_call_t *); … … 64 65 remote_usbhc_get_address, 65 66 66 remote_usbhc_get_buffer,67 68 67 remote_usbhc_reserve_default_address, 69 68 remote_usbhc_release_default_address, … … 98 97 typedef struct { 99 98 ipc_callid_t caller; 99 ipc_callid_t data_caller; 100 100 void *buffer; 101 101 void *setup_packet; … … 127 127 128 128 trans->caller = caller; 129 trans->data_caller = 0; 129 130 trans->buffer = NULL; 130 131 trans->setup_packet = NULL; … … 155 156 } 156 157 157 void remote_usbhc_get_buffer(device_t *device, void *iface,158 ipc_callid_t callid, ipc_call_t *call)159 {160 sysarg_t buffer_hash = DEV_IPC_GET_ARG1(*call);161 async_transaction_t * trans = (async_transaction_t *)buffer_hash;162 if (trans == NULL) {163 async_answer_0(callid, ENOENT);164 return;165 }166 if (trans->buffer == NULL) {167 async_answer_0(callid, EINVAL);168 async_transaction_destroy(trans);169 return;170 }171 172 ipc_callid_t cid;173 size_t accepted_size;174 if (!async_data_read_receive(&cid, &accepted_size)) {175 async_answer_0(callid, EINVAL);176 async_transaction_destroy(trans);177 return;178 }179 180 if (accepted_size > trans->size) {181 accepted_size = trans->size;182 }183 async_data_read_finalize(cid, trans->buffer, accepted_size);184 185 async_answer_1(callid, EOK, accepted_size);186 187 async_transaction_destroy(trans);188 }189 190 158 void remote_usbhc_reserve_default_address(device_t *device, void *iface, 191 159 ipc_callid_t callid, ipc_call_t *call) … … 197 165 return; 198 166 } 199 200 int rc = usb_iface->reserve_default_address(device); 167 168 bool full_speed = DEV_IPC_GET_ARG1(*call); 169 170 int rc = usb_iface->reserve_default_address(device, full_speed); 201 171 202 172 async_answer_0(callid, rc); … … 227 197 return; 228 198 } 199 200 bool full_speed = DEV_IPC_GET_ARG1(*call); 229 201 230 202 usb_address_t address; 231 int rc = usb_iface->request_address(device, &address);203 int rc = usb_iface->request_address(device, full_speed, &address); 232 204 if (rc != EOK) { 233 205 async_answer_0(callid, rc); … … 274 246 275 247 static void callback_out(device_t *device, 276 usb_transaction_outcome_t outcome, void *arg)248 int outcome, void *arg) 277 249 { 278 250 async_transaction_t *trans = (async_transaction_t *)arg; … … 284 256 285 257 static void callback_in(device_t *device, 286 usb_transaction_outcome_t outcome, size_t actual_size, void *arg)258 int outcome, size_t actual_size, void *arg) 287 259 { 288 260 async_transaction_t *trans = (async_transaction_t *)arg; 289 261 290 if (outcome != USB_OUTCOME_OK) {262 if (outcome != EOK) { 291 263 async_answer_0(trans->caller, outcome); 264 if (trans->data_caller) { 265 async_answer_0(trans->data_caller, EINTR); 266 } 292 267 async_transaction_destroy(trans); 293 268 return; … … 295 270 296 271 trans->size = actual_size; 297 async_answer_1(trans->caller, USB_OUTCOME_OK, (sysarg_t)trans); 272 273 if (trans->data_caller) { 274 async_data_read_finalize(trans->data_caller, 275 trans->buffer, actual_size); 276 } 277 278 async_answer_0(trans->caller, EOK); 279 280 async_transaction_destroy(trans); 298 281 } 299 282 … … 345 328 trans->size = len; 346 329 347 int rc = transfer_func(device, target, buffer, len, 330 int rc = transfer_func(device, target, HACK_MAX_PACKET_SIZE, 331 buffer, len, 348 332 callback_out, trans); 349 333 … … 376 360 }; 377 361 362 ipc_callid_t data_callid; 363 if (!async_data_read_receive(&data_callid, &len)) { 364 async_answer_0(callid, EPARTY); 365 return; 366 } 367 378 368 async_transaction_t *trans = async_transaction_create(callid); 379 369 if (trans == NULL) { … … 381 371 return; 382 372 } 373 trans->data_caller = data_callid; 383 374 trans->buffer = malloc(len); 384 375 trans->size = len; 385 376 386 int rc = transfer_func(device, target, trans->buffer, len, 377 int rc = transfer_func(device, target, HACK_MAX_PACKET_SIZE_INTERRUPT_IN, 378 trans->buffer, len, 387 379 callback_in, trans); 388 380 … … 556 548 .endpoint = DEV_IPC_GET_ARG2(*call) 557 549 }; 550 size_t data_buffer_len = DEV_IPC_GET_ARG3(*call); 558 551 559 552 int rc; … … 562 555 void *data_buffer = NULL; 563 556 size_t setup_packet_len = 0; 564 size_t data_buffer_len = 0;565 557 566 558 rc = async_data_write_accept(&setup_packet, false, … … 570 562 return; 571 563 } 572 rc = async_data_write_accept(&data_buffer, false, 573 1, USB_MAX_PAYLOAD_SIZE, 0, &data_buffer_len); 574 if (rc != EOK) { 575 async_answer_0(callid, rc); 576 free(setup_packet); 577 return; 564 565 if (data_buffer_len > 0) { 566 rc = async_data_write_accept(&data_buffer, false, 567 1, USB_MAX_PAYLOAD_SIZE, 0, &data_buffer_len); 568 if (rc != EOK) { 569 async_answer_0(callid, rc); 570 free(setup_packet); 571 return; 572 } 578 573 } 579 574 … … 589 584 trans->size = data_buffer_len; 590 585 591 rc = usb_iface->control_write(device, target, 586 rc = usb_iface->control_write(device, target, HACK_MAX_PACKET_SIZE, 592 587 setup_packet, setup_packet_len, 593 588 data_buffer, data_buffer_len, … … 612 607 } 613 608 614 size_t data_len = DEV_IPC_GET_ARG3(*call);615 609 usb_target_t target = { 616 610 .address = DEV_IPC_GET_ARG1(*call), … … 622 616 void *setup_packet = NULL; 623 617 size_t setup_packet_len = 0; 618 size_t data_len = 0; 624 619 625 620 rc = async_data_write_accept(&setup_packet, false, … … 627 622 if (rc != EOK) { 628 623 async_answer_0(callid, rc); 624 return; 625 } 626 627 ipc_callid_t data_callid; 628 if (!async_data_read_receive(&data_callid, &data_len)) { 629 async_answer_0(callid, EPARTY); 630 free(setup_packet); 629 631 return; 630 632 } … … 636 638 return; 637 639 } 640 trans->data_caller = data_callid; 638 641 trans->setup_packet = setup_packet; 639 642 trans->size = data_len; … … 645 648 } 646 649 647 rc = usb_iface->control_read(device, target, 650 rc = usb_iface->control_read(device, target, HACK_MAX_PACKET_SIZE, 648 651 setup_packet, setup_packet_len, 649 652 trans->buffer, trans->size, -
uspace/lib/drv/include/usbhc_iface.h
rd81ef61c r50ba203 40 40 #include "driver.h" 41 41 #include <usb/usb.h> 42 #include <bool.h> 42 43 43 44 … … 66 67 * - argument #2 is target endpoint 67 68 * - argument #3 is buffer size 69 * - this call is immediately followed by IPC data read (async version) 68 70 * - the call is not answered until the device returns some data (or until 69 71 * error occurs) 70 * - if the call is answered with EOK, first argument of the answer is buffer71 * hash that could be used to retrieve the actual data72 72 * 73 73 * Some special methods (NO-DATA transactions) do not send any data. These 74 74 * might behave as both OUT or IN transactions because communication parts 75 75 * where actual buffers are exchanged are omitted. 76 * 77 * The mentioned data retrieval can be done any time after receiving EOK 78 * answer to IN method. 79 * This retrieval is done using the IPC_M_USBHC_GET_BUFFER where 80 * the first argument is buffer hash from call answer. 81 * This call must be immediately followed by data read-in and after the 82 * data are transferred, the initial call (IPC_M_USBHC_GET_BUFFER) 83 * is answered. Each buffer can be retrieved only once. 84 * 76 ** 85 77 * For all these methods, wrap functions exists. Important rule: functions 86 78 * for IN transactions have (as parameters) buffers where retrieved data … … 104 96 IPC_M_USBHC_GET_ADDRESS, 105 97 106 /** Asks for data buffer.107 * See explanation at usb_iface_funcs_t.108 * This function does not have counter part in functional interface109 * as it is handled by the remote part itself.110 */111 IPC_M_USBHC_GET_BUFFER,112 113 98 114 99 /** Reserve usage of default address. … … 223 208 /** Callback for outgoing transfer. */ 224 209 typedef void (*usbhc_iface_transfer_out_callback_t)(device_t *, 225 usb_transaction_outcome_t, void *);210 int, void *); 226 211 227 212 /** Callback for incoming transfer. */ 228 213 typedef void (*usbhc_iface_transfer_in_callback_t)(device_t *, 229 usb_transaction_outcome_t, size_t, void *);214 int, size_t, void *); 230 215 231 216 232 217 /** Out transfer processing function prototype. */ 233 typedef int (*usbhc_iface_transfer_out_t)(device_t *, usb_target_t, 218 typedef int (*usbhc_iface_transfer_out_t)(device_t *, usb_target_t, size_t, 234 219 void *, size_t, 235 220 usbhc_iface_transfer_out_callback_t, void *); 236 221 237 /** Setup transfer processing function prototype. */222 /** Setup transfer processing function prototype. @deprecated */ 238 223 typedef usbhc_iface_transfer_out_t usbhc_iface_transfer_setup_t; 239 224 240 225 /** In transfer processing function prototype. */ 241 typedef int (*usbhc_iface_transfer_in_t)(device_t *, usb_target_t, 226 typedef int (*usbhc_iface_transfer_in_t)(device_t *, usb_target_t, size_t, 242 227 void *, size_t, 243 228 usbhc_iface_transfer_in_callback_t, void *); … … 247 232 int (*tell_address)(device_t *, devman_handle_t, usb_address_t *); 248 233 249 int (*reserve_default_address)(device_t * );234 int (*reserve_default_address)(device_t *, bool); 250 235 int (*release_default_address)(device_t *); 251 int (*request_address)(device_t *, usb_address_t *);236 int (*request_address)(device_t *, bool, usb_address_t *); 252 237 int (*bind_address)(device_t *, usb_address_t, devman_handle_t); 253 238 int (*release_address)(device_t *, usb_address_t); … … 267 252 268 253 int (*control_write)(device_t *, usb_target_t, 254 size_t, 269 255 void *, size_t, void *, size_t, 270 256 usbhc_iface_transfer_out_callback_t, void *); 271 257 272 258 int (*control_read)(device_t *, usb_target_t, 259 size_t, 273 260 void *, size_t, void *, size_t, 274 261 usbhc_iface_transfer_in_callback_t, void *); -
uspace/lib/usb/Makefile
rd81ef61c r50ba203 39 39 src/drvpsync.c \ 40 40 src/dump.c \ 41 src/hcdhubd.c \42 src/hcdrv.c \43 41 src/hidparser.c \ 44 src/ localdrv.c \42 src/hub.c \ 45 43 src/pipes.c \ 44 src/pipesinit.c \ 45 src/pipesio.c \ 46 46 src/recognise.c \ 47 src/remotedrv.c \48 47 src/request.c \ 49 48 src/usb.c \ 49 src/usbdevice.c \ 50 50 src/usbdrvreq.c \ 51 51 src/usbdrv.c \ -
uspace/lib/usb/include/usb/addrkeep.h
-
Property mode
changed from
120000to100644
rd81ef61c r50ba203 1 hcd.h 1 /* 2 * Copyright (c) 2010 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 address keeping for host controller drivers. 34 */ 35 #ifndef LIBUSB_ADDRKEEP_H_ 36 #define LIBUSB_ADDRKEEP_H_ 37 38 #include <usb/usb.h> 39 #include <fibril_synch.h> 40 #include <devman.h> 41 42 /** Info about used address. */ 43 typedef struct { 44 /** Linked list member. */ 45 link_t link; 46 /** Address. */ 47 usb_address_t address; 48 /** Corresponding devman handle. */ 49 devman_handle_t devman_handle; 50 } usb_address_keeping_used_t; 51 52 /** Structure for keeping track of free and used USB addresses. */ 53 typedef struct { 54 /** Head of list of used addresses. */ 55 link_t used_addresses; 56 /** Upper bound for USB addresses. */ 57 usb_address_t max_address; 58 /** Mutex protecting used address. */ 59 fibril_mutex_t used_addresses_guard; 60 /** Condition variable for used addresses. */ 61 fibril_condvar_t used_addresses_condvar; 62 63 /** Condition variable mutex for default address. */ 64 fibril_mutex_t default_condvar_guard; 65 /** Condition variable for default address. */ 66 fibril_condvar_t default_condvar; 67 /** Whether is default address available. */ 68 bool default_available; 69 } usb_address_keeping_t; 70 71 void usb_address_keeping_init(usb_address_keeping_t *, usb_address_t); 72 73 void usb_address_keeping_reserve_default(usb_address_keeping_t *); 74 void usb_address_keeping_release_default(usb_address_keeping_t *); 75 76 usb_address_t usb_address_keeping_request(usb_address_keeping_t *); 77 int usb_address_keeping_release(usb_address_keeping_t *, usb_address_t); 78 void usb_address_keeping_devman_bind(usb_address_keeping_t *, usb_address_t, 79 devman_handle_t); 80 usb_address_t usb_address_keeping_find(usb_address_keeping_t *, 81 devman_handle_t); 82 83 #endif 84 /** 85 * @} 86 */ -
Property mode
changed from
-
uspace/lib/usb/include/usb/classes/hid.h
rd81ef61c r50ba203 50 50 USB_HIDREQ_SET_PROTOCOL = 11 51 51 } usb_hid_request_t; 52 53 /** USB/HID subclass constants. */ 54 typedef enum { 55 USB_HID_SUBCLASS_NONE = 0, 56 USB_HID_SUBCLASS_BOOT = 1 57 } usb_hid_subclass_t; 52 58 53 59 /** USB/HID interface protocols. */ -
uspace/lib/usb/include/usb/classes/hub.h
rd81ef61c r50ba203 37 37 38 38 #include <sys/types.h> 39 #include <usb/hcdhubd.h>40 41 39 42 40 /** Hub class feature selector. … … 80 78 /** 81 79 D1...D0: Logical Power Switching Mode 82 00: Ganged power switching (all ports ’power at80 00: Ganged power switching (all ports power at 83 81 once) 84 82 01: Individual port power switching … … 91 89 00: Global Over-current Protection. The hub 92 90 reports over-current as a summation of all 93 ports ’current draw, without a breakdown of91 ports current draw, without a breakdown of 94 92 individual port over-current status. 95 93 01: Individual Port Over-current Protection. The -
uspace/lib/usb/include/usb/hub.h
rd81ef61c r50ba203 1 1 /* 2 * Copyright (c) 201 0Vojtech Horky2 * Copyright (c) 2011 Vojtech Horky 3 3 * All rights reserved. 4 4 * … … 31 31 */ 32 32 /** @file 33 * @brief HC driver.33 * Functions needed by hub drivers. 34 34 */ 35 #ifndef LIBUSB_H CD_H_36 #define LIBUSB_H CD_H_35 #ifndef LIBUSB_HUB_H_ 36 #define LIBUSB_HUB_H_ 37 37 38 #include <usb/usb.h> 39 #include <fibril_synch.h> 40 #include <devman.h> 38 #include <sys/types.h> 39 #include <usb/usbdevice.h> 41 40 42 /** Info about used address. */ 41 /** Info about device attached to host controller. 42 * 43 * This structure exists only to keep the same signature of 44 * usb_hc_register_device() when more properties of the device 45 * would have to be passed to the host controller. 46 */ 43 47 typedef struct { 44 /** Linked list member. */ 45 link_t link; 46 /** Address. */ 48 /** Device address. */ 47 49 usb_address_t address; 48 /** Corresponding devman handle. */49 devman_handle_t devman_handle;50 } usb_ address_keeping_used_t;50 /** Devman handle of the device. */ 51 devman_handle_t handle; 52 } usb_hc_attached_device_t; 51 53 52 /** Structure for keeping track of free and used USB addresses. */ 53 typedef struct { 54 /** Head of list of used addresses. */ 55 link_t used_addresses; 56 /** Upper bound for USB addresses. */ 57 usb_address_t max_address; 58 /** Mutex protecting used address. */ 59 fibril_mutex_t used_addresses_guard; 60 /** Condition variable for used addresses. */ 61 fibril_condvar_t used_addresses_condvar; 54 int usb_hc_reserve_default_address(usb_hc_connection_t *, bool); 55 int usb_hc_release_default_address(usb_hc_connection_t *); 62 56 63 /** Condition variable mutex for default address. */ 64 fibril_mutex_t default_condvar_guard; 65 /** Condition variable for default address. */ 66 fibril_condvar_t default_condvar; 67 /** Whether is default address available. */ 68 bool default_available; 69 } usb_address_keeping_t; 70 71 void usb_address_keeping_init(usb_address_keeping_t *, usb_address_t); 72 73 void usb_address_keeping_reserve_default(usb_address_keeping_t *); 74 void usb_address_keeping_release_default(usb_address_keeping_t *); 75 76 usb_address_t usb_address_keeping_request(usb_address_keeping_t *); 77 int usb_address_keeping_release(usb_address_keeping_t *, usb_address_t); 78 void usb_address_keeping_devman_bind(usb_address_keeping_t *, usb_address_t, 79 devman_handle_t); 80 usb_address_t usb_address_keeping_find(usb_address_keeping_t *, 81 devman_handle_t); 57 usb_address_t usb_hc_request_address(usb_hc_connection_t *, bool); 58 int usb_hc_register_device(usb_hc_connection_t *, 59 const usb_hc_attached_device_t *); 60 int usb_hc_unregister_device(usb_hc_connection_t *, usb_address_t); 82 61 83 62 #endif -
uspace/lib/usb/include/usb/pipes.h
rd81ef61c r50ba203 31 31 */ 32 32 /** @file 33 * Communication between device drivers and host controller driver.33 * USB pipes representation. 34 34 */ 35 35 #ifndef LIBUSB_PIPES_H_ … … 38 38 #include <sys/types.h> 39 39 #include <usb/usb.h> 40 #include <usb/usbdevice.h> 41 #include <usb/descriptor.h> 40 42 #include <ipc/devman.h> 41 43 #include <driver.h> … … 73 75 usb_direction_t direction; 74 76 77 /** Maximum packet size for the endpoint. */ 78 size_t max_packet_size; 79 75 80 /** Phone to the host controller. 76 81 * Negative when no session is active. … … 80 85 81 86 87 /** Description of endpoint characteristics. */ 88 typedef struct { 89 /** Transfer type (e.g. control or interrupt). */ 90 usb_transfer_type_t transfer_type; 91 /** Transfer direction (to or from a device). */ 92 usb_direction_t direction; 93 /** Interface class this endpoint belongs to (-1 for any). */ 94 int interface_class; 95 /** Interface subclass this endpoint belongs to (-1 for any). */ 96 int interface_subclass; 97 /** Interface protocol this endpoint belongs to (-1 for any). */ 98 int interface_protocol; 99 /** Extra endpoint flags. */ 100 unsigned int flags; 101 } usb_endpoint_description_t; 102 103 /** Mapping of endpoint pipes and endpoint descriptions. */ 104 typedef struct { 105 /** Endpoint pipe. */ 106 usb_endpoint_pipe_t *pipe; 107 /** Endpoint description. */ 108 const usb_endpoint_description_t *description; 109 /** Found descriptor fitting the description. */ 110 usb_standard_endpoint_descriptor_t *descriptor; 111 /** Interface the endpoint belongs to. */ 112 usb_standard_interface_descriptor_t *interface; 113 /** Whether the endpoint was actually found. */ 114 bool present; 115 } usb_endpoint_mapping_t; 116 117 int usb_device_connection_initialize_on_default_address( 118 usb_device_connection_t *, usb_hc_connection_t *); 82 119 int usb_device_connection_initialize_from_device(usb_device_connection_t *, 83 120 device_t *); … … 87 124 int usb_endpoint_pipe_initialize(usb_endpoint_pipe_t *, 88 125 usb_device_connection_t *, 89 usb_endpoint_t, usb_transfer_type_t, usb_direction_t);126 usb_endpoint_t, usb_transfer_type_t, size_t, usb_direction_t); 90 127 int usb_endpoint_pipe_initialize_default_control(usb_endpoint_pipe_t *, 91 128 usb_device_connection_t *); 129 int usb_endpoint_pipe_initialize_from_configuration(usb_endpoint_mapping_t *, 130 size_t, uint8_t *, size_t, usb_device_connection_t *); 92 131 93 132 … … 103 142 void *, size_t); 104 143 105 106 107 int usb_endpoint_pipe_async_read(usb_endpoint_pipe_t *, void *, size_t,108 size_t *, usb_handle_t *);109 int usb_endpoint_pipe_async_write(usb_endpoint_pipe_t *, void *, size_t,110 usb_handle_t *);111 112 int usb_endpoint_pipe_async_control_read(usb_endpoint_pipe_t *, void *, size_t,113 void *, size_t, size_t *, usb_handle_t *);114 int usb_endpoint_pipe_async_control_write(usb_endpoint_pipe_t *, void *, size_t,115 void *, size_t, usb_handle_t *);116 117 int usb_endpoint_pipe_wait_for(usb_endpoint_pipe_t *, usb_handle_t);118 119 144 #endif 120 145 /** -
uspace/lib/usb/include/usb/usb.h
rd81ef61c r50ba203 83 83 } usb_request_recipient_t; 84 84 85 /** USB transaction outcome. */86 typedef enum {87 USB_OUTCOME_OK,88 USB_OUTCOME_CRCERROR,89 USB_OUTCOME_BABBLE90 } usb_transaction_outcome_t;91 92 const char * usb_str_transaction_outcome(usb_transaction_outcome_t o);93 94 85 /** USB address type. 95 86 * Negative values could be used to indicate error. -
uspace/lib/usb/include/usb/usbdrv.h
rd81ef61c r50ba203 106 106 const void *, size_t); 107 107 108 int usb_drv_create_device_match_ids(int, match_id_list_t *, usb_address_t);109 int usb_drv_register_child_in_devman(int, device_t *, usb_address_t,110 devman_handle_t *);111 112 108 113 109 #endif -
uspace/lib/usb/src/addrkeep.c
rd81ef61c r50ba203 33 33 * @brief Address keeping. 34 34 */ 35 #include <usb/ hcd.h>35 #include <usb/addrkeep.h> 36 36 #include <errno.h> 37 37 #include <assert.h> -
uspace/lib/usb/src/dump.c
rd81ef61c r50ba203 147 147 PRINTLINE("bDeviceProtocol = 0x%02x", d->device_protocol); 148 148 PRINTLINE("bMaxPacketSize0 = %d", d->max_packet_size); 149 PRINTLINE("idVendor = %d", d->vendor_id);150 PRINTLINE("idProduct = %d", d->product_id);149 PRINTLINE("idVendor = 0x%04x", d->vendor_id); 150 PRINTLINE("idProduct = 0x%04x", d->product_id); 151 151 PRINTLINE("bcdDevice = %d", d->device_version); 152 152 PRINTLINE("iManufacturer = %d", d->str_manufacturer); -
uspace/lib/usb/src/pipes.c
rd81ef61c r50ba203 31 31 */ 32 32 /** @file 33 * Communication between device drivers and host controller driver. 34 * 35 * Note on synchronousness of the operations: there is ABSOLUTELY NO 36 * guarantee that a call to particular function will not trigger a fibril 37 * switch. 38 * The initialization functions may actually involve contacting some other 39 * task, starting/ending a session might involve asynchronous IPC and since 40 * the transfer functions uses IPC, asynchronous nature of them is obvious. 41 * The pseudo synchronous versions for the transfers internally call the 42 * asynchronous ones and so fibril switch is possible in them as well. 33 * USB endpoint pipes miscellaneous functions. 43 34 */ 44 35 #include <usb/usb.h> … … 47 38 #include <assert.h> 48 39 #include <usb/usbdrv.h> 49 50 #define _PREPARE_TARGET(varname, pipe) \51 usb_target_t varname = { \52 .address = (pipe)->wire->address, \53 .endpoint = (pipe)->endpoint_no \54 }55 40 56 41 /** Initialize connection to USB device. … … 117 102 } 118 103 119 /** Initialize USB endpoint pipe.104 /** Initialize connection to USB device on default address. 120 105 * 121 * @param pipe Endpoint pipe to be initialized. 122 * @param connection Connection to the USB device backing this pipe (the wire). 123 * @param endpoint_no Endpoint number (in USB 1.1 in range 0 to 15). 124 * @param transfer_type Transfer type (e.g. interrupt or bulk). 125 * @param direction Endpoint direction (in/out). 106 * @param dev_connection Device connection structure to be initialized. 107 * @param hc_connection Initialized connection to host controller. 126 108 * @return Error code. 127 109 */ 128 int usb_ endpoint_pipe_initialize(usb_endpoint_pipe_t *pipe,129 usb_device_connection_t * connection, usb_endpoint_t endpoint_no,130 usb_ transfer_type_t transfer_type, usb_direction_t direction)110 int usb_device_connection_initialize_on_default_address( 111 usb_device_connection_t *dev_connection, 112 usb_hc_connection_t *hc_connection) 131 113 { 132 assert(pipe); 133 assert(connection); 114 assert(dev_connection); 134 115 135 pipe->wire = connection; 136 pipe->hc_phone = -1; 137 pipe->endpoint_no = endpoint_no; 138 pipe->transfer_type = transfer_type; 139 pipe->direction = direction; 116 if (hc_connection == NULL) { 117 return EBADMEM; 118 } 140 119 141 return EOK; 142 } 143 144 145 /** Initialize USB endpoint pipe as the default zero control pipe. 146 * 147 * @param pipe Endpoint pipe to be initialized. 148 * @param connection Connection to the USB device backing this pipe (the wire). 149 * @return Error code. 150 */ 151 int usb_endpoint_pipe_initialize_default_control(usb_endpoint_pipe_t *pipe, 152 usb_device_connection_t *connection) 153 { 154 assert(pipe); 155 assert(connection); 156 157 int rc = usb_endpoint_pipe_initialize(pipe, connection, 158 0, USB_TRANSFER_CONTROL, USB_DIRECTION_BOTH); 159 160 return rc; 120 return usb_device_connection_initialize(dev_connection, 121 hc_connection->hc_handle, (usb_address_t) 0); 161 122 } 162 123 … … 221 182 } 222 183 223 224 /** Request a read (in) transfer on an endpoint pipe.225 *226 * @param[in] pipe Pipe used for the transfer.227 * @param[out] buffer Buffer where to store the data.228 * @param[in] size Size of the buffer (in bytes).229 * @param[out] size_transfered Number of bytes that were actually transfered.230 * @return Error code.231 */232 int usb_endpoint_pipe_read(usb_endpoint_pipe_t *pipe,233 void *buffer, size_t size, size_t *size_transfered)234 {235 assert(pipe);236 237 int rc;238 usb_handle_t handle;239 240 rc = usb_endpoint_pipe_async_read(pipe, buffer, size, size_transfered,241 &handle);242 if (rc != EOK) {243 return rc;244 }245 246 rc = usb_endpoint_pipe_wait_for(pipe, handle);247 return rc;248 }249 250 /** Request a write (out) transfer on an endpoint pipe.251 *252 * @param[in] pipe Pipe used for the transfer.253 * @param[in] buffer Buffer with data to transfer.254 * @param[in] size Size of the buffer (in bytes).255 * @return Error code.256 */257 int usb_endpoint_pipe_write(usb_endpoint_pipe_t *pipe,258 void *buffer, size_t size)259 {260 assert(pipe);261 262 int rc;263 usb_handle_t handle;264 265 rc = usb_endpoint_pipe_async_write(pipe, buffer, size, &handle);266 if (rc != EOK) {267 return rc;268 }269 270 rc = usb_endpoint_pipe_wait_for(pipe, handle);271 return rc;272 }273 274 275 /** Request a control read transfer on an endpoint pipe.276 *277 * This function encapsulates all three stages of a control transfer.278 *279 * @param[in] pipe Pipe used for the transfer.280 * @param[in] setup_buffer Buffer with the setup packet.281 * @param[in] setup_buffer_size Size of the setup packet (in bytes).282 * @param[out] data_buffer Buffer for incoming data.283 * @param[in] data_buffer_size Size of the buffer for incoming data (in bytes).284 * @param[out] data_transfered_size Number of bytes that were actually285 * transfered during the DATA stage.286 * @return Error code.287 */288 int usb_endpoint_pipe_control_read(usb_endpoint_pipe_t *pipe,289 void *setup_buffer, size_t setup_buffer_size,290 void *data_buffer, size_t data_buffer_size, size_t *data_transfered_size)291 {292 assert(pipe);293 294 int rc;295 usb_handle_t handle;296 297 rc = usb_endpoint_pipe_async_control_read(pipe,298 setup_buffer, setup_buffer_size,299 data_buffer, data_buffer_size, data_transfered_size,300 &handle);301 if (rc != EOK) {302 return rc;303 }304 305 rc = usb_endpoint_pipe_wait_for(pipe, handle);306 return rc;307 }308 309 310 /** Request a control write transfer on an endpoint pipe.311 *312 * This function encapsulates all three stages of a control transfer.313 *314 * @param[in] pipe Pipe used for the transfer.315 * @param[in] setup_buffer Buffer with the setup packet.316 * @param[in] setup_buffer_size Size of the setup packet (in bytes).317 * @param[in] data_buffer Buffer with data to be sent.318 * @param[in] data_buffer_size Size of the buffer with outgoing data (in bytes).319 * @return Error code.320 */321 int usb_endpoint_pipe_control_write(usb_endpoint_pipe_t *pipe,322 void *setup_buffer, size_t setup_buffer_size,323 void *data_buffer, size_t data_buffer_size)324 {325 assert(pipe);326 327 int rc;328 usb_handle_t handle;329 330 rc = usb_endpoint_pipe_async_control_write(pipe,331 setup_buffer, setup_buffer_size,332 data_buffer, data_buffer_size,333 &handle);334 if (rc != EOK) {335 return rc;336 }337 338 rc = usb_endpoint_pipe_wait_for(pipe, handle);339 return rc;340 }341 342 343 /** Request a read (in) transfer on an endpoint pipe (asynchronous version).344 *345 * @param[in] pipe Pipe used for the transfer.346 * @param[out] buffer Buffer where to store the data.347 * @param[in] size Size of the buffer (in bytes).348 * @param[out] size_transfered Number of bytes that were actually transfered.349 * @param[out] handle Handle of the transfer.350 * @return Error code.351 */352 int usb_endpoint_pipe_async_read(usb_endpoint_pipe_t *pipe,353 void *buffer, size_t size, size_t *size_transfered,354 usb_handle_t *handle)355 {356 assert(pipe);357 358 if (pipe->hc_phone < 0) {359 return EBADF;360 }361 362 if (pipe->direction != USB_DIRECTION_IN) {363 return EBADF;364 }365 366 int rc;367 _PREPARE_TARGET(target, pipe);368 369 switch (pipe->transfer_type) {370 case USB_TRANSFER_INTERRUPT:371 rc = usb_drv_async_interrupt_in(pipe->hc_phone, target,372 buffer, size, size_transfered, handle);373 break;374 case USB_TRANSFER_CONTROL:375 rc = EBADF;376 break;377 default:378 rc = ENOTSUP;379 break;380 }381 382 return rc;383 }384 385 386 /** Request a write (out) transfer on an endpoint pipe (asynchronous version).387 *388 * @param[in] pipe Pipe used for the transfer.389 * @param[in] buffer Buffer with data to transfer.390 * @param[in] size Size of the buffer (in bytes).391 * @param[out] handle Handle of the transfer.392 * @return Error code.393 */394 int usb_endpoint_pipe_async_write(usb_endpoint_pipe_t *pipe,395 void *buffer, size_t size,396 usb_handle_t *handle)397 {398 assert(pipe);399 400 if (pipe->hc_phone < 0) {401 return EBADF;402 }403 404 if (pipe->direction != USB_DIRECTION_OUT) {405 return EBADF;406 }407 408 int rc;409 _PREPARE_TARGET(target, pipe);410 411 switch (pipe->transfer_type) {412 case USB_TRANSFER_INTERRUPT:413 rc = usb_drv_async_interrupt_out(pipe->hc_phone, target,414 buffer, size, handle);415 break;416 case USB_TRANSFER_CONTROL:417 rc = EBADF;418 break;419 default:420 rc = ENOTSUP;421 break;422 }423 424 return rc;425 }426 427 428 /** Request a control read transfer on an endpoint pipe (asynchronous version).429 *430 * This function encapsulates all three stages of a control transfer.431 *432 * @param[in] pipe Pipe used for the transfer.433 * @param[in] setup_buffer Buffer with the setup packet.434 * @param[in] setup_buffer_size Size of the setup packet (in bytes).435 * @param[out] data_buffer Buffer for incoming data.436 * @param[in] data_buffer_size Size of the buffer for incoming data (in bytes).437 * @param[out] data_transfered_size Number of bytes that were actually438 * transfered during the DATA stage.439 * @param[out] handle Handle of the transfer.440 * @return Error code.441 */442 int usb_endpoint_pipe_async_control_read(usb_endpoint_pipe_t *pipe,443 void *setup_buffer, size_t setup_buffer_size,444 void *data_buffer, size_t data_buffer_size, size_t *data_transfered_size,445 usb_handle_t *handle)446 {447 assert(pipe);448 449 if (pipe->hc_phone < 0) {450 return EBADF;451 }452 453 if ((pipe->direction != USB_DIRECTION_BOTH)454 || (pipe->transfer_type != USB_TRANSFER_CONTROL)) {455 return EBADF;456 }457 458 int rc;459 _PREPARE_TARGET(target, pipe);460 461 rc = usb_drv_async_control_read(pipe->hc_phone, target,462 setup_buffer, setup_buffer_size,463 data_buffer, data_buffer_size, data_transfered_size,464 handle);465 466 return rc;467 }468 469 470 /** Request a control write transfer on an endpoint pipe (asynchronous version).471 *472 * This function encapsulates all three stages of a control transfer.473 *474 * @param[in] pipe Pipe used for the transfer.475 * @param[in] setup_buffer Buffer with the setup packet.476 * @param[in] setup_buffer_size Size of the setup packet (in bytes).477 * @param[in] data_buffer Buffer with data to be sent.478 * @param[in] data_buffer_size Size of the buffer with outgoing data (in bytes).479 * @param[out] handle Handle of the transfer.480 * @return Error code.481 */482 int usb_endpoint_pipe_async_control_write(usb_endpoint_pipe_t *pipe,483 void *setup_buffer, size_t setup_buffer_size,484 void *data_buffer, size_t data_buffer_size,485 usb_handle_t *handle)486 {487 assert(pipe);488 489 if (pipe->hc_phone < 0) {490 return EBADF;491 }492 493 if ((pipe->direction != USB_DIRECTION_BOTH)494 || (pipe->transfer_type != USB_TRANSFER_CONTROL)) {495 return EBADF;496 }497 498 int rc;499 _PREPARE_TARGET(target, pipe);500 501 rc = usb_drv_async_control_write(pipe->hc_phone, target,502 setup_buffer, setup_buffer_size,503 data_buffer, data_buffer_size,504 handle);505 506 return rc;507 }508 509 /** Wait for transfer completion.510 *511 * The function blocks the caller fibril until the transfer associated512 * with given @p handle is completed.513 *514 * @param[in] pipe Pipe the transfer executed on.515 * @param[in] handle Transfer handle.516 * @return Error code.517 */518 int usb_endpoint_pipe_wait_for(usb_endpoint_pipe_t *pipe, usb_handle_t handle)519 {520 return usb_drv_async_wait_for(handle);521 }522 523 524 184 /** 525 185 * @} -
uspace/lib/usb/src/recognise.c
rd81ef61c r50ba203 36 36 #include <usb_iface.h> 37 37 #include <usb/usbdrv.h> 38 #include <usb/pipes.h> 39 #include <usb/recognise.h> 40 #include <usb/request.h> 38 41 #include <usb/classes/classes.h> 39 42 #include <stdio.h> 40 43 #include <errno.h> 44 45 static size_t device_name_index = 0; 46 static FIBRIL_MUTEX_INITIALIZE(device_name_index_mutex); 41 47 42 48 /** Callback for getting host controller handle. … … 70 76 }; 71 77 72 staticdevice_ops_t child_ops = {78 device_ops_t child_ops = { 73 79 .interfaces[USB_DEV_IFACE] = &usb_iface 74 80 }; … … 155 161 /* First, with release number. */ 156 162 rc = usb_add_match_id(matches, 100, 157 "usb&vendor= %d&product=%d&release=" BCD_FMT,163 "usb&vendor=0x%04x&product=0x%04x&release=" BCD_FMT, 158 164 (int) device_descriptor->vendor_id, 159 165 (int) device_descriptor->product_id, … … 164 170 165 171 /* Next, without release number. */ 166 rc = usb_add_match_id(matches, 90, "usb&vendor=%d&product=%d", 172 rc = usb_add_match_id(matches, 90, 173 "usb&vendor=0x%04x&product=0x%04x", 167 174 (int) device_descriptor->vendor_id, 168 175 (int) device_descriptor->product_id); … … 241 248 /** Add match ids based on configuration descriptor. 242 249 * 243 * @param hc Open phone to host controller.250 * @param pipe Control pipe to the device. 244 251 * @param matches Match ids list to add matches to. 245 * @param address USB address of the attached device.246 252 * @param config_count Number of configurations the device has. 247 253 * @return Error code. 248 254 */ 249 static int usb_add_config_descriptor_match_ids(int hc, 250 match_id_list_t *matches, usb_address_t address, 251 int config_count) 255 static int usb_add_config_descriptor_match_ids(usb_endpoint_pipe_t *pipe, 256 match_id_list_t *matches, int config_count) 252 257 { 253 258 int final_rc = EOK; … … 257 262 int rc; 258 263 usb_standard_configuration_descriptor_t config_descriptor; 259 rc = usb_ drv_req_get_bare_configuration_descriptor(hc,260 address,config_index, &config_descriptor);264 rc = usb_request_get_bare_configuration_descriptor(pipe, 265 config_index, &config_descriptor); 261 266 if (rc != EOK) { 262 267 final_rc = rc; … … 267 272 void *full_config_descriptor 268 273 = malloc(config_descriptor.total_length); 269 rc = usb_ drv_req_get_full_configuration_descriptor(hc,270 address,config_index,274 rc = usb_request_get_full_configuration_descriptor(pipe, 275 config_index, 271 276 full_config_descriptor, config_descriptor.total_length, 272 277 &full_config_descriptor_size); … … 299 304 * function exits with error. 300 305 * 301 * @param hc Open phone to host controller. 306 * @param ctrl_pipe Control pipe to given device (session must be already 307 * started). 302 308 * @param matches Initialized list of match ids. 303 * @param address USB address of the attached device. 304 * @return Error code. 305 */ 306 int usb_drv_create_device_match_ids(int hc, match_id_list_t *matches, 307 usb_address_t address) 309 * @return Error code. 310 */ 311 int usb_device_create_match_ids(usb_endpoint_pipe_t *ctrl_pipe, 312 match_id_list_t *matches) 308 313 { 309 314 int rc; 310 311 315 /* 312 316 * Retrieve device descriptor and add matches from it. … … 314 318 usb_standard_device_descriptor_t device_descriptor; 315 319 316 rc = usb_drv_req_get_device_descriptor(hc, address, 317 &device_descriptor); 320 rc = usb_request_get_device_descriptor(ctrl_pipe, &device_descriptor); 318 321 if (rc != EOK) { 319 322 return rc; 320 323 } 321 324 322 325 rc = usb_drv_create_match_ids_from_device_descriptor(matches, 323 326 &device_descriptor); … … 325 328 return rc; 326 329 } 327 330 328 331 /* 329 332 * Go through all configurations and add matches 330 333 * based on interface class. 331 334 */ 332 rc = usb_add_config_descriptor_match_ids( hc, matches,333 address,device_descriptor.configuration_count);335 rc = usb_add_config_descriptor_match_ids(ctrl_pipe, matches, 336 device_descriptor.configuration_count); 334 337 if (rc != EOK) { 335 338 return rc; … … 347 350 } 348 351 349 350 352 /** Probe for device kind and register it in devman. 351 353 * 352 * @param[in] hc Open phone to the host controller. 354 * @param[in] address Address of the (unknown) attached device. 355 * @param[in] hc_handle Handle of the host controller. 353 356 * @param[in] parent Parent device. 354 * @param[in] address Address of the (unknown) attached device.355 357 * @param[out] child_handle Handle of the child device. 356 358 * @return Error code. 357 359 */ 358 int usb_drv_register_child_in_devman(int hc, device_t *parent, 359 usb_address_t address, devman_handle_t *child_handle) 360 { 361 static size_t device_name_index = 0; 362 static FIBRIL_MUTEX_INITIALIZE(device_name_index_mutex); 363 360 int usb_device_register_child_in_devman(usb_address_t address, 361 devman_handle_t hc_handle, 362 device_t *parent, devman_handle_t *child_handle) 363 { 364 364 size_t this_device_name_index; 365 365 … … 369 369 fibril_mutex_unlock(&device_name_index_mutex); 370 370 371 372 371 device_t *child = NULL; 373 372 char *child_name = NULL; 374 373 int rc; 374 usb_device_connection_t dev_connection; 375 usb_endpoint_pipe_t ctrl_pipe; 376 377 rc = usb_device_connection_initialize(&dev_connection, hc_handle, address); 378 if (rc != EOK) { 379 goto failure; 380 } 381 382 rc = usb_endpoint_pipe_initialize_default_control(&ctrl_pipe, 383 &dev_connection); 384 if (rc != EOK) { 385 goto failure; 386 } 375 387 376 388 child = create_device(); … … 391 403 child->name = child_name; 392 404 child->ops = &child_ops; 393 394 rc = usb_drv_create_device_match_ids(hc, &child->match_ids, address); 405 406 rc = usb_endpoint_pipe_start_session(&ctrl_pipe); 407 if (rc != EOK) { 408 goto failure; 409 } 410 411 rc = usb_device_create_match_ids(&ctrl_pipe, &child->match_ids); 412 if (rc != EOK) { 413 goto failure; 414 } 415 416 rc = usb_endpoint_pipe_end_session(&ctrl_pipe); 395 417 if (rc != EOK) { 396 418 goto failure; … … 405 427 *child_handle = child->handle; 406 428 } 407 429 408 430 return EOK; 409 431 … … 419 441 420 442 return rc; 421 422 443 } 423 444 -
uspace/lib/usb/src/usb.c
rd81ef61c r50ba203 54 54 } 55 55 56 /** String representation of USB transaction outcome. */57 const char * usb_str_transaction_outcome(usb_transaction_outcome_t o)58 {59 switch (o) {60 case USB_OUTCOME_OK:61 return "ok";62 case USB_OUTCOME_CRCERROR:63 return "CRC error";64 case USB_OUTCOME_BABBLE:65 return "babble";66 default:67 return "unknown";68 }69 }70 71 72 56 /** 73 57 * @} -
uspace/lib/usb/src/usbdrv.c
rd81ef61c r50ba203 49 49 /** Storage for actual number of bytes transferred. */ 50 50 size_t *size_transferred; 51 /** Initial call repl ay data. */51 /** Initial call reply data. */ 52 52 ipc_call_t reply; 53 53 /** Initial call identifier. */ 54 54 aid_t request; 55 /** Reply data for data read call. */ 56 ipc_call_t read_reply; 57 /** Data read call identifier. */ 58 aid_t read_request; 55 59 } transfer_info_t; 56 60 … … 140 144 141 145 if (rc != EOK) { 142 printf("usb_drv_get_my_address over %d failed: %s\n", phone, str_error(rc));143 146 return rc; 144 147 } … … 250 253 } 251 254 255 transfer->read_request = 0; 252 256 transfer->size_transferred = NULL; 253 257 transfer->buffer = NULL; … … 315 319 } 316 320 321 transfer->read_request = 0; 317 322 transfer->size_transferred = actual_size; 318 323 transfer->buffer = buffer; … … 327 332 &transfer->reply); 328 333 334 if (buffer != NULL) { 335 transfer->read_request = async_data_read(phone, buffer, size, 336 &transfer->read_reply); 337 } 338 329 339 *handle = (usb_handle_t) transfer; 330 340 … … 332 342 } 333 343 334 /** Read buffer from HCD.335 *336 * @param phone Opened phone to HCD.337 * @param hash Buffer hash (obtained after completing IN transaction).338 * @param buffer Buffer where to store data data.339 * @param size Buffer size.340 * @param actual_size Storage where actual number of bytes transferred will341 * be stored.342 * @return Error status.343 */344 static int read_buffer_in(int phone, sysarg_t hash,345 void *buffer, size_t size, size_t *actual_size)346 {347 ipc_call_t answer_data;348 sysarg_t answer_rc;349 aid_t req;350 int rc;351 352 req = async_send_2(phone,353 DEV_IFACE_ID(USBHC_DEV_IFACE),354 IPC_M_USBHC_GET_BUFFER,355 hash,356 &answer_data);357 358 rc = async_data_read_start(phone, buffer, size);359 if (rc != EOK) {360 async_wait_for(req, NULL);361 return EINVAL;362 }363 364 async_wait_for(req, &answer_rc);365 rc = (int)answer_rc;366 367 if (rc != EOK) {368 return rc;369 }370 371 *actual_size = IPC_GET_ARG1(answer_data);372 373 return EOK;374 }375 344 376 345 /** Blocks caller until given USB transaction is finished. … … 395 364 396 365 sysarg_t answer_rc; 397 async_wait_for(transfer->request, &answer_rc);398 399 if (answer_rc != EOK) {400 rc = (int) answer_rc;401 goto leave;402 }403 366 404 367 /* … … 406 369 */ 407 370 if ((transfer->buffer != NULL) && (transfer->size > 0)) { 408 /* 409 * The buffer hash identifies the data on the server 410 * side. 411 * We will use it when actually reading-in the data. 412 */ 413 sysarg_t buffer_hash = IPC_GET_ARG1(transfer->reply); 414 if (buffer_hash == 0) { 415 rc = ENOENT; 371 async_wait_for(transfer->read_request, &answer_rc); 372 373 if (answer_rc != EOK) { 374 rc = (int) answer_rc; 416 375 goto leave; 417 376 } 418 377 419 size_t actual_size; 420 rc = read_buffer_in(transfer->phone, buffer_hash, 421 transfer->buffer, transfer->size, &actual_size); 422 423 if (rc != EOK) { 424 goto leave; 378 if (transfer->size_transferred != NULL) { 379 *(transfer->size_transferred) 380 = IPC_GET_ARG2(transfer->read_reply); 425 381 } 426 427 if (transfer->size_transferred) { 428 *(transfer->size_transferred) = actual_size; 429 } 382 } 383 384 async_wait_for(transfer->request, &answer_rc); 385 386 if (answer_rc != EOK) { 387 rc = (int) answer_rc; 388 goto leave; 430 389 } 431 390 … … 499 458 void *setup_packet, size_t setup_packet_size, 500 459 void *buffer, size_t buffer_size, 460 usb_handle_t *handle) 461 { 462 // FIXME - check input parameters instead of asserting them 463 assert(phone > 0); 464 assert(setup_packet != NULL); 465 assert(setup_packet_size > 0); 466 assert(((buffer != NULL) && (buffer_size > 0)) 467 || ((buffer == NULL) && (buffer_size == 0))); 468 assert(handle != NULL); 469 470 transfer_info_t *transfer 471 = (transfer_info_t *) malloc(sizeof(transfer_info_t)); 472 if (transfer == NULL) { 473 return ENOMEM; 474 } 475 476 transfer->read_request = 0; 477 transfer->size_transferred = NULL; 478 transfer->buffer = NULL; 479 transfer->size = 0; 480 transfer->phone = phone; 481 482 int rc; 483 484 transfer->request = async_send_3(phone, 485 DEV_IFACE_ID(USBHC_DEV_IFACE), 486 IPC_M_USBHC_CONTROL_WRITE, 487 target.address, target.endpoint, 488 &transfer->reply); 489 490 rc = async_data_write_start(phone, setup_packet, setup_packet_size); 491 if (rc != EOK) { 492 async_wait_for(transfer->request, NULL); 493 return rc; 494 } 495 496 if (buffer_size > 0) { 497 rc = async_data_write_start(phone, buffer, buffer_size); 498 if (rc != EOK) { 499 async_wait_for(transfer->request, NULL); 500 return rc; 501 } 502 } 503 504 *handle = (usb_handle_t) transfer; 505 506 return EOK; 507 } 508 509 /** Start control read transfer. */ 510 int usb_drv_async_control_read_setup(int phone, usb_target_t target, 511 void *buffer, size_t size, 512 usb_handle_t *handle) 513 { 514 return async_send_buffer(phone, 515 IPC_M_USBHC_CONTROL_READ_SETUP, 516 target, 517 buffer, size, 518 handle); 519 } 520 521 /** Read data during control read transfer. */ 522 int usb_drv_async_control_read_data(int phone, usb_target_t target, 523 void *buffer, size_t size, size_t *actual_size, 524 usb_handle_t *handle) 525 { 526 return async_recv_buffer(phone, 527 IPC_M_USBHC_CONTROL_READ_DATA, 528 target, 529 buffer, size, actual_size, 530 handle); 531 } 532 533 /** Finalize control read transfer. */ 534 int usb_drv_async_control_read_status(int phone, usb_target_t target, 535 usb_handle_t *handle) 536 { 537 return async_send_buffer(phone, 538 IPC_M_USBHC_CONTROL_READ_STATUS, 539 target, 540 NULL, 0, 541 handle); 542 } 543 544 /** Issue whole control read transfer. */ 545 int usb_drv_async_control_read(int phone, usb_target_t target, 546 void *setup_packet, size_t setup_packet_size, 547 void *buffer, size_t buffer_size, size_t *actual_size, 501 548 usb_handle_t *handle) 502 549 { … … 515 562 } 516 563 517 transfer->size_transferred = NULL;518 transfer->buffer = NULL;519 transfer->size = 0;520 transfer->phone = phone;521 522 int rc;523 524 transfer->request = async_send_3(phone,525 DEV_IFACE_ID(USBHC_DEV_IFACE),526 IPC_M_USBHC_CONTROL_WRITE,527 target.address, target.endpoint,528 &transfer->reply);529 530 rc = async_data_write_start(phone, setup_packet, setup_packet_size);531 if (rc != EOK) {532 async_wait_for(transfer->request, NULL);533 return rc;534 }535 536 rc = async_data_write_start(phone, buffer, buffer_size);537 if (rc != EOK) {538 async_wait_for(transfer->request, NULL);539 return rc;540 }541 542 *handle = (usb_handle_t) transfer;543 544 return EOK;545 }546 547 /** Start control read transfer. */548 int usb_drv_async_control_read_setup(int phone, usb_target_t target,549 void *buffer, size_t size,550 usb_handle_t *handle)551 {552 return async_send_buffer(phone,553 IPC_M_USBHC_CONTROL_READ_SETUP,554 target,555 buffer, size,556 handle);557 }558 559 /** Read data during control read transfer. */560 int usb_drv_async_control_read_data(int phone, usb_target_t target,561 void *buffer, size_t size, size_t *actual_size,562 usb_handle_t *handle)563 {564 return async_recv_buffer(phone,565 IPC_M_USBHC_CONTROL_READ_DATA,566 target,567 buffer, size, actual_size,568 handle);569 }570 571 /** Finalize control read transfer. */572 int usb_drv_async_control_read_status(int phone, usb_target_t target,573 usb_handle_t *handle)574 {575 return async_send_buffer(phone,576 IPC_M_USBHC_CONTROL_READ_STATUS,577 target,578 NULL, 0,579 handle);580 }581 582 /** Issue whole control read transfer. */583 int usb_drv_async_control_read(int phone, usb_target_t target,584 void *setup_packet, size_t setup_packet_size,585 void *buffer, size_t buffer_size, size_t *actual_size,586 usb_handle_t *handle)587 {588 // FIXME - check input parameters instead of asserting them589 assert(phone > 0);590 assert(setup_packet != NULL);591 assert(setup_packet_size > 0);592 assert(buffer != NULL);593 assert(buffer_size > 0);594 assert(handle != NULL);595 596 transfer_info_t *transfer597 = (transfer_info_t *) malloc(sizeof(transfer_info_t));598 if (transfer == NULL) {599 return ENOMEM;600 }601 602 564 transfer->size_transferred = actual_size; 603 565 transfer->buffer = buffer; … … 620 582 } 621 583 584 transfer->read_request = async_data_read(phone, buffer, buffer_size, 585 &transfer->read_reply); 586 622 587 *handle = (usb_handle_t) transfer; 623 588 -
uspace/lib/usbvirt/Makefile
rd81ef61c r50ba203 30 30 LIBRARY = libusbvirt 31 31 32 LIBS = $(LIBUSB_PREFIX)/libusb.a33 32 EXTRA_CFLAGS = -I$(LIBUSB_PREFIX)/include -Iinclude 34 33
Note:
See TracChangeset
for help on using the changeset viewer.
