Changeset 9d9ffdd in mainline for uspace/drv/usbhid/hiddev.c


Ignore:
Timestamp:
2011-03-11T15:42:43Z (14 years ago)
Author:
Matej Klonfar <maklf@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
0bd4810c
Parents:
60a228f (diff), a8def7d (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.
Message:

merge with hidd

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/usbhid/hiddev.c

    r60a228f r9d9ffdd  
    5353/* Non-API functions                                                          */
    5454/*----------------------------------------------------------------------------*/
    55 
     55/**
     56 * Retreives HID Report descriptor from the device.
     57 *
     58 * This function first parses the HID descriptor from the Interface descriptor
     59 * to get the size of the Report descriptor and then requests the Report
     60 * descriptor from the device.
     61 *
     62 * @param hid_dev HID device structure.
     63 * @param config_desc Full configuration descriptor (including all nested
     64 *                    descriptors).
     65 * @param config_desc_size Size of the full configuration descriptor (in bytes).
     66 * @param iface_desc Pointer to the interface descriptor inside the full
     67 *                   configuration descriptor (@a config_desc) for the interface
     68 *                   assigned with this device (@a hid_dev).
     69 *
     70 * @retval EOK if successful.
     71 * @retval ENOENT if no HID descriptor could be found.
     72 * @retval EINVAL if the HID descriptor  or HID report descriptor have different
     73 *                size than expected.
     74 * @retval ENOMEM if some allocation failed.
     75 * @return Other value inherited from function usb_request_get_descriptor().
     76 *
     77 * @sa usb_request_get_descriptor()
     78 */
    5679static int usbhid_dev_get_report_descriptor(usbhid_dev_t *hid_dev,
    5780    uint8_t *config_desc, size_t config_desc_size, uint8_t *iface_desc)
     
    135158        }
    136159       
     160        hid_dev->report_desc_size = length;
     161       
    137162        usb_log_debug("Done.\n");
    138163       
     
    141166
    142167/*----------------------------------------------------------------------------*/
    143 
     168/**
     169 * Retreives descriptors from the device, initializes pipes and stores
     170 * important information from descriptors.
     171 *
     172 * Initializes the polling pipe described by the given endpoint description
     173 * (@a poll_ep_desc).
     174 *
     175 * Information retreived from descriptors and stored in the HID device structure:
     176 *    - Assigned interface number (the interface controlled by this instance of
     177 *                                 the driver)
     178 *    - Polling interval (from the interface descriptor)
     179 *    - Report descriptor
     180 *
     181 * @param hid_dev HID device structure to be initialized.
     182 * @param poll_ep_desc Description of the polling (Interrupt In) endpoint
     183 *                     that has to be present in the device in order to
     184 *                     successfuly initialize the structure.
     185 *
     186 * @sa usb_endpoint_pipe_initialize_from_configuration(),
     187 *     usbhid_dev_get_report_descriptor()
     188 */
    144189static int usbhid_dev_process_descriptors(usbhid_dev_t *hid_dev,
    145190    usb_endpoint_description_t *poll_ep_desc)
     
    149194        usb_log_info("Processing descriptors...\n");
    150195       
    151         // get the first configuration descriptor
    152         usb_standard_configuration_descriptor_t config_desc;
    153        
    154196        int rc;
    155         rc = usb_request_get_bare_configuration_descriptor(&hid_dev->ctrl_pipe,
    156             0, &config_desc);
    157        
    158         if (rc != EOK) {
    159                 usb_log_error("Failed to get bare config descriptor: %s.\n",
     197
     198        uint8_t *descriptors = NULL;
     199        size_t descriptors_size;
     200        rc = usb_request_get_full_configuration_descriptor_alloc(
     201            &hid_dev->ctrl_pipe, 0, (void **) &descriptors, &descriptors_size);
     202        if (rc != EOK) {
     203                usb_log_error("Failed to retrieve config descriptor: %s.\n",
    160204                    str_error(rc));
    161205                return rc;
    162         }
    163        
    164         // prepare space for all underlying descriptors
    165         uint8_t *descriptors = (uint8_t *)malloc(config_desc.total_length);
    166         if (descriptors == NULL) {
    167                 usb_log_error("No memory!.\n");
    168                 return ENOMEM;
    169         }
    170        
    171         size_t transferred = 0;
    172         // get full configuration descriptor
    173         rc = usb_request_get_full_configuration_descriptor(&hid_dev->ctrl_pipe,
    174             0, descriptors, config_desc.total_length, &transferred);
    175        
    176         if (rc != EOK) {
    177                 usb_log_error("Failed to get full config descriptor: %s.\n",
    178                     str_error(rc));
    179                 free(descriptors);
    180                 return rc;
    181         }
    182        
    183         if (transferred != config_desc.total_length) {
    184                 usb_log_error("Configuration descriptor has wrong size (%u, "
    185                     "expected %u).\n", transferred, config_desc.total_length);
    186                 free(descriptors);
    187                 return ELIMIT;
    188206        }
    189207       
     
    201219       
    202220        rc = usb_endpoint_pipe_initialize_from_configuration(
    203             endpoint_mapping, 1, descriptors, config_desc.total_length,
     221            endpoint_mapping, 1, descriptors, descriptors_size,
    204222            &hid_dev->wire);
    205223       
     
    233251        assert(endpoint_mapping[0].interface != NULL);
    234252       
    235         rc = usbhid_dev_get_report_descriptor(hid_dev, descriptors, transferred,
     253        /*
     254         * Save polling interval
     255         */
     256        hid_dev->poll_interval = endpoint_mapping[0].descriptor->poll_interval;
     257        assert(hid_dev->poll_interval > 0);
     258       
     259        rc = usbhid_dev_get_report_descriptor(hid_dev,
     260            descriptors, descriptors_size,
    236261            (uint8_t *)endpoint_mapping[0].interface);
    237262       
     
    239264       
    240265        if (rc != EOK) {
    241                 usb_log_warning("Problem with parsing Report descriptor: %s.\n",
     266                usb_log_warning("Problem with getting Report descriptor: %s.\n",
    242267                    str_error(rc));
    243268                return rc;
    244269        }
     270       
     271        rc = usb_hid_parse_report_descriptor(hid_dev->parser,
     272            hid_dev->report_desc, hid_dev->report_desc_size);
     273        if (rc != EOK) {
     274                usb_log_warning("Problem parsing Report descriptor: %s.\n",
     275                    str_error(rc));
     276                return rc;
     277        }
     278       
     279        usb_hid_descriptor_print(hid_dev->parser);
    245280       
    246281        return EOK;
     
    250285/* API functions                                                              */
    251286/*----------------------------------------------------------------------------*/
    252 
     287/**
     288 * Creates new uninitialized HID device structure.
     289 *
     290 * @return Pointer to the new HID device structure, or NULL if an error occured.
     291 */
    253292usbhid_dev_t *usbhid_dev_new(void)
    254293{
     
    263302        memset(dev, 0, sizeof(usbhid_dev_t));
    264303       
     304        dev->parser = (usb_hid_report_parser_t *)(malloc(sizeof(
     305            usb_hid_report_parser_t)));
     306        if (dev->parser == NULL) {
     307                usb_log_fatal("No memory!\n");
     308                free(dev);
     309                return NULL;
     310        }
     311       
    265312        dev->initialized = 0;
    266313       
     
    269316
    270317/*----------------------------------------------------------------------------*/
    271 
     318/**
     319 * Properly destroys the HID device structure.
     320 *
     321 * @note Currently does not clean-up the used pipes, as there are no functions
     322 *       offering such functionality.
     323 *
     324 * @param hid_dev Pointer to the structure to be destroyed.
     325 */
    272326void usbhid_dev_free(usbhid_dev_t **hid_dev)
    273327{
     
    292346
    293347/*----------------------------------------------------------------------------*/
    294 
     348/**
     349 * Initializes HID device structure.
     350 *
     351 * @param hid_dev HID device structure to be initialized.
     352 * @param dev DDF device representing the HID device.
     353 * @param poll_ep_desc Description of the polling (Interrupt In) endpoint
     354 *                     that has to be present in the device in order to
     355 *                     successfuly initialize the structure.
     356 *
     357 * @retval EOK if successful.
     358 * @retval EINVAL if some argument is missing.
     359 * @return Other value inherited from one of functions
     360 *         usb_device_connection_initialize_from_device(),
     361 *         usb_endpoint_pipe_initialize_default_control(),
     362 *         usb_endpoint_pipe_start_session(), usb_endpoint_pipe_end_session(),
     363 *         usbhid_dev_process_descriptors().
     364 *
     365 * @sa usbhid_dev_process_descriptors()
     366 */
    295367int usbhid_dev_init(usbhid_dev_t *hid_dev, ddf_dev_t *dev,
    296368    usb_endpoint_description_t *poll_ep_desc)
     
    339411                return rc;
    340412        }
     413       
     414        /*
     415         * Initialize the report parser.
     416         */
     417        rc = usb_hid_parser_init(hid_dev->parser);
     418        if (rc != EOK) {
     419                usb_log_error("Failed to initialize report parser.\n");
     420                return rc;
     421        }
    341422
    342423        /*
    343424         * Get descriptors, parse descriptors and save endpoints.
    344425         */
    345         usb_endpoint_pipe_start_session(&hid_dev->ctrl_pipe);
     426        rc = usb_endpoint_pipe_start_session(&hid_dev->ctrl_pipe);
     427        if (rc != EOK) {
     428                usb_log_error("Failed to start session on the control pipe: %s"
     429                    ".\n", str_error(rc));
     430                return rc;
     431        }
    346432       
    347433        rc = usbhid_dev_process_descriptors(hid_dev, poll_ep_desc);
    348        
    349         usb_endpoint_pipe_end_session(&hid_dev->ctrl_pipe);
    350         if (rc != EOK) {
     434        if (rc != EOK) {
     435                /* TODO: end session?? */
    351436                usb_log_error("Failed to process descriptors: %s.\n",
    352437                    str_error(rc));
     
    354439        }
    355440       
     441        rc = usb_endpoint_pipe_end_session(&hid_dev->ctrl_pipe);
     442        if (rc != EOK) {
     443                usb_log_warning("Failed to start session on the control pipe: "
     444                    "%s.\n", str_error(rc));
     445                return rc;
     446        }
     447       
    356448        hid_dev->initialized = 1;
    357449        usb_log_info("HID device structure initialized.\n");
Note: See TracChangeset for help on using the changeset viewer.