request.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2011 Vojtech Horky
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  *
00009  * - Redistributions of source code must retain the above copyright
00010  *   notice, this list of conditions and the following disclaimer.
00011  * - Redistributions in binary form must reproduce the above copyright
00012  *   notice, this list of conditions and the following disclaimer in the
00013  *   documentation and/or other materials provided with the distribution.
00014  * - The name of the author may not be used to endorse or promote products
00015  *   derived from this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
00018  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00019  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
00020  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
00021  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
00022  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00023  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00024  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00025  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00026  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
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          * TODO: check that @p request_type and @p recipient are
00082          * within ranges.
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          * TODO: check that @p request_type and @p recipient are
00142          * within ranges.
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         /* TODO: prevent other from accessing wire now. */
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          * Get only first byte to retrieve descriptor length.
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                 /* FIXME: some better error code? */
00358                 return ESTALL;
00359         }
00360 
00361         size_t size = tmp_buffer[0];
00362         if (size == 0) {
00363                 /* FIXME: some better error code? */
00364                 return ESTALL;
00365         }
00366 
00367         /*
00368          * Allocate buffer and get the descriptor again.
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                 /* FIXME: some better error code? */
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         /* Verify that all data has been transferred. */
00422         if (actually_transferred < sizeof(descriptor_tmp)) {
00423                 return ELIMIT;
00424         }
00425 
00426         /* Everything is okay, copy the descriptor. */
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         /* Verify that all data has been transferred. */
00467         if (actually_transferred < sizeof(descriptor_tmp)) {
00468                 return ELIMIT;
00469         }
00470 
00471         /* Everything is okay, copy the descriptor. */
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         /* Everything looks okay, copy the pointers. */
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         /* FIXME: proper endianness. */
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         /* Subtract first 2 bytes (length and descriptor type). */
00737         string_descriptor_size -= 2;
00738 
00739         /* Odd number of bytes - descriptor is broken? */
00740         if ((string_descriptor_size % 2) != 0) {
00741                 /* FIXME: shall we return with error or silently ignore? */
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                 /* Language code from the descriptor is in USB endianness. */
00757                 /* FIXME: is this really correct? */
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          * Index is actually one byte value and zero index is used
00791          * to retrieve list of supported languages.
00792          */
00793         if ((index < 1) || (index > 0xFF)) {
00794                 return ERANGE;
00795         }
00796         /* Language is actually two byte value. */
00797         if (lang > 0xFFFF) {
00798                 return ERANGE;
00799         }
00800 
00801         int rc;
00802 
00803         /* Prepare dynamically allocated variables. */
00804         uint8_t *string = NULL;
00805         wchar_t *string_chars = NULL;
00806 
00807         /* Get the actual descriptor. */
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         /* Subtract first 2 bytes (length and descriptor type). */
00822         string_size -= 2;
00823 
00824         /* Odd number of bytes - descriptor is broken? */
00825         if ((string_size % 2) != 0) {
00826                 /* FIXME: shall we return with error or silently ignore? */
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          * Build a wide string.
00840          * And do not forget to set NULL terminator (string descriptors
00841          * do not have them).
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         /* Convert to normal string. */
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 

Generated on Thu Jun 2 07:45:48 2011 for HelenOS/USB by  doxygen 1.4.7