00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00035 #include <usb/dev/request.h>
00036 #include <errno.h>
00037 #include <assert.h>
00038 #include <usb/debug.h>
00039
00040 #define MAX_DATA_LENGTH ((size_t)(0xFFFF))
00041
00062 int usb_control_request_set(usb_pipe_t *pipe,
00063 usb_request_type_t request_type, usb_request_recipient_t recipient,
00064 uint8_t request,
00065 uint16_t value, uint16_t index,
00066 void *data, size_t data_size)
00067 {
00068 if (pipe == NULL) {
00069 return EBADMEM;
00070 }
00071
00072 if (data_size > MAX_DATA_LENGTH) {
00073 return ERANGE;
00074 }
00075
00076 if ((data_size > 0) && (data == NULL)) {
00077 return EBADMEM;
00078 }
00079
00080
00081
00082
00083
00084
00085 usb_device_request_setup_packet_t setup_packet;
00086 setup_packet.request_type = (request_type << 5) | recipient;
00087 setup_packet.request = request;
00088 setup_packet.value = value;
00089 setup_packet.index = index;
00090 setup_packet.length = (uint16_t) data_size;
00091
00092 int rc = usb_pipe_control_write(pipe,
00093 &setup_packet, sizeof(setup_packet),
00094 data, data_size);
00095
00096 return rc;
00097 }
00098
00122 int usb_control_request_get(usb_pipe_t *pipe,
00123 usb_request_type_t request_type, usb_request_recipient_t recipient,
00124 uint8_t request,
00125 uint16_t value, uint16_t index,
00126 void *data, size_t data_size, size_t *actual_data_size)
00127 {
00128 if (pipe == NULL) {
00129 return EBADMEM;
00130 }
00131
00132 if (data_size > MAX_DATA_LENGTH) {
00133 return ERANGE;
00134 }
00135
00136 if ((data_size > 0) && (data == NULL)) {
00137 return EBADMEM;
00138 }
00139
00140
00141
00142
00143
00144
00145 usb_device_request_setup_packet_t setup_packet;
00146 setup_packet.request_type = 128 | (request_type << 5) | recipient;
00147 setup_packet.request = request;
00148 setup_packet.value = value;
00149 setup_packet.index = index;
00150 setup_packet.length = (uint16_t) data_size;
00151
00152 int rc = usb_pipe_control_read(pipe,
00153 &setup_packet, sizeof(setup_packet),
00154 data, data_size, actual_data_size);
00155
00156 return rc;
00157 }
00158
00167 int usb_request_get_status(usb_pipe_t *pipe,
00168 usb_request_recipient_t recipient, uint16_t index,
00169 uint16_t *status)
00170 {
00171 if ((recipient == USB_REQUEST_RECIPIENT_DEVICE) && (index != 0)) {
00172 return EINVAL;
00173 }
00174
00175 if (status == NULL) {
00176 return EBADMEM;
00177 }
00178
00179 uint16_t status_usb_endianess;
00180 size_t data_transfered_size;
00181 int rc = usb_control_request_get(pipe, USB_REQUEST_TYPE_STANDARD,
00182 recipient, USB_DEVREQ_GET_STATUS, 0, uint16_host2usb(index),
00183 &status_usb_endianess, 2, &data_transfered_size);
00184 if (rc != EOK) {
00185 return rc;
00186 }
00187 if (data_transfered_size != 2) {
00188 return ELIMIT;
00189 }
00190
00191 *status = uint16_usb2host(status_usb_endianess);
00192
00193 return EOK;
00194 }
00195
00205 int usb_request_clear_feature(usb_pipe_t *pipe,
00206 usb_request_type_t request_type, usb_request_recipient_t recipient,
00207 uint16_t feature_selector, uint16_t index)
00208 {
00209 if (request_type == USB_REQUEST_TYPE_STANDARD) {
00210 if ((recipient == USB_REQUEST_RECIPIENT_DEVICE)
00211 && (index != 0)) {
00212 return EINVAL;
00213 }
00214 }
00215
00216 int rc = usb_control_request_set(pipe, request_type, recipient,
00217 USB_DEVREQ_CLEAR_FEATURE,
00218 uint16_host2usb(feature_selector), uint16_host2usb(index),
00219 NULL, 0);
00220
00221 return rc;
00222 }
00223
00233 int usb_request_set_feature(usb_pipe_t *pipe,
00234 usb_request_type_t request_type, usb_request_recipient_t recipient,
00235 uint16_t feature_selector, uint16_t index)
00236 {
00237 if (request_type == USB_REQUEST_TYPE_STANDARD) {
00238 if ((recipient == USB_REQUEST_RECIPIENT_DEVICE)
00239 && (index != 0)) {
00240 return EINVAL;
00241 }
00242 }
00243
00244 int rc = usb_control_request_set(pipe, request_type, recipient,
00245 USB_DEVREQ_SET_FEATURE,
00246 uint16_host2usb(feature_selector), uint16_host2usb(index),
00247 NULL, 0);
00248
00249 return rc;
00250 }
00251
00260 int usb_request_set_address(usb_pipe_t *pipe,
00261 usb_address_t new_address)
00262 {
00263 if ((new_address < 0) || (new_address >= USB11_ADDRESS_MAX)) {
00264 return EINVAL;
00265 }
00266
00267 uint16_t addr = uint16_host2usb((uint16_t)new_address);
00268
00269 int rc = usb_control_request_set(pipe,
00270 USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE,
00271 USB_DEVREQ_SET_ADDRESS,
00272 addr, 0,
00273 NULL, 0);
00274
00275 if (rc != EOK) {
00276 return rc;
00277 }
00278
00279 assert(pipe->wire != NULL);
00280
00281 pipe->wire->address = new_address;
00282
00283 return EOK;
00284 }
00285
00299 int usb_request_get_descriptor(usb_pipe_t *pipe,
00300 usb_request_type_t request_type, usb_request_recipient_t recipient,
00301 uint8_t descriptor_type, uint8_t descriptor_index,
00302 uint16_t language,
00303 void *buffer, size_t size, size_t *actual_size)
00304 {
00305 if (buffer == NULL) {
00306 return EBADMEM;
00307 }
00308 if (size == 0) {
00309 return EINVAL;
00310 }
00311
00312 uint16_t wValue = descriptor_index | (descriptor_type << 8);
00313
00314 return usb_control_request_get(pipe,
00315 request_type, recipient,
00316 USB_DEVREQ_GET_DESCRIPTOR,
00317 wValue, language,
00318 buffer, size, actual_size);
00319 }
00320
00333 int usb_request_get_descriptor_alloc(usb_pipe_t * pipe,
00334 usb_request_type_t request_type, usb_request_recipient_t recipient,
00335 uint8_t descriptor_type, uint8_t descriptor_index,
00336 uint16_t language,
00337 void **buffer_ptr, size_t *buffer_size)
00338 {
00339 if (buffer_ptr == NULL) {
00340 return EBADMEM;
00341 }
00342
00343 int rc;
00344
00345
00346
00347
00348 uint8_t tmp_buffer[1];
00349 size_t bytes_transfered;
00350 rc = usb_request_get_descriptor(pipe, request_type, recipient,
00351 descriptor_type, descriptor_index, language,
00352 &tmp_buffer, 1, &bytes_transfered);
00353 if (rc != EOK) {
00354 return rc;
00355 }
00356 if (bytes_transfered != 1) {
00357
00358 return ESTALL;
00359 }
00360
00361 size_t size = tmp_buffer[0];
00362 if (size == 0) {
00363
00364 return ESTALL;
00365 }
00366
00367
00368
00369
00370 void *buffer = malloc(size);
00371 if (buffer == NULL) {
00372 return ENOMEM;
00373 }
00374
00375 rc = usb_request_get_descriptor(pipe, request_type, recipient,
00376 descriptor_type, descriptor_index, language,
00377 buffer, size, &bytes_transfered);
00378 if (rc != EOK) {
00379 free(buffer);
00380 return rc;
00381 }
00382 if (bytes_transfered != size) {
00383 free(buffer);
00384
00385 return ESTALL;
00386 }
00387
00388 *buffer_ptr = buffer;
00389 if (buffer_size != NULL) {
00390 *buffer_size = size;
00391 }
00392
00393 return EOK;
00394 }
00395
00402 int usb_request_get_device_descriptor(usb_pipe_t *pipe,
00403 usb_standard_device_descriptor_t *descriptor)
00404 {
00405 if (descriptor == NULL) {
00406 return EBADMEM;
00407 }
00408
00409 size_t actually_transferred = 0;
00410 usb_standard_device_descriptor_t descriptor_tmp;
00411 int rc = usb_request_get_descriptor(pipe,
00412 USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE,
00413 USB_DESCTYPE_DEVICE, 0, 0,
00414 &descriptor_tmp, sizeof(descriptor_tmp),
00415 &actually_transferred);
00416
00417 if (rc != EOK) {
00418 return rc;
00419 }
00420
00421
00422 if (actually_transferred < sizeof(descriptor_tmp)) {
00423 return ELIMIT;
00424 }
00425
00426
00427 memcpy(descriptor, &descriptor_tmp,
00428 sizeof(descriptor_tmp));
00429
00430 return EOK;
00431 }
00432
00444 int usb_request_get_bare_configuration_descriptor(usb_pipe_t *pipe,
00445 int index, usb_standard_configuration_descriptor_t *descriptor)
00446 {
00447 if (descriptor == NULL) {
00448 return EBADMEM;
00449 }
00450
00451 if ((index < 0) || (index > 0xFF)) {
00452 return ERANGE;
00453 }
00454
00455 size_t actually_transferred = 0;
00456 usb_standard_configuration_descriptor_t descriptor_tmp;
00457 int rc = usb_request_get_descriptor(pipe,
00458 USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE,
00459 USB_DESCTYPE_CONFIGURATION, index, 0,
00460 &descriptor_tmp, sizeof(descriptor_tmp),
00461 &actually_transferred);
00462 if (rc != EOK) {
00463 return rc;
00464 }
00465
00466
00467 if (actually_transferred < sizeof(descriptor_tmp)) {
00468 return ELIMIT;
00469 }
00470
00471
00472 memcpy(descriptor, &descriptor_tmp,
00473 sizeof(descriptor_tmp));
00474
00475 return EOK;
00476 }
00477
00490 int usb_request_get_full_configuration_descriptor(usb_pipe_t *pipe,
00491 int index, void *descriptor, size_t descriptor_size, size_t *actual_size)
00492 {
00493 if ((index < 0) || (index > 0xFF)) {
00494 return ERANGE;
00495 }
00496
00497 return usb_request_get_descriptor(pipe,
00498 USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE,
00499 USB_DESCTYPE_CONFIGURATION, index, 0,
00500 descriptor, descriptor_size, actual_size);
00501 }
00502
00515 int usb_request_get_full_configuration_descriptor_alloc(
00516 usb_pipe_t *pipe, int index,
00517 void **descriptor_ptr, size_t *descriptor_size)
00518 {
00519 int rc;
00520
00521 if (descriptor_ptr == NULL) {
00522 return EBADMEM;
00523 }
00524
00525 usb_standard_configuration_descriptor_t bare_config;
00526 rc = usb_request_get_bare_configuration_descriptor(pipe, index,
00527 &bare_config);
00528 if (rc != EOK) {
00529 return rc;
00530 }
00531 if (bare_config.descriptor_type != USB_DESCTYPE_CONFIGURATION) {
00532 return ENOENT;
00533 }
00534 if (bare_config.total_length < sizeof(bare_config)) {
00535 return ELIMIT;
00536 }
00537
00538 void *buffer = malloc(bare_config.total_length);
00539 if (buffer == NULL) {
00540 return ENOMEM;
00541 }
00542
00543 size_t transferred = 0;
00544 rc = usb_request_get_full_configuration_descriptor(pipe, index,
00545 buffer, bare_config.total_length, &transferred);
00546 if (rc != EOK) {
00547 free(buffer);
00548 return rc;
00549 }
00550
00551 if (transferred != bare_config.total_length) {
00552 free(buffer);
00553 return ELIMIT;
00554 }
00555
00556
00557
00558 *descriptor_ptr = buffer;
00559
00560 if (descriptor_size != NULL) {
00561 *descriptor_size = bare_config.total_length;
00562 }
00563
00564 return EOK;
00565 }
00566
00579 int usb_request_set_descriptor(usb_pipe_t *pipe,
00580 usb_request_type_t request_type, usb_request_recipient_t recipient,
00581 uint8_t descriptor_type, uint8_t descriptor_index,
00582 uint16_t language,
00583 void *buffer, size_t size)
00584 {
00585 if (buffer == NULL) {
00586 return EBADMEM;
00587 }
00588 if (size == 0) {
00589 return EINVAL;
00590 }
00591
00592
00593 uint16_t wValue = descriptor_index | (descriptor_type << 8);
00594
00595 return usb_control_request_set(pipe,
00596 request_type, recipient,
00597 USB_DEVREQ_SET_DESCRIPTOR,
00598 wValue, language,
00599 buffer, size);
00600 }
00601
00608 int usb_request_get_configuration(usb_pipe_t *pipe,
00609 uint8_t *configuration_value)
00610 {
00611 uint8_t value;
00612 size_t actual_size;
00613
00614 int rc = usb_control_request_get(pipe,
00615 USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE,
00616 USB_DEVREQ_GET_CONFIGURATION,
00617 0, 0,
00618 &value, 1, &actual_size);
00619
00620 if (rc != EOK) {
00621 return rc;
00622 }
00623 if (actual_size != 1) {
00624 return ELIMIT;
00625 }
00626
00627 if (configuration_value != NULL) {
00628 *configuration_value = value;
00629 }
00630
00631 return EOK;
00632 }
00633
00640 int usb_request_set_configuration(usb_pipe_t *pipe,
00641 uint8_t configuration_value)
00642 {
00643 uint16_t config_value
00644 = uint16_host2usb((uint16_t) configuration_value);
00645
00646 return usb_control_request_set(pipe,
00647 USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE,
00648 USB_DEVREQ_SET_CONFIGURATION, config_value, 0,
00649 NULL, 0);
00650 }
00651
00659 int usb_request_get_interface(usb_pipe_t *pipe,
00660 uint8_t interface_index, uint8_t *alternate_setting)
00661 {
00662 uint8_t value;
00663 size_t actual_size;
00664
00665 int rc = usb_control_request_get(pipe,
00666 USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_INTERFACE,
00667 USB_DEVREQ_GET_INTERFACE,
00668 0, uint16_host2usb((uint16_t) interface_index),
00669 &value, 1, &actual_size);
00670
00671 if (rc != EOK) {
00672 return rc;
00673 }
00674 if (actual_size != 1) {
00675 return ELIMIT;
00676 }
00677
00678 if (alternate_setting != NULL) {
00679 *alternate_setting = value;
00680 }
00681
00682 return EOK;
00683 }
00684
00692 int usb_request_set_interface(usb_pipe_t *pipe,
00693 uint8_t interface_index, uint8_t alternate_setting)
00694 {
00695 return usb_control_request_set(pipe,
00696 USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_INTERFACE,
00697 USB_DEVREQ_SET_INTERFACE,
00698 uint16_host2usb((uint16_t) alternate_setting),
00699 uint16_host2usb((uint16_t) interface_index),
00700 NULL, 0);
00701 }
00702
00711 int usb_request_get_supported_languages(usb_pipe_t *pipe,
00712 l18_win_locales_t **languages_ptr, size_t *languages_count)
00713 {
00714 int rc;
00715
00716 if (languages_ptr == NULL) {
00717 return EBADMEM;
00718 }
00719 if (languages_count == NULL) {
00720 return EBADMEM;
00721 }
00722
00723 uint8_t *string_descriptor = NULL;
00724 size_t string_descriptor_size = 0;
00725 rc = usb_request_get_descriptor_alloc(pipe,
00726 USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE,
00727 USB_DESCTYPE_STRING, 0, 0,
00728 (void **) &string_descriptor, &string_descriptor_size);
00729 if (rc != EOK) {
00730 return rc;
00731 }
00732 if (string_descriptor_size <= 2) {
00733 free(string_descriptor);
00734 return EEMPTY;
00735 }
00736
00737 string_descriptor_size -= 2;
00738
00739
00740 if ((string_descriptor_size % 2) != 0) {
00741
00742 free(string_descriptor);
00743 return ESTALL;
00744 }
00745
00746 size_t langs_count = string_descriptor_size / 2;
00747 l18_win_locales_t *langs
00748 = malloc(sizeof(l18_win_locales_t) * langs_count);
00749 if (langs == NULL) {
00750 free(string_descriptor);
00751 return ENOMEM;
00752 }
00753
00754 size_t i;
00755 for (i = 0; i < langs_count; i++) {
00756
00757
00758 uint16_t lang_code = (string_descriptor[2 + 2 * i + 1] << 8)
00759 + string_descriptor[2 + 2 * i];
00760 langs[i] = uint16_usb2host(lang_code);
00761 }
00762
00763 free(string_descriptor);
00764
00765 *languages_ptr = langs;
00766 *languages_count =langs_count;
00767
00768 return EOK;
00769 }
00770
00783 int usb_request_get_string(usb_pipe_t *pipe,
00784 size_t index, l18_win_locales_t lang, char **string_ptr)
00785 {
00786 if (string_ptr == NULL) {
00787 return EBADMEM;
00788 }
00789
00790
00791
00792
00793 if ((index < 1) || (index > 0xFF)) {
00794 return ERANGE;
00795 }
00796
00797 if (lang > 0xFFFF) {
00798 return ERANGE;
00799 }
00800
00801 int rc;
00802
00803
00804 uint8_t *string = NULL;
00805 wchar_t *string_chars = NULL;
00806
00807
00808 size_t string_size;
00809 rc = usb_request_get_descriptor_alloc(pipe,
00810 USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE,
00811 USB_DESCTYPE_STRING, index, uint16_host2usb(lang),
00812 (void **) &string, &string_size);
00813 if (rc != EOK) {
00814 goto leave;
00815 }
00816
00817 if (string_size <= 2) {
00818 rc = EEMPTY;
00819 goto leave;
00820 }
00821
00822 string_size -= 2;
00823
00824
00825 if ((string_size % 2) != 0) {
00826
00827 rc = ESTALL;
00828 goto leave;
00829 }
00830
00831 size_t string_char_count = string_size / 2;
00832 string_chars = malloc(sizeof(wchar_t) * (string_char_count + 1));
00833 if (string_chars == NULL) {
00834 rc = ENOMEM;
00835 goto leave;
00836 }
00837
00838
00839
00840
00841
00842
00843 size_t i;
00844 for (i = 0; i < string_char_count; i++) {
00845 uint16_t uni_char = (string[2 + 2 * i + 1] << 8)
00846 + string[2 + 2 * i];
00847 string_chars[i] = uni_char;
00848 }
00849 string_chars[string_char_count] = 0;
00850
00851
00852
00853 char *str = wstr_to_astr(string_chars);
00854 if (str == NULL) {
00855 rc = ENOMEM;
00856 goto leave;
00857 }
00858
00859 *string_ptr = str;
00860 rc = EOK;
00861
00862 leave:
00863 if (string != NULL) {
00864 free(string);
00865 }
00866 if (string_chars != NULL) {
00867 free(string_chars);
00868 }
00869
00870 return rc;
00871 }
00872
00879 int usb_request_clear_endpoint_halt(usb_pipe_t *pipe, uint16_t ep_index)
00880 {
00881 return usb_request_clear_feature(pipe,
00882 USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_ENDPOINT,
00883 uint16_host2usb(USB_FEATURE_SELECTOR_ENDPOINT_HALT),
00884 uint16_host2usb(ep_index));
00885 }
00886
00893 int usb_pipe_clear_halt(usb_pipe_t *ctrl_pipe, usb_pipe_t *target_pipe)
00894 {
00895 if ((ctrl_pipe == NULL) || (target_pipe == NULL)) {
00896 return EINVAL;
00897 }
00898 return usb_request_clear_endpoint_halt(ctrl_pipe,
00899 target_pipe->endpoint_no);
00900 }
00901
00909 int usb_request_get_endpoint_status(usb_pipe_t *ctrl_pipe, usb_pipe_t *pipe,
00910 uint16_t *status)
00911 {
00912 uint16_t status_tmp;
00913 uint16_t pipe_index = (uint16_t) pipe->endpoint_no;
00914 int rc = usb_request_get_status(ctrl_pipe,
00915 USB_REQUEST_RECIPIENT_ENDPOINT, uint16_host2usb(pipe_index),
00916 &status_tmp);
00917 if (rc != EOK) {
00918 return rc;
00919 }
00920
00921 if (status != NULL) {
00922 *status = uint16_usb2host(status_tmp);
00923 }
00924
00925 return EOK;
00926 }
00927