Changeset ca56afa in mainline for uspace/lib/usb/src
- Timestamp:
- 2011-02-25T09:46:23Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- d493ac17
- Parents:
- 15b0432 (diff), a80849c (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/usb/src
- Files:
-
- 7 edited
-
ddfiface.c (modified) (6 diffs)
-
hub.c (modified) (3 diffs)
-
pipes.c (modified) (9 diffs)
-
pipesio.c (modified) (4 diffs)
-
recognise.c (modified) (10 diffs)
-
request.c (modified) (3 diffs)
-
usbdevice.c (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/usb/src/ddfiface.c
r15b0432 rca56afa 34 34 */ 35 35 #include <ipc/devman.h> 36 #include <devman.h> 37 #include <async.h> 36 38 #include <usb/ddfiface.h> 39 #include <usb/debug.h> 37 40 #include <errno.h> 41 #include <assert.h> 38 42 39 43 /** DDF interface for USB device, implementation for typical hub. */ … … 56 60 * @return Error code. 57 61 */ 58 int usb_iface_get_hc_handle_hub_impl(d evice_t *device, devman_handle_t *handle)62 int usb_iface_get_hc_handle_hub_impl(ddf_fun_t *fun, devman_handle_t *handle) 59 63 { 60 assert( device);61 return usb_hc_find( device->handle, handle);64 assert(fun); 65 return usb_hc_find(fun->handle, handle); 62 66 } 63 67 … … 69 73 * @return Error code. 70 74 */ 71 int usb_iface_get_hc_handle_hub_child_impl(d evice_t *device,75 int usb_iface_get_hc_handle_hub_child_impl(ddf_fun_t *fun, 72 76 devman_handle_t *handle) 73 77 { 74 assert(device); 75 device_t *parent = device->parent; 78 assert(fun != NULL); 76 79 77 /* Default error, device does not support this operation. */ 78 int rc = ENOTSUP; 79 80 if (parent && parent->ops && parent->ops->interfaces[USB_DEV_IFACE]) { 81 usb_iface_t *usb_iface 82 = (usb_iface_t *) parent->ops->interfaces[USB_DEV_IFACE]; 83 assert(usb_iface != NULL); 84 85 if (usb_iface->get_hc_handle) { 86 rc = usb_iface->get_hc_handle(parent, handle); 87 } 80 int parent_phone = devman_parent_device_connect(fun->handle, 81 IPC_FLAG_BLOCKING); 82 if (parent_phone < 0) { 83 return parent_phone; 88 84 } 89 85 90 return rc; 86 sysarg_t hc_handle; 87 int rc = async_req_1_1(parent_phone, DEV_IFACE_ID(USB_DEV_IFACE), 88 IPC_M_USB_GET_HOST_CONTROLLER_HANDLE, &hc_handle); 89 90 if (rc != EOK) { 91 return rc; 92 } 93 94 *handle = hc_handle; 95 96 return EOK; 91 97 } 92 98 … … 97 103 * @return Always EOK. 98 104 */ 99 int usb_iface_get_hc_handle_hc_impl(d evice_t *device, devman_handle_t *handle)105 int usb_iface_get_hc_handle_hc_impl(ddf_fun_t *fun, devman_handle_t *handle) 100 106 { 101 assert( device);107 assert(fun); 102 108 103 109 if (handle != NULL) { 104 *handle = device->handle;110 *handle = fun->handle; 105 111 } 106 112 … … 115 121 * @return Error code. 116 122 */ 117 int usb_iface_get_address_hub_impl(d evice_t *device, devman_handle_t handle,123 int usb_iface_get_address_hub_impl(ddf_fun_t *fun, devman_handle_t handle, 118 124 usb_address_t *address) 119 125 { 120 assert( device);121 int parent_phone = devman_parent_device_connect( device->handle,126 assert(fun); 127 int parent_phone = devman_parent_device_connect(fun->handle, 122 128 IPC_FLAG_BLOCKING); 123 129 if (parent_phone < 0) { … … 150 156 * @return Error code. 151 157 */ 152 int usb_iface_get_address_hub_child_impl(d evice_t *device,158 int usb_iface_get_address_hub_child_impl(ddf_fun_t *fun, 153 159 devman_handle_t handle, usb_address_t *address) 154 160 { 155 assert(device); 156 device_t *parent = device->parent; 157 158 /* Default error, device does not support this operation. */ 159 int rc = ENOTSUP; 160 161 if (parent && parent->ops && parent->ops->interfaces[USB_DEV_IFACE]) { 162 usb_iface_t *usb_iface 163 = (usb_iface_t *) parent->ops->interfaces[USB_DEV_IFACE]; 164 assert(usb_iface != NULL); 165 166 if (usb_iface->get_address) { 167 rc = usb_iface->get_address(parent, handle, address); 168 } 161 if (handle == 0) { 162 handle = fun->handle; 169 163 } 170 171 return rc; 164 return usb_iface_get_address_hub_impl(fun, handle, address); 172 165 } 173 166 -
uspace/lib/usb/src/hub.c
r15b0432 rca56afa 39 39 #include <usbhc_iface.h> 40 40 #include <errno.h> 41 #include <assert.h> 41 42 42 43 /** Check that HC connection is alright. … … 172 173 * request or requests for descriptors when creating match ids). 173 174 */ 174 int usb_hc_new_device_wrapper(d evice_t *parent, usb_hc_connection_t *connection,175 int usb_hc_new_device_wrapper(ddf_dev_t *parent, usb_hc_connection_t *connection, 175 176 usb_speed_t dev_speed, 176 177 int (*enable_port)(int port_no, void *arg), int port_no, void *arg, 177 usb_address_t *assigned_address, devman_handle_t *assigned_handle) 178 usb_address_t *assigned_address, devman_handle_t *assigned_handle, 179 ddf_dev_ops_t *dev_ops, void *new_dev_data, ddf_fun_t **new_fun) 178 180 { 179 181 CHECK_CONNECTION(connection); … … 251 253 devman_handle_t child_handle; 252 254 rc = usb_device_register_child_in_devman(dev_addr, dev_conn.hc_handle, 253 parent, &child_handle); 255 parent, &child_handle, 256 dev_ops, new_dev_data, new_fun); 254 257 if (rc != EOK) { 255 258 rc = ESTALL; -
uspace/lib/usb/src/pipes.c
r15b0432 rca56afa 35 35 #include <usb/usb.h> 36 36 #include <usb/pipes.h> 37 #include <usb/debug.h> 37 38 #include <usbhc_iface.h> 38 39 #include <usb_iface.h> 40 #include <devman.h> 39 41 #include <errno.h> 40 42 #include <assert.h> … … 46 48 * @return USB address or error code. 47 49 */ 48 static usb_address_t get_my_address(int phone, d evice_t *dev)50 static usb_address_t get_my_address(int phone, ddf_dev_t *dev) 49 51 { 50 52 sysarg_t address; 53 54 55 /* 56 * We are sending special value as a handle - zero - to get 57 * handle of the parent function (that handle was used 58 * when registering our device @p dev. 59 */ 51 60 int rc = async_req_2_1(phone, DEV_IFACE_ID(USB_DEV_IFACE), 52 61 IPC_M_USB_GET_ADDRESS, 53 dev->handle, &address);62 0, &address); 54 63 55 64 if (rc != EOK) { … … 65 74 * @return Interface number (negative code means any). 66 75 */ 67 int usb_device_get_assigned_interface(d evice_t *device)76 int usb_device_get_assigned_interface(ddf_dev_t *device) 68 77 { 69 78 int parent_phone = devman_parent_device_connect(device->handle, … … 94 103 */ 95 104 int usb_device_connection_initialize_from_device( 96 usb_device_connection_t *connection, d evice_t *device)105 usb_device_connection_t *connection, ddf_dev_t *dev) 97 106 { 98 107 assert(connection); 99 assert(dev ice);108 assert(dev); 100 109 101 110 int rc; … … 103 112 usb_address_t my_address; 104 113 105 rc = usb_hc_find(dev ice->handle, &hc_handle);114 rc = usb_hc_find(dev->handle, &hc_handle); 106 115 if (rc != EOK) { 107 116 return rc; 108 117 } 109 118 110 int parent_phone = devman_parent_device_connect(dev ice->handle,119 int parent_phone = devman_parent_device_connect(dev->handle, 111 120 IPC_FLAG_BLOCKING); 112 121 if (parent_phone < 0) { … … 114 123 } 115 124 116 my_address = get_my_address(parent_phone, dev ice);125 my_address = get_my_address(parent_phone, dev); 117 126 if (my_address < 0) { 118 127 rc = my_address; … … 191 200 assert(pipe); 192 201 193 if ( pipe->hc_phone >= 0) {202 if (usb_endpoint_pipe_is_session_started(pipe)) { 194 203 return EBUSY; 195 204 } … … 217 226 assert(pipe); 218 227 219 if ( pipe->hc_phone < 0) {228 if (!usb_endpoint_pipe_is_session_started(pipe)) { 220 229 return ENOENT; 221 230 } … … 229 238 230 239 return EOK; 240 } 241 242 /** Tell whether a session is started (open) on the endpoint pipe. 243 * 244 * The expected usage of this function is in assertions for some 245 * nested functions. 246 * 247 * @param pipe Endpoint pipe in question. 248 * @return Whether @p pipe has opened a session. 249 */ 250 bool usb_endpoint_pipe_is_session_started(usb_endpoint_pipe_t *pipe) 251 { 252 return (pipe->hc_phone >= 0); 231 253 } 232 254 -
uspace/lib/usb/src/pipesio.c
r15b0432 rca56afa 148 148 } 149 149 150 if ( pipe->hc_phone < 0) {150 if (!usb_endpoint_pipe_is_session_started(pipe)) { 151 151 return EBADF; 152 152 } … … 255 255 } 256 256 257 if ( pipe->hc_phone < 0) {257 if (!usb_endpoint_pipe_is_session_started(pipe)) { 258 258 return EBADF; 259 259 } … … 369 369 } 370 370 371 if ( pipe->hc_phone < 0) {371 if (!usb_endpoint_pipe_is_session_started(pipe)) { 372 372 return EBADF; 373 373 } … … 481 481 } 482 482 483 if ( pipe->hc_phone < 0) {483 if (!usb_endpoint_pipe_is_session_started(pipe)) { 484 484 return EBADF; 485 485 } -
uspace/lib/usb/src/recognise.c
r15b0432 rca56afa 34 34 */ 35 35 #include <sys/types.h> 36 #include <fibril_synch.h> 36 37 #include <usb/pipes.h> 37 38 #include <usb/recognise.h> … … 41 42 #include <stdio.h> 42 43 #include <errno.h> 44 #include <assert.h> 43 45 44 46 static size_t device_name_index = 0; 45 47 static FIBRIL_MUTEX_INITIALIZE(device_name_index_mutex); 46 48 47 d evice_ops_t child_ops = {49 ddf_dev_ops_t child_ops = { 48 50 .interfaces[USB_DEV_IFACE] = &usb_iface_hub_child_impl 49 51 }; … … 308 310 } 309 311 310 /*311 * As a fallback, provide the simplest match id possible.312 */313 ADD_MATCHID_OR_RETURN(matches, 1, "usb&fallback");314 315 312 return EOK; 316 313 } … … 326 323 int usb_device_register_child_in_devman(usb_address_t address, 327 324 devman_handle_t hc_handle, 328 device_t *parent, devman_handle_t *child_handle) 325 ddf_dev_t *parent, devman_handle_t *child_handle, 326 ddf_dev_ops_t *dev_ops, void *dev_data, ddf_fun_t **child_fun) 329 327 { 330 328 size_t this_device_name_index; … … 335 333 fibril_mutex_unlock(&device_name_index_mutex); 336 334 337 d evice_t *child = NULL;335 ddf_fun_t *child = NULL; 338 336 char *child_name = NULL; 339 337 int rc; … … 352 350 } 353 351 354 child = create_device(); 352 /* 353 * TODO: Once the device driver framework support persistent 354 * naming etc., something more descriptive could be created. 355 */ 356 rc = asprintf(&child_name, "usbdev%02zu", this_device_name_index); 357 if (rc < 0) { 358 goto failure; 359 } 360 361 child = ddf_fun_create(parent, fun_inner, child_name); 355 362 if (child == NULL) { 356 363 rc = ENOMEM; … … 358 365 } 359 366 360 /* 361 * TODO: Once the device driver framework support persistent 362 * naming etc., something more descriptive could be created. 363 */ 364 rc = asprintf(&child_name, "usbdev%02zu", this_device_name_index); 365 if (rc < 0) { 366 goto failure; 367 } 368 child->parent = parent; 369 child->name = child_name; 370 child->ops = &child_ops; 367 if (dev_ops != NULL) { 368 child->ops = dev_ops; 369 } else { 370 child->ops = &child_ops; 371 } 372 373 child->driver_data = dev_data; 371 374 372 375 rc = usb_endpoint_pipe_start_session(&ctrl_pipe); … … 385 388 } 386 389 387 rc = child_device_register(child, parent);390 rc = ddf_fun_bind(child); 388 391 if (rc != EOK) { 389 392 goto failure; … … 392 395 if (child_handle != NULL) { 393 396 *child_handle = child->handle; 397 } 398 399 if (child_fun != NULL) { 400 *child_fun = child; 394 401 } 395 402 … … 400 407 child->name = NULL; 401 408 /* This takes care of match_id deallocation as well. */ 402 d elete_device(child);409 ddf_fun_destroy(child); 403 410 } 404 411 if (child_name != NULL) { -
uspace/lib/usb/src/request.c
r15b0432 rca56afa 35 35 #include <usb/request.h> 36 36 #include <errno.h> 37 #include <assert.h> 37 38 38 39 #define MAX_DATA_LENGTH ((size_t)(0xFFFF)) … … 229 230 } 230 231 232 /** Retrieve USB descriptor, allocate space for it. 233 * 234 * @param[in] pipe Control endpoint pipe (session must be already started). 235 * @param[in] request_type Request type (standard/class/vendor). 236 * @param[in] descriptor_type Descriptor type (device/configuration/HID/...). 237 * @param[in] descriptor_index Descriptor index. 238 * @param[in] language Language index. 239 * @param[out] buffer_ptr Where to store pointer to allocated buffer. 240 * @param[out] buffer_size Where to store the size of the descriptor. 241 * @return 242 */ 243 int usb_request_get_descriptor_alloc(usb_endpoint_pipe_t * pipe, 244 usb_request_type_t request_type, 245 uint8_t descriptor_type, uint8_t descriptor_index, 246 uint16_t language, 247 void **buffer_ptr, size_t *buffer_size) 248 { 249 if (buffer_ptr == NULL) { 250 return EBADMEM; 251 } 252 253 int rc; 254 255 /* 256 * Get only first byte to retrieve descriptor length. 257 */ 258 uint8_t tmp_buffer[1]; 259 size_t bytes_transfered; 260 rc = usb_request_get_descriptor(pipe, request_type, 261 descriptor_type, descriptor_index, language, 262 &tmp_buffer, 1, &bytes_transfered); 263 if (rc != EOK) { 264 return rc; 265 } 266 if (bytes_transfered != 1) { 267 /* FIXME: some better error code? */ 268 return ESTALL; 269 } 270 271 size_t size = tmp_buffer[0]; 272 if (size == 0) { 273 /* FIXME: some better error code? */ 274 return ESTALL; 275 } 276 277 /* 278 * Allocate buffer and get the descriptor again. 279 */ 280 void *buffer = malloc(size); 281 if (buffer == NULL) { 282 return ENOMEM; 283 } 284 285 rc = usb_request_get_descriptor(pipe, request_type, 286 descriptor_type, descriptor_index, language, 287 buffer, size, &bytes_transfered); 288 if (rc != EOK) { 289 free(buffer); 290 return rc; 291 } 292 if (bytes_transfered != size) { 293 free(buffer); 294 /* FIXME: some better error code? */ 295 return ESTALL; 296 } 297 298 *buffer_ptr = buffer; 299 if (buffer_size != NULL) { 300 *buffer_size = size; 301 } 302 303 return EOK; 304 } 305 231 306 /** Retrieve standard device descriptor of a USB device. 232 307 * … … 354 429 } 355 430 431 /** Get list of supported languages by USB device. 432 * 433 * @param[in] pipe Control endpoint pipe (session must be already started). 434 * @param[out] languages_ptr Where to store pointer to allocated array of 435 * supported languages. 436 * @param[out] languages_count Number of supported languages. 437 * @return Error code. 438 */ 439 int usb_request_get_supported_languages(usb_endpoint_pipe_t *pipe, 440 l18_win_locales_t **languages_ptr, size_t *languages_count) 441 { 442 int rc; 443 444 if (languages_ptr == NULL) { 445 return EBADMEM; 446 } 447 if (languages_count == NULL) { 448 return EBADMEM; 449 } 450 451 uint8_t *string_descriptor = NULL; 452 size_t string_descriptor_size = 0; 453 rc = usb_request_get_descriptor_alloc(pipe, 454 USB_REQUEST_TYPE_STANDARD, USB_DESCTYPE_STRING, 0, 0, 455 (void **) &string_descriptor, &string_descriptor_size); 456 if (rc != EOK) { 457 return rc; 458 } 459 if (string_descriptor_size <= 2) { 460 free(string_descriptor); 461 return EEMPTY; 462 } 463 /* Substract first 2 bytes (length and descriptor type). */ 464 string_descriptor_size -= 2; 465 466 /* Odd number of bytes - descriptor is broken? */ 467 if ((string_descriptor_size % 2) != 0) { 468 /* FIXME: shall we return with error or silently ignore? */ 469 free(string_descriptor); 470 return ESTALL; 471 } 472 473 size_t langs_count = string_descriptor_size / 2; 474 l18_win_locales_t *langs 475 = malloc(sizeof(l18_win_locales_t) * langs_count); 476 if (langs == NULL) { 477 free(string_descriptor); 478 return ENOMEM; 479 } 480 481 size_t i; 482 for (i = 0; i < langs_count; i++) { 483 /* Language code from the descriptor is in USB endianess. */ 484 /* FIXME: is this really correct? */ 485 uint16_t lang_code = (string_descriptor[2 + 2 * i + 1] << 8) 486 + string_descriptor[2 + 2 * i]; 487 langs[i] = uint16_usb2host(lang_code); 488 } 489 490 free(string_descriptor); 491 492 *languages_ptr = langs; 493 *languages_count =langs_count; 494 495 return EOK; 496 } 497 498 /** Get string (descriptor) from USB device. 499 * 500 * The string is returned in native encoding of the operating system. 501 * For HelenOS, that is UTF-8. 502 * 503 * @param[in] pipe Control endpoint pipe (session must be already started). 504 * @param[in] index String index (in native endianess). 505 * @param[in] lang String language (in native endianess). 506 * @param[out] string_ptr Where to store allocated string in native encoding. 507 * @return Error code. 508 */ 509 int usb_request_get_string(usb_endpoint_pipe_t *pipe, 510 size_t index, l18_win_locales_t lang, char **string_ptr) 511 { 512 if (string_ptr == NULL) { 513 return EBADMEM; 514 } 515 /* Index is actually one byte value. */ 516 if (index > 0xFF) { 517 return ERANGE; 518 } 519 /* Language is actually two byte value. */ 520 if (lang > 0xFFFF) { 521 return ERANGE; 522 } 523 524 int rc; 525 526 /* Prepare dynamically allocated variables. */ 527 uint8_t *string = NULL; 528 wchar_t *string_chars = NULL; 529 530 /* Get the actual descriptor. */ 531 size_t string_size; 532 rc = usb_request_get_descriptor_alloc(pipe, 533 USB_REQUEST_TYPE_STANDARD, USB_DESCTYPE_STRING, 534 index, uint16_host2usb(lang), 535 (void **) &string, &string_size); 536 if (rc != EOK) { 537 goto leave; 538 } 539 540 if (string_size <= 2) { 541 rc = EEMPTY; 542 goto leave; 543 } 544 /* Substract first 2 bytes (length and descriptor type). */ 545 string_size -= 2; 546 547 /* Odd number of bytes - descriptor is broken? */ 548 if ((string_size % 2) != 0) { 549 /* FIXME: shall we return with error or silently ignore? */ 550 rc = ESTALL; 551 goto leave; 552 } 553 554 size_t string_char_count = string_size / 2; 555 string_chars = malloc(sizeof(wchar_t) * (string_char_count + 1)); 556 if (string_chars == NULL) { 557 rc = ENOMEM; 558 goto leave; 559 } 560 561 /* 562 * Build a wide string. 563 * And do not forget to set NULL terminator (string descriptors 564 * do not have them). 565 */ 566 size_t i; 567 for (i = 0; i < string_char_count; i++) { 568 uint16_t uni_char = (string[2 + 2 * i + 1] << 8) 569 + string[2 + 2 * i]; 570 string_chars[i] = uni_char; 571 } 572 string_chars[string_char_count] = 0; 573 574 575 /* Convert to normal string. */ 576 char *str = wstr_to_astr(string_chars); 577 if (str == NULL) { 578 rc = ENOMEM; 579 goto leave; 580 } 581 582 *string_ptr = str; 583 rc = EOK; 584 585 leave: 586 if (string != NULL) { 587 free(string); 588 } 589 if (string_chars != NULL) { 590 free(string_chars); 591 } 592 593 return rc; 594 } 595 356 596 /** 357 597 * @} -
uspace/lib/usb/src/usbdevice.c
r15b0432 rca56afa 37 37 #include <usb_iface.h> 38 38 #include <usb/usbdevice.h> 39 #include <usb/debug.h> 39 40 #include <errno.h> 41 #include <assert.h> 40 42 41 43 /** Find host controller handle that is ancestor of given device. … … 55 57 56 58 devman_handle_t h; 59 usb_log_debug("asking for HC handle (my handle is %zu).\n", device_handle); 57 60 int rc = async_req_1_1(parent_phone, DEV_IFACE_ID(USB_DEV_IFACE), 58 61 IPC_M_USB_GET_HOST_CONTROLLER_HANDLE, &h); … … 78 81 */ 79 82 int usb_hc_connection_initialize_from_device(usb_hc_connection_t *connection, 80 d evice_t *device)83 ddf_dev_t *device) 81 84 { 82 85 assert(connection);
Note:
See TracChangeset
for help on using the changeset viewer.
