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