Changeset 07b9cbae in mainline


Ignore:
Timestamp:
2011-11-09T14:26:29Z (13 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
f317490
Parents:
90df90c
Message:

usbhid: Rework and cleanup usbhid device initialization.

Location:
uspace/drv/bus/usb/usbhid
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/bus/usb/usbhid/subdrivers.c

    r90df90c r07b9cbae  
    9898                }
    9999        },
    100         {NULL, -1, 0, -1, -1, {NULL, NULL, NULL, NULL, NULL}}
    101100};
    102101
    103 const int USB_HID_MAX_SUBDRIVERS =
     102const size_t USB_HID_MAX_SUBDRIVERS =
    104103    sizeof(usb_hid_subdrivers) / sizeof(usb_hid_subdrivers[0]);
    105104
  • uspace/drv/bus/usb/usbhid/subdrivers.h

    r90df90c r07b9cbae  
    8484
    8585extern const usb_hid_subdriver_mapping_t usb_hid_subdrivers[];
    86 extern const int USB_HID_MAX_SUBDRIVERS;
     86extern const size_t USB_HID_MAX_SUBDRIVERS;
    8787
    8888/*----------------------------------------------------------------------------*/
  • uspace/drv/bus/usb/usbhid/usbhid.c

    r90df90c r07b9cbae  
    6060        NULL
    6161};
    62 
    63 /*----------------------------------------------------------------------------*/
    64 
     62/*----------------------------------------------------------------------------*/
    6563static int usb_hid_set_boot_kbd_subdriver(usb_hid_dev_t *hid_dev)
    6664{
     
    7876        return EOK;
    7977}
    80 
    81 /*----------------------------------------------------------------------------*/
    82 
     78/*----------------------------------------------------------------------------*/
    8379static int usb_hid_set_boot_mouse_subdriver(usb_hid_dev_t *hid_dev)
    8480{
     
    9692        return EOK;
    9793}
    98 
    99 /*----------------------------------------------------------------------------*/
    100 
     94/*----------------------------------------------------------------------------*/
    10195static int usb_hid_set_generic_hid_subdriver(usb_hid_dev_t *hid_dev)
    10296{
    103         assert(hid_dev != NULL && hid_dev->subdriver_count == 0);
     97        assert(hid_dev != NULL);
     98        assert(hid_dev->subdriver_count == 0);
    10499
    105100        hid_dev->subdrivers = malloc(sizeof(usb_hid_subdriver_t));
     
    117112        return EOK;
    118113}
    119 
    120 /*----------------------------------------------------------------------------*/
    121 
     114/*----------------------------------------------------------------------------*/
    122115static bool usb_hid_ids_match(const usb_hid_dev_t *hid_dev,
    123116    const usb_hid_subdriver_mapping_t *mapping)
     
    131124            == mapping->product_id);
    132125}
    133 
    134 /*----------------------------------------------------------------------------*/
    135 
     126/*----------------------------------------------------------------------------*/
    136127static bool usb_hid_path_matches(usb_hid_dev_t *hid_dev,
    137128    const usb_hid_subdriver_mapping_t *mapping)
     
    145136                return false;
    146137        }
    147         int i = 0;
    148         while (mapping->usage_path[i].usage != 0
    149             || mapping->usage_path[i].usage_page != 0) {
     138
     139        for (int i = 0; mapping->usage_path[i].usage != 0
     140            || mapping->usage_path[i].usage_page != 0; ++i) {
    150141                if (usb_hid_report_path_append_item(usage_path,
    151142                    mapping->usage_path[i].usage_page,
     
    155146                        return false;
    156147                }
    157                 ++i;
    158148        }
    159149
     
    165155        do {
    166156                usb_log_debug("Trying report id %u\n", report_id);
    167 
    168157                if (report_id != 0) {
    169158                        usb_hid_report_path_set_report_id(usage_path,
     
    171160                }
    172161
    173                 usb_hid_report_field_t *field = usb_hid_report_get_sibling(
    174                     &hid_dev->report, NULL, usage_path, mapping->compare,
    175                     USB_HID_REPORT_TYPE_INPUT);
     162                const usb_hid_report_field_t *field =
     163                    usb_hid_report_get_sibling(
     164                        &hid_dev->report, NULL, usage_path, mapping->compare,
     165                        USB_HID_REPORT_TYPE_INPUT);
    176166
    177167                usb_log_debug("Field: %p\n", field);
     
    190180        return matches;
    191181}
    192 
    193 /*----------------------------------------------------------------------------*/
    194 
     182/*----------------------------------------------------------------------------*/
    195183static int usb_hid_save_subdrivers(usb_hid_dev_t *hid_dev,
    196     const usb_hid_subdriver_t **subdrivers, int count)
    197 {
    198         int i;
    199 
    200         if (count <= 0) {
     184    const usb_hid_subdriver_t **subdrivers, unsigned count)
     185{
     186        assert(hid_dev);
     187        assert(subdrivers);
     188
     189        if (count == 0) {
    201190                hid_dev->subdriver_count = 0;
    202191                hid_dev->subdrivers = NULL;
     
    210199        }
    211200
    212         for (i = 0; i < count; ++i) {
    213                 hid_dev->subdrivers[i].init = subdrivers[i]->init;
    214                 hid_dev->subdrivers[i].deinit = subdrivers[i]->deinit;
    215                 hid_dev->subdrivers[i].poll = subdrivers[i]->poll;
    216                 hid_dev->subdrivers[i].poll_end = subdrivers[i]->poll_end;
     201        for (unsigned i = 0; i < count; ++i) {
     202                hid_dev->subdrivers[i] = *subdrivers[i];
    217203        }
    218204
     
    227213        return EOK;
    228214}
    229 
    230 /*----------------------------------------------------------------------------*/
    231 
     215/*----------------------------------------------------------------------------*/
    232216static int usb_hid_find_subdrivers(usb_hid_dev_t *hid_dev)
    233217{
     
    235219
    236220        const usb_hid_subdriver_t *subdrivers[USB_HID_MAX_SUBDRIVERS];
    237 
    238         int i = 0, count = 0;
    239         const usb_hid_subdriver_mapping_t *mapping = &usb_hid_subdrivers[i];
    240 
    241         bool ids_matched;
    242         bool matched;
    243 
    244         while (count < USB_HID_MAX_SUBDRIVERS &&
    245             (mapping->usage_path != NULL
    246             || mapping->vendor_id >= 0 || mapping->product_id >= 0)) {
    247                 // check the vendor & product ID
     221        unsigned count = 0;
     222
     223        for (unsigned i = 0; i < USB_HID_MAX_SUBDRIVERS; ++i) {
     224                const usb_hid_subdriver_mapping_t *mapping =
     225                    &usb_hid_subdrivers[i];
     226                /* Check the vendor & product ID. */
    248227                if (mapping->vendor_id >= 0 && mapping->product_id < 0) {
    249                         usb_log_warning("Missing Product ID for Vendor ID %d\n",
    250                             mapping->vendor_id);
    251                         return EINVAL;
     228                        usb_log_warning("Mapping[%d]: Missing Product ID for "
     229                            "Vendor ID %d\n", i, mapping->vendor_id);
    252230                }
    253231                if (mapping->product_id >= 0 && mapping->vendor_id < 0) {
    254                         usb_log_warning("Missing Vendor ID for Product ID %d\n",
    255                             mapping->product_id);
    256                         return EINVAL;
    257                 }
    258 
    259                 ids_matched = false;
    260                 matched = false;
    261 
    262                 if (mapping->vendor_id >= 0) {
    263                         assert(mapping->product_id >= 0);
     232                        usb_log_warning("Mapping[%d]: Missing Vendor ID for "
     233                            "Product ID %d\n", i, mapping->product_id);
     234                }
     235
     236                bool matched = false;
     237
     238                /* Check ID match. */
     239                if (mapping->vendor_id >= 0 && mapping->product_id >= 0) {
    264240                        usb_log_debug("Comparing device against vendor ID %u"
    265241                            " and product ID %u.\n", mapping->vendor_id,
     
    267243                        if (usb_hid_ids_match(hid_dev, mapping)) {
    268244                                usb_log_debug("IDs matched.\n");
    269                                 ids_matched = true;
     245                                matched = true;
    270246                        }
    271247                }
    272248
     249                /* Check usage match. */
    273250                if (mapping->usage_path != NULL) {
    274251                        usb_log_debug("Comparing device against usage path.\n");
     
    277254                                matched = true;
    278255                        }
    279                 } else {
    280                         // matched only if IDs were matched and there is no path
    281                         matched = ids_matched;
    282256                }
    283257
     
    286260                        subdrivers[count++] = &mapping->subdriver;
    287261                }
    288 
    289                 mapping = &usb_hid_subdrivers[++i];
    290262        }
    291263
    292264        /* We have all subdrivers determined, save them into the hid device */
    293         // TODO Do we really need this complicated stuff if there is
    294         // max_subdrivers limitation?
    295265        return usb_hid_save_subdrivers(hid_dev, subdrivers, count);
    296266}
     
    322292        return ENOTSUP;
    323293}
    324 
    325 /*----------------------------------------------------------------------------*/
    326 
     294/*----------------------------------------------------------------------------*/
    327295static int usb_hid_init_report(usb_hid_dev_t *hid_dev)
    328296{
     
    394362
    395363        /* Get the report descriptor and parse it. */
    396         rc = usb_hid_process_report_descriptor(hid_dev->usb_dev,
    397             &hid_dev->report, &hid_dev->report_desc, &hid_dev->report_desc_size);
     364        rc = usb_hid_process_report_descriptor(
     365            hid_dev->usb_dev, &hid_dev->report, &hid_dev->report_desc,
     366            &hid_dev->report_desc_size);
     367
     368        /* If report parsing went well, find subdrivers. */
     369        if (rc == EOK) {
     370                usb_hid_find_subdrivers(hid_dev);
     371        } else {
     372                usb_log_error("Failed to parse report descriptor: fallback.\n");
     373                hid_dev->subdrivers = NULL;
     374                hid_dev->subdriver_count = 0;
     375        }
     376
     377        usb_log_debug("Subdriver count(before trying boot protocol): %d\n",
     378            hid_dev->subdriver_count);
     379
     380        /* No subdrivers, fall back to the boot protocol if available. */
     381        if (hid_dev->subdriver_count == 0) {
     382                assert(hid_dev->subdrivers == NULL);
     383                usb_log_info("No subdrivers found to handle device, trying "
     384                    "boot protocol.\n");
     385
     386                switch (hid_dev->poll_pipe_index) {
     387                case USB_HID_KBD_POLL_EP_NO:
     388                        usb_log_info("Falling back to kbd boot protocol.\n");
     389                        rc = usb_kbd_set_boot_protocol(hid_dev);
     390                        if (rc == EOK) {
     391                                usb_hid_set_boot_kbd_subdriver(hid_dev);
     392                        }
     393                        break;
     394                case USB_HID_MOUSE_POLL_EP_NO:
     395                        usb_log_info("Falling back to mouse boot protocol.\n");
     396                        rc = usb_mouse_set_boot_protocol(hid_dev);
     397                        if (rc == EOK) {
     398                                usb_hid_set_boot_mouse_subdriver(hid_dev);
     399                        }
     400                        break;
     401                default:
     402                        assert(hid_dev->poll_pipe_index
     403                            == USB_HID_GENERIC_POLL_EP_NO);
     404                        usb_log_info("Falling back to generic HID driver.\n");
     405                        usb_hid_set_generic_hid_subdriver(hid_dev);
     406                }
     407        }
     408
     409        usb_log_debug("Subdriver count(after trying boot protocol): %d\n",
     410            hid_dev->subdriver_count);
     411
     412        /* Still no subdrivers? */
     413        if (hid_dev->subdriver_count == 0) {
     414                assert(hid_dev->subdrivers == NULL);
     415                usb_log_error(
     416                    "No subdriver for handling this device could be found.\n");
     417                return ENOTSUP;
     418        }
    398419
    399420        /*
     
    407428         *    pouzit usb/classes/hid/iface.h - prvy int je telefon
    408429         */
    409 
    410         bool fallback = false;
    411 
    412         if (rc == EOK) {
    413                 // try to find subdrivers that may want to handle this device
    414                 rc = usb_hid_find_subdrivers(hid_dev);
    415                 if (rc != EOK || hid_dev->subdriver_count == 0) {
    416                         // try to fall back to the boot protocol if available
    417                         usb_log_info("No subdrivers found to handle this"
    418                             " device.\n");
    419                         fallback = true;
    420                         assert(hid_dev->subdrivers == NULL);
    421                         assert(hid_dev->subdriver_count == 0);
    422                 }
    423         } else {
    424                 usb_log_error("Failed to parse Report descriptor.\n");
    425                 // try to fall back to the boot protocol if available
    426                 fallback = true;
    427         }
    428 
    429         if (fallback) {
    430                 // fall back to boot protocol
    431                 switch (hid_dev->poll_pipe_index) {
    432                 case USB_HID_KBD_POLL_EP_NO:
    433                         usb_log_info("Falling back to kbd boot protocol.\n");
    434                         rc = usb_kbd_set_boot_protocol(hid_dev);
    435                         if (rc == EOK) {
    436                                 rc = usb_hid_set_boot_kbd_subdriver(hid_dev);
    437                         }
    438                         break;
    439                 case USB_HID_MOUSE_POLL_EP_NO:
    440                         usb_log_info("Falling back to mouse boot protocol.\n");
    441                         rc = usb_mouse_set_boot_protocol(hid_dev);
    442                         if (rc == EOK) {
    443                                 rc = usb_hid_set_boot_mouse_subdriver(hid_dev);
    444                         }
    445                         break;
    446                 default:
    447                         assert(hid_dev->poll_pipe_index
    448                             == USB_HID_GENERIC_POLL_EP_NO);
    449 
    450                         usb_log_info("Falling back to generic HID driver.\n");
    451                         rc = usb_hid_set_generic_hid_subdriver(hid_dev);
    452                 }
    453         }
    454 
    455         if (rc != EOK) {
    456                 usb_log_error("No subdriver for handling this device could be"
    457                     " initialized: %s.\n", str_error(rc));
    458                 usb_log_debug("Subdriver count: %d\n",
    459                     hid_dev->subdriver_count);
    460         } else {
    461                 bool ok = false;
    462 
    463                 usb_log_debug("Subdriver count: %d\n",
    464                     hid_dev->subdriver_count);
    465 
    466                 for (int i = 0; i < hid_dev->subdriver_count; ++i) {
    467                         if (hid_dev->subdrivers[i].init != NULL) {
    468                                 usb_log_debug("Initializing subdriver %d.\n",i);
    469                                 rc = hid_dev->subdrivers[i].init(hid_dev,
    470                                     &hid_dev->subdrivers[i].data);
    471                                 if (rc != EOK) {
    472                                         usb_log_warning("Failed to initialize"
    473                                             " HID subdriver structure.\n");
    474                                 } else {
    475                                         // at least one subdriver initialized
    476                                         ok = true;
    477                                 }
     430        bool ok = false;
     431        for (int i = 0; i < hid_dev->subdriver_count; ++i) {
     432                if (hid_dev->subdrivers[i].init != NULL) {
     433                        usb_log_debug("Initializing subdriver %d.\n",i);
     434                        const int pret = hid_dev->subdrivers[i].init(hid_dev,
     435                            &hid_dev->subdrivers[i].data);
     436                        if (pret != EOK) {
     437                                usb_log_warning("Failed to initialize"
     438                                    " HID subdriver structure: %s.\n",
     439                                    str_error(pret));
     440                                rc = pret;
    478441                        } else {
     442                                /* At least one subdriver initialized. */
    479443                                ok = true;
    480444                        }
    481                 }
    482 
    483                 rc = (ok) ? EOK : -1;   // what error to report
    484         }
    485 
    486 
    487         if (rc == EOK) {
    488                 // save max input report size and allocate space for the report
     445                } else {
     446                        /* Does not need initialization. */
     447                        ok = true;
     448                }
     449        }
     450
     451        if (ok) {
     452                /* Save max input report size and
     453                 * allocate space for the report */
    489454                rc = usb_hid_init_report(hid_dev);
    490455                if (rc != EOK) {
     
    496461        return rc;
    497462}
    498 
    499 /*----------------------------------------------------------------------------*/
    500 
     463/*----------------------------------------------------------------------------*/
    501464bool usb_hid_polling_callback(usb_device_t *dev, uint8_t *buffer,
    502465    size_t buffer_size, void *arg)
Note: See TracChangeset for help on using the changeset viewer.