Changes in uspace/lib/usbdev/src/request.c [58563585:9d58539] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/usbdev/src/request.c
r58563585 r9d58539 34 34 */ 35 35 #include <usb/dev/request.h> 36 #include <usb/request.h>37 #include <usb/usb.h>38 39 36 #include <errno.h> 40 #include <mem.h> 41 #include <stdlib.h> 42 #include <str.h> 37 #include <assert.h> 38 #include <usb/debug.h> 43 39 44 40 #define MAX_DATA_LENGTH ((size_t)(0xFFFF)) 45 41 46 static_assert(sizeof(usb_device_request_setup_packet_t) == 8);47 48 42 /** Generic wrapper for SET requests using standard control request format. 49 43 * 50 44 * @see usb_pipe_control_write 51 45 * 52 * @param pipe 46 * @param pipe Pipe used for the communication. 53 47 * @param request_type Request type (standard/class/vendor). 54 * @param recipient Request recipient (e.g. device or endpoint). 55 * @param request Actual request (e.g. GET_DESCRIPTOR). 56 * @param value Value of @c wValue field of setup packet 57 * (must be in USB endianness). 58 * @param index Value of @c wIndex field of setup packet 59 * (must be in USB endianness). 60 * @param data Data to be sent during DATA stage 61 * (expected to be in USB endianness). 62 * @param data_size Size of the @p data buffer (in native endianness). 63 * 48 * @param recipient Request recipient (e.g. device or endpoint). 49 * @param request Actual request (e.g. GET_DESCRIPTOR). 50 * @param value Value of @c wValue field of setup packet 51 * (must be in USB endianness). 52 * @param index Value of @c wIndex field of setup packet 53 * (must be in USB endianness). 54 * @param data Data to be sent during DATA stage 55 * (expected to be in USB endianness). 56 * @param data_size Size of the @p data buffer (in native endianness). 64 57 * @return Error code. 65 58 * @retval EBADMEM @p pipe is NULL. 66 59 * @retval EBADMEM @p data is NULL and @p data_size is not zero. 67 60 * @retval ERANGE Data buffer too large. 68 *69 61 */ 70 62 int usb_control_request_set(usb_pipe_t *pipe, 71 63 usb_request_type_t request_type, usb_request_recipient_t recipient, 72 uint8_t request, uint16_t value, uint16_t index, 73 const void *data, size_t data_size) 64 uint8_t request, 65 uint16_t value, uint16_t index, 66 void *data, size_t data_size) 74 67 { 75 68 if (pipe == NULL) { … … 90 83 */ 91 84 85 usb_device_request_setup_packet_t setup_packet; 86 setup_packet.request_type = (request_type << 5) | recipient; 87 setup_packet.request = request; 88 setup_packet.value = value; 89 setup_packet.index = index; 90 setup_packet.length = (uint16_t) data_size; 91 92 int rc = usb_pipe_control_write(pipe, 93 &setup_packet, sizeof(setup_packet), 94 data, data_size); 95 96 return rc; 97 } 98 99 /** Generic wrapper for GET requests using standard control request format. 100 * 101 * @see usb_pipe_control_read 102 * 103 * @param pipe Pipe used for the communication. 104 * @param request_type Request type (standard/class/vendor). 105 * @param recipient Request recipient (e.g. device or endpoint). 106 * @param request Actual request (e.g. GET_DESCRIPTOR). 107 * @param value Value of @c wValue field of setup packet 108 * (must be in USB endianness). 109 * @param index Value of @c wIndex field of setup packet 110 * (must be in USB endianness). 111 * @param data Buffer where to store data accepted during the DATA stage. 112 * (they will come in USB endianness). 113 * @param data_size Size of the @p data buffer 114 * (in native endianness). 115 * @param actual_data_size Actual size of transfered data 116 * (in native endianness). 117 * @return Error code. 118 * @retval EBADMEM @p pipe is NULL. 119 * @retval EBADMEM @p data is NULL and @p data_size is not zero. 120 * @retval ERANGE Data buffer too large. 121 */ 122 int usb_control_request_get(usb_pipe_t *pipe, 123 usb_request_type_t request_type, usb_request_recipient_t recipient, 124 uint8_t request, 125 uint16_t value, uint16_t index, 126 void *data, size_t data_size, size_t *actual_data_size) 127 { 128 if (pipe == NULL) { 129 return EBADMEM; 130 } 131 132 if (data_size > MAX_DATA_LENGTH) { 133 return ERANGE; 134 } 135 136 if ((data_size > 0) && (data == NULL)) { 137 return EBADMEM; 138 } 139 140 /* 141 * TODO: check that @p request_type and @p recipient are 142 * within ranges. 143 */ 144 92 145 const usb_device_request_setup_packet_t setup_packet = { 93 .request_type = (request_type << 5) | recipient, 146 .request_type = SETUP_REQUEST_TYPE_DEVICE_TO_HOST 147 | (request_type << 5) | recipient, 94 148 .request = request, 95 149 .value = value, … … 98 152 }; 99 153 100 return usb_pipe_control_write(pipe,101 &setup_packet, sizeof(setup_packet), data, data_size);102 }103 104 /** Generic wrapper for GET requests using standard control request format.105 *106 * @see usb_pipe_control_read107 *108 * @param pipe Pipe used for the communication.109 * @param request_type Request type (standard/class/vendor).110 * @param recipient Request recipient (e.g. device or endpoint).111 * @param request Actual request (e.g. GET_DESCRIPTOR).112 * @param value Value of @c wValue field of setup packet113 * (must be in USB endianness).114 * @param index Value of @c wIndex field of setup packet115 * (must be in USB endianness).116 * @param data Buffer where to store data accepted during117 * the DATA stage (they will come in USB endianness).118 * @param data_size Size of the @p data buffer119 * (in native endianness).120 * @param actual_data_size Actual size of transfered data121 * (in native endianness).122 *123 * @return Error code.124 * @retval EBADMEM @p pipe is NULL.125 * @retval EBADMEM @p data is NULL and @p data_size is not zero.126 * @retval ERANGE Data buffer too large.127 *128 */129 int usb_control_request_get(usb_pipe_t *pipe,130 usb_request_type_t request_type, usb_request_recipient_t recipient,131 uint8_t request, uint16_t value, uint16_t index,132 void *data, size_t data_size, size_t *actual_data_size)133 {134 if (pipe == NULL) {135 return EBADMEM;136 }137 138 if (data_size > MAX_DATA_LENGTH) {139 return ERANGE;140 }141 142 if ((data_size > 0) && (data == NULL)) {143 return EBADMEM;144 }145 146 /*147 * TODO: check that @p request_type and @p recipient are148 * within ranges.149 */150 151 const usb_device_request_setup_packet_t setup_packet = {152 .request_type = SETUP_REQUEST_TYPE_DEVICE_TO_HOST153 | (request_type << 5) | recipient,154 .request = request,155 .value = uint16_host2usb(value),156 .index = uint16_host2usb(index),157 .length = uint16_host2usb(data_size),158 };159 160 154 return usb_pipe_control_read(pipe, &setup_packet, sizeof(setup_packet), 161 155 data, data_size, actual_data_size); … … 213 207 { 214 208 if (request_type == USB_REQUEST_TYPE_STANDARD) { 215 if ((recipient == USB_REQUEST_RECIPIENT_DEVICE) && (index != 0)) { 209 if ((recipient == USB_REQUEST_RECIPIENT_DEVICE) 210 && (index != 0)) { 216 211 return EINVAL; 217 212 } 218 213 } 219 214 220 return usb_control_request_set(pipe, 221 request_type, recipient, USB_DEVREQ_CLEAR_FEATURE, 222 uint16_host2usb(feature_selector), uint16_host2usb(index), NULL, 0); 215 int rc = usb_control_request_set(pipe, request_type, recipient, 216 USB_DEVREQ_CLEAR_FEATURE, 217 uint16_host2usb(feature_selector), uint16_host2usb(index), 218 NULL, 0); 219 220 return rc; 223 221 } 224 222 … … 237 235 { 238 236 if (request_type == USB_REQUEST_TYPE_STANDARD) { 239 if ((recipient == USB_REQUEST_RECIPIENT_DEVICE) && (index != 0)) { 237 if ((recipient == USB_REQUEST_RECIPIENT_DEVICE) 238 && (index != 0)) { 240 239 return EINVAL; 241 240 } 242 241 } 243 242 244 return usb_control_request_set(pipe, 245 request_type, recipient, USB_DEVREQ_SET_FEATURE, 246 uint16_host2usb(feature_selector), uint16_host2usb(index), NULL, 0); 243 int rc = usb_control_request_set(pipe, request_type, recipient, 244 USB_DEVREQ_SET_FEATURE, 245 uint16_host2usb(feature_selector), uint16_host2usb(index), 246 NULL, 0); 247 248 return rc; 247 249 } 248 250 … … 273 275 } 274 276 275 /*276 * The wValue field specifies the descriptor type in the high byte277 * and the descriptor index in the low byte. USB 1.1 spec p. 189278 */279 277 const uint16_t wValue = descriptor_index | (descriptor_type << 8); 280 278 … … 313 311 * Get only first byte to retrieve descriptor length. 314 312 */ 315 uint8_t tmp_buffer ;313 uint8_t tmp_buffer[1]; 316 314 size_t bytes_transfered; 317 315 rc = usb_request_get_descriptor(pipe, request_type, recipient, 318 316 descriptor_type, descriptor_index, language, 319 &tmp_buffer, sizeof(tmp_buffer), &bytes_transfered);317 &tmp_buffer, 1, &bytes_transfered); 320 318 if (rc != EOK) { 321 319 return rc; 322 320 } 323 321 if (bytes_transfered != 1) { 324 return ELIMIT; 325 } 326 327 const size_t size = tmp_buffer; 322 /* FIXME: some better error code? */ 323 return ESTALL; 324 } 325 326 size_t size = tmp_buffer[0]; 328 327 if (size == 0) { 329 return ELIMIT; 328 /* FIXME: some better error code? */ 329 return ESTALL; 330 330 } 331 331 … … 347 347 if (bytes_transfered != size) { 348 348 free(buffer); 349 return ELIMIT; 349 /* FIXME: some better error code? */ 350 return ESTALL; 350 351 } 351 352 … … 374 375 usb_standard_device_descriptor_t descriptor_tmp; 375 376 int rc = usb_request_get_descriptor(pipe, 376 USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE, 377 USB_DESCTYPE_DEVICE, 0, 0, &descriptor_tmp, sizeof(descriptor_tmp), 377 USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE, 378 USB_DESCTYPE_DEVICE, 0, 0, 379 &descriptor_tmp, sizeof(descriptor_tmp), 378 380 &actually_transferred); 379 381 … … 417 419 size_t actually_transferred = 0; 418 420 usb_standard_configuration_descriptor_t descriptor_tmp; 419 constint rc = usb_request_get_descriptor(pipe,421 int rc = usb_request_get_descriptor(pipe, 420 422 USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE, 421 423 USB_DESCTYPE_CONFIGURATION, index, 0, … … 433 435 /* Everything is okay, copy the descriptor. */ 434 436 memcpy(descriptor, &descriptor_tmp, sizeof(descriptor_tmp)); 437 435 438 return EOK; 436 439 } … … 475 478 int usb_request_get_full_configuration_descriptor_alloc( 476 479 usb_pipe_t *pipe, int index, 477 constvoid **descriptor_ptr, size_t *descriptor_size)480 void **descriptor_ptr, size_t *descriptor_size) 478 481 { 479 482 int rc; … … 492 495 return ENOENT; 493 496 } 494 495 const size_t total_length = uint16_usb2host(bare_config.total_length); 496 if (total_length < sizeof(bare_config)) { 497 if (bare_config.total_length < sizeof(bare_config)) { 497 498 return ELIMIT; 498 499 } 499 500 500 void *buffer = malloc( total_length);501 void *buffer = malloc(bare_config.total_length); 501 502 if (buffer == NULL) { 502 503 return ENOMEM; … … 505 506 size_t transferred = 0; 506 507 rc = usb_request_get_full_configuration_descriptor(pipe, index, 507 buffer, total_length, &transferred);508 buffer, bare_config.total_length, &transferred); 508 509 if (rc != EOK) { 509 510 free(buffer); … … 511 512 } 512 513 513 if (transferred != total_length) {514 if (transferred != bare_config.total_length) { 514 515 free(buffer); 515 516 return ELIMIT; … … 521 522 522 523 if (descriptor_size != NULL) { 523 *descriptor_size = total_length;524 *descriptor_size = bare_config.total_length; 524 525 } 525 526 … … 542 543 usb_request_type_t request_type, usb_request_recipient_t recipient, 543 544 uint8_t descriptor_type, uint8_t descriptor_index, 544 uint16_t language, const void *buffer, size_t size) 545 uint16_t language, 546 void *buffer, size_t size) 545 547 { 546 548 if (buffer == NULL) { … … 555 557 556 558 return usb_control_request_set(pipe, 557 request_type, recipient, USB_DEVREQ_SET_DESCRIPTOR, 558 wValue, language, buffer, size); 559 request_type, recipient, 560 USB_DEVREQ_SET_DESCRIPTOR, 561 wValue, language, 562 buffer, size); 559 563 } 560 564 … … 571 575 size_t actual_size; 572 576 573 constint rc = usb_control_request_get(pipe,577 int rc = usb_control_request_get(pipe, 574 578 USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE, 575 USB_DEVREQ_GET_CONFIGURATION, 0, 0, &value, 1, &actual_size); 579 USB_DEVREQ_GET_CONFIGURATION, 580 0, 0, 581 &value, 1, &actual_size); 576 582 577 583 if (rc != EOK) { … … 598 604 uint8_t configuration_value) 599 605 { 600 constuint16_t config_value606 uint16_t config_value 601 607 = uint16_host2usb((uint16_t) configuration_value); 602 608 … … 620 626 size_t actual_size; 621 627 622 constint rc = usb_control_request_get(pipe,628 int rc = usb_control_request_get(pipe, 623 629 USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_INTERFACE, 624 630 USB_DEVREQ_GET_INTERFACE, 625 631 0, uint16_host2usb((uint16_t) interface_index), 626 &value, sizeof(value), &actual_size);632 &value, 1, &actual_size); 627 633 628 634 if (rc != EOK) { … … 669 675 l18_win_locales_t **languages_ptr, size_t *languages_count) 670 676 { 671 if (languages_ptr == NULL || languages_count == NULL) { 677 int rc; 678 679 if (languages_ptr == NULL) { 680 return EBADMEM; 681 } 682 if (languages_count == NULL) { 672 683 return EBADMEM; 673 684 } … … 675 686 uint8_t *string_descriptor = NULL; 676 687 size_t string_descriptor_size = 0; 677 const intrc = usb_request_get_descriptor_alloc(pipe,688 rc = usb_request_get_descriptor_alloc(pipe, 678 689 USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE, 679 690 USB_DESCTYPE_STRING, 0, 0, … … 696 707 } 697 708 698 constsize_t langs_count = string_descriptor_size / 2;699 l18_win_locales_t *langs =700 calloc(langs_count, sizeof(l18_win_locales_t));709 size_t langs_count = string_descriptor_size / 2; 710 l18_win_locales_t *langs 711 = malloc(sizeof(l18_win_locales_t) * langs_count); 701 712 if (langs == NULL) { 702 713 free(string_descriptor); … … 704 715 } 705 716 706 for (size_t i = 0; i < langs_count; i++) { 717 size_t i; 718 for (i = 0; i < langs_count; i++) { 707 719 /* Language code from the descriptor is in USB endianness. */ 708 720 /* FIXME: is this really correct? */ 709 const uint16_t lang_code = 710 (string_descriptor[2 + 2 * i + 1] << 8) 721 uint16_t lang_code = (string_descriptor[2 + 2 * i + 1] << 8) 711 722 + string_descriptor[2 + 2 * i]; 712 723 langs[i] = uint16_usb2host(lang_code); … … 747 758 } 748 759 /* Language is actually two byte value. */ 749 if (lang > L18N_WIN_LOCALE_MAX) {760 if (lang > 0xFFFF) { 750 761 return ERANGE; 751 762 } … … 781 792 } 782 793 783 constsize_t string_char_count = string_size / 2;794 size_t string_char_count = string_size / 2; 784 795 string_chars = malloc(sizeof(wchar_t) * (string_char_count + 1)); 785 796 if (string_chars == NULL) { … … 793 804 * do not have them). 794 805 */ 795 for (size_t i = 0; i < string_char_count; i++) { 796 const uint16_t uni_char = (string[2 + 2 * i + 1] << 8) 806 size_t i; 807 for (i = 0; i < string_char_count; i++) { 808 uint16_t uni_char = (string[2 + 2 * i + 1] << 8) 797 809 + string[2 + 2 * i]; 798 810 string_chars[i] = uni_char; … … 812 824 813 825 leave: 814 free(string); 815 free(string_chars); 826 if (string != NULL) { 827 free(string); 828 } 829 if (string_chars != NULL) { 830 free(string_chars); 831 } 816 832 817 833 return rc; … … 828 844 return usb_request_clear_feature(pipe, 829 845 USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_ENDPOINT, 830 uint16_host2usb(USB_FEATURE_ ENDPOINT_HALT),846 uint16_host2usb(USB_FEATURE_SELECTOR_ENDPOINT_HALT), 831 847 uint16_host2usb(ep_index)); 832 848 }
Note:
See TracChangeset
for help on using the changeset viewer.