Changeset df6ded8 in mainline for uspace/drv/hid/usbhid/usbhid.c


Ignore:
Timestamp:
2018-02-28T16:37:50Z (6 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
1b20da0
Parents:
f5e5f73 (diff), b2dca8de (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.
git-author:
Jakub Jermar <jakub@…> (2018-02-28 16:06:42)
git-committer:
Jakub Jermar <jakub@…> (2018-02-28 16:37:50)
Message:

Merge github.com:helenos-xhci-team/helenos

This commit merges support for USB 3 and generally refactors, fixes,
extends and cleans up the existing USB framework.

Notable additions and features:

  • new host controller driver has been implemented to control various xHC models (among others, NEC Renesas uPD720200)
  • isochronous data transfer mode
  • support for explicit USB device removal
  • USB tablet driver
File:
1 edited

Legend:

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

    rf5e5f73 rdf6ded8  
    11/*
    22 * Copyright (c) 2011 Lubos Slovak
     3 * Copyright (c) 2018 Petr Manek, Ondrej Hlavaty
    34 * All rights reserved.
    45 *
     
    134135        usb_hid_report_path_t *usage_path = usb_hid_report_path();
    135136        if (usage_path == NULL) {
    136                 usb_log_debug("Failed to create usage path.\n");
     137                usb_log_debug("Failed to create usage path.");
    137138                return false;
    138139        }
     
    143144                    mapping->usage_path[i].usage_page,
    144145                    mapping->usage_path[i].usage) != EOK) {
    145                         usb_log_debug("Failed to append to usage path.\n");
     146                        usb_log_debug("Failed to append to usage path.");
    146147                        usb_hid_report_path_free(usage_path);
    147148                        return false;
     
    149150        }
    150151
    151         usb_log_debug("Compare flags: %d\n", mapping->compare);
     152        usb_log_debug("Compare flags: %d", mapping->compare);
    152153
    153154        bool matches = false;
     
    155156
    156157        do {
    157                 usb_log_debug("Trying report id %u\n", report_id);
     158                usb_log_debug("Trying report id %u", report_id);
    158159                if (report_id != 0) {
    159160                        usb_hid_report_path_set_report_id(usage_path,
     
    166167                        USB_HID_REPORT_TYPE_INPUT);
    167168
    168                 usb_log_debug("Field: %p\n", field);
     169                usb_log_debug("Field: %p", field);
    169170
    170171                if (field != NULL) {
     
    243244                            mapping->product_id);
    244245                        if (usb_hid_ids_match(hid_dev, mapping)) {
    245                                 usb_log_debug("IDs matched.\n");
     246                                usb_log_debug("IDs matched.");
    246247                                matched = true;
    247248                        }
     
    250251                /* Check usage match. */
    251252                if (mapping->usage_path != NULL) {
    252                         usb_log_debug("Comparing device against usage path.\n");
     253                        usb_log_debug("Comparing device against usage path.");
    253254                        if (usb_hid_path_matches(hid_dev, mapping)) {
    254255                                /* Does not matter if IDs were matched. */
     
    258259
    259260                if (matched) {
    260                         usb_log_debug("Subdriver matched.\n");
     261                        usb_log_debug("Subdriver matched.");
    261262                        subdrivers[count++] = &mapping->subdriver;
    262263                }
     
    285286                    usb_device_get_mapped_ep_desc(dev, endpoints[i].desc);
    286287                if (epm && epm->present) {
    287                         usb_log_debug("Found: %s.\n", endpoints[i].description);
     288                        usb_log_debug("Found: %s.", endpoints[i].description);
    288289                        hid_dev->poll_pipe_mapping = epm;
    289290                        return EOK;
     
    301302
    302303        do {
    303                 usb_log_debug("Getting size of the report.\n");
     304                usb_log_debug("Getting size of the report.");
    304305                const size_t size =
    305306                    usb_hid_report_byte_size(&hid_dev->report, report_id,
    306307                        USB_HID_REPORT_TYPE_INPUT);
    307                 usb_log_debug("Report ID: %u, size: %zu\n", report_id, size);
     308                usb_log_debug("Report ID: %u, size: %zu", report_id, size);
    308309                max_size = (size > max_size) ? size : max_size;
    309                 usb_log_debug("Getting next report ID\n");
     310                usb_log_debug("Getting next report ID");
    310311                report_id = usb_hid_get_next_report_id(&hid_dev->report,
    311312                    report_id, USB_HID_REPORT_TYPE_INPUT);
    312313        } while (report_id != 0);
    313314
    314         usb_log_debug("Max size of input report: %zu\n", max_size);
     315        usb_log_debug("Max size of input report: %zu", max_size);
    315316
    316317        assert(hid_dev->input_report == NULL);
     
    323324
    324325        return EOK;
     326}
     327
     328static bool usb_hid_polling_callback(usb_device_t *dev, uint8_t *buffer,
     329    size_t buffer_size, void *arg)
     330{
     331        if (dev == NULL || arg == NULL || buffer == NULL) {
     332                usb_log_error("Missing arguments to polling callback.");
     333                return false;
     334        }
     335        usb_hid_dev_t *hid_dev = arg;
     336
     337        assert(hid_dev->input_report != NULL);
     338
     339        usb_log_debug("New data [%zu/%zu]: %s", buffer_size,
     340            hid_dev->max_input_report_size,
     341            usb_debug_str_buffer(buffer, buffer_size, 0));
     342
     343        if (hid_dev->max_input_report_size >= buffer_size) {
     344                /*! @todo This should probably be atomic. */
     345                memcpy(hid_dev->input_report, buffer, buffer_size);
     346                hid_dev->input_report_size = buffer_size;
     347                usb_hid_new_report(hid_dev);
     348        }
     349
     350        /* Parse the input report */
     351        const errno_t rc = usb_hid_parse_report(
     352            &hid_dev->report, buffer, buffer_size, &hid_dev->report_id);
     353        if (rc != EOK) {
     354                usb_log_warning("Failure in usb_hid_parse_report():"
     355                    "%s\n", str_error(rc));
     356        }
     357
     358        bool cont = false;
     359        /* Continue if at least one of the subdrivers want to continue */
     360        for (unsigned i = 0; i < hid_dev->subdriver_count; ++i) {
     361                if (hid_dev->subdrivers[i].poll != NULL) {
     362                        cont = cont || hid_dev->subdrivers[i].poll(
     363                            hid_dev, hid_dev->subdrivers[i].data);
     364                }
     365        }
     366
     367        return cont;
     368}
     369
     370static bool usb_hid_polling_error_callback(usb_device_t *dev, errno_t err_code, void *arg)
     371{
     372        assert(dev);
     373        assert(arg);
     374        usb_hid_dev_t *hid_dev = arg;
     375
     376        usb_log_error("Device %s polling error: %s", usb_device_get_name(dev),
     377            str_error(err_code));
     378
     379        /* Continue polling until the device is about to be removed. */
     380        return hid_dev->running;
     381}
     382
     383static void usb_hid_polling_ended_callback(usb_device_t *dev, bool reason, void *arg)
     384{
     385        assert(dev);
     386        assert(arg);
     387
     388        usb_hid_dev_t *hid_dev = arg;
     389
     390        for (unsigned i = 0; i < hid_dev->subdriver_count; ++i) {
     391                if (hid_dev->subdrivers[i].poll_end != NULL) {
     392                        hid_dev->subdrivers[i].poll_end(
     393                            hid_dev, hid_dev->subdrivers[i].data, reason);
     394                }
     395        }
     396
     397        hid_dev->running = false;
    325398}
    326399
     
    332405 * During initialization, the keyboard is switched into boot protocol, the idle
    333406 * rate is set to 0 (infinity), resulting in the keyboard only reporting event
    334  * when a key is pressed or released. Finally, the LED lights are turned on 
     407 * when a key is pressed or released. Finally, the LED lights are turned on
    335408 * according to the default setup of lock keys.
    336409 *
    337  * @note By default, the keyboards is initialized with Num Lock turned on and 
     410 * @note By default, the keyboards is initialized with Num Lock turned on and
    338411 *       other locks turned off.
    339412 *
     
    347420        assert(dev);
    348421
    349         usb_log_debug("Initializing HID structure...\n");
     422        usb_log_debug("Initializing HID structure...");
    350423
    351424        usb_hid_report_init(&hid_dev->report);
     
    369442                usb_hid_find_subdrivers(hid_dev);
    370443        } else {
    371                 usb_log_error("Failed to parse report descriptor: fallback.\n");
     444                usb_log_error("Failed to parse report descriptor: fallback.");
    372445                hid_dev->subdrivers = NULL;
    373446                hid_dev->subdriver_count = 0;
    374447        }
    375448
    376         usb_log_debug("Subdriver count(before trying boot protocol): %d\n",
     449        usb_log_debug("Subdriver count(before trying boot protocol): %d",
    377450            hid_dev->subdriver_count);
    378451
     
    385458                switch (hid_dev->poll_pipe_mapping->interface->interface_protocol) {
    386459                case USB_HID_PROTOCOL_KEYBOARD:
    387                         usb_log_info("Falling back to kbd boot protocol.\n");
     460                        usb_log_info("Falling back to kbd boot protocol.");
    388461                        rc = usb_kbd_set_boot_protocol(hid_dev);
    389462                        if (rc == EOK) {
     
    392465                        break;
    393466                case USB_HID_PROTOCOL_MOUSE:
    394                         usb_log_info("Falling back to mouse boot protocol.\n");
     467                        usb_log_info("Falling back to mouse boot protocol.");
    395468                        rc = usb_mouse_set_boot_protocol(hid_dev);
    396469                        if (rc == EOK) {
     
    399472                        break;
    400473                default:
    401                         usb_log_info("Falling back to generic HID driver.\n");
     474                        usb_log_info("Falling back to generic HID driver.");
    402475                        usb_hid_set_generic_hid_subdriver(hid_dev);
    403476                }
    404477        }
    405478
    406         usb_log_debug("Subdriver count(after trying boot protocol): %d\n",
     479        usb_log_debug("Subdriver count(after trying boot protocol): %d",
    407480            hid_dev->subdriver_count);
    408481
     
    419492        for (unsigned i = 0; i < hid_dev->subdriver_count; ++i) {
    420493                if (hid_dev->subdrivers[i].init != NULL) {
    421                         usb_log_debug("Initializing subdriver %d.\n",i);
     494                        usb_log_debug("Initializing subdriver %d.",i);
    422495                        const errno_t pret = hid_dev->subdrivers[i].init(hid_dev,
    423496                            &hid_dev->subdrivers[i].data);
     
    442515                rc = usb_hid_init_report(hid_dev);
    443516                if (rc != EOK) {
    444                         usb_log_error("Failed to initialize input report buffer"
    445                             ".\n");
    446                 }
     517                        usb_log_error("Failed to initialize input report buffer: %s", str_error(rc));
     518                        // FIXME: What happens now?
     519                }
     520
     521                usb_polling_t *polling = &hid_dev->polling;
     522                if ((rc = usb_polling_init(polling))) {
     523                        usb_log_error("Failed to initialize polling: %s", str_error(rc));
     524                        // FIXME: What happens now?
     525                }
     526
     527                polling->device = hid_dev->usb_dev;
     528                polling->ep_mapping = hid_dev->poll_pipe_mapping;
     529                polling->request_size = hid_dev->poll_pipe_mapping->pipe.desc.max_transfer_size;
     530                polling->buffer = malloc(polling->request_size);
     531                polling->on_data = usb_hid_polling_callback;
     532                polling->on_polling_end = usb_hid_polling_ended_callback;
     533                polling->on_error = usb_hid_polling_error_callback;
     534                polling->arg = hid_dev;
    447535        }
    448536
    449537        return rc;
    450 }
    451 
    452 bool usb_hid_polling_callback(usb_device_t *dev, uint8_t *buffer,
    453     size_t buffer_size, void *arg)
    454 {
    455         if (dev == NULL || arg == NULL || buffer == NULL) {
    456                 usb_log_error("Missing arguments to polling callback.\n");
    457                 return false;
    458         }
    459         usb_hid_dev_t *hid_dev = arg;
    460 
    461         assert(hid_dev->input_report != NULL);
    462 
    463         usb_log_debug("New data [%zu/%zu]: %s\n", buffer_size,
    464             hid_dev->max_input_report_size,
    465             usb_debug_str_buffer(buffer, buffer_size, 0));
    466 
    467         if (hid_dev->max_input_report_size >= buffer_size) {
    468                 /*! @todo This should probably be atomic. */
    469                 memcpy(hid_dev->input_report, buffer, buffer_size);
    470                 hid_dev->input_report_size = buffer_size;
    471                 usb_hid_new_report(hid_dev);
    472         }
    473 
    474         /* Parse the input report */
    475         const errno_t rc = usb_hid_parse_report(
    476             &hid_dev->report, buffer, buffer_size, &hid_dev->report_id);
    477         if (rc != EOK) {
    478                 usb_log_warning("Failure in usb_hid_parse_report():"
    479                     "%s\n", str_error(rc));
    480         }
    481 
    482         bool cont = false;
    483         /* Continue if at least one of the subdrivers want to continue */
    484         for (unsigned i = 0; i < hid_dev->subdriver_count; ++i) {
    485                 if (hid_dev->subdrivers[i].poll != NULL) {
    486                         cont = cont || hid_dev->subdrivers[i].poll(
    487                             hid_dev, hid_dev->subdrivers[i].data);
    488                 }
    489         }
    490 
    491         return cont;
    492 }
    493 
    494 void usb_hid_polling_ended_callback(usb_device_t *dev, bool reason, void *arg)
    495 {
    496         assert(dev);
    497         assert(arg);
    498 
    499         usb_hid_dev_t *hid_dev = arg;
    500 
    501         for (unsigned i = 0; i < hid_dev->subdriver_count; ++i) {
    502                 if (hid_dev->subdrivers[i].poll_end != NULL) {
    503                         hid_dev->subdrivers[i].poll_end(
    504                             hid_dev, hid_dev->subdrivers[i].data, reason);
    505                 }
    506         }
    507 
    508         hid_dev->running = false;
    509538}
    510539
     
    524553        assert(hid_dev->subdrivers != NULL || hid_dev->subdriver_count == 0);
    525554
    526 
    527         usb_log_debug("Subdrivers: %p, subdriver count: %d\n",
     555        free(hid_dev->polling.buffer);
     556        usb_polling_fini(&hid_dev->polling);
     557
     558        usb_log_debug("Subdrivers: %p, subdriver count: %d",
    528559            hid_dev->subdrivers, hid_dev->subdriver_count);
    529560
     
    541572        /* Destroy the parser */
    542573        usb_hid_report_deinit(&hid_dev->report);
    543 
    544574}
    545575
Note: See TracChangeset for help on using the changeset viewer.