Ignore:
File:
1 edited

Legend:

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

    r2d1ba51 r5f6e25e  
    5151#include "subdrivers.h"
    5252
     53/*----------------------------------------------------------------------------*/
     54
    5355/* Array of endpoints expected on the device, NULL terminated. */
    54 const usb_endpoint_description_t *usb_hid_endpoints[] = {
     56usb_endpoint_description_t *usb_hid_endpoints[USB_HID_POLL_EP_COUNT + 1] = {
    5557        &usb_hid_kbd_poll_endpoint_description,
    5658        &usb_hid_mouse_poll_endpoint_description,
     
    5860        NULL
    5961};
    60 /*----------------------------------------------------------------------------*/
     62
     63static const int USB_HID_MAX_SUBDRIVERS = 10;
     64
     65/*----------------------------------------------------------------------------*/
     66
    6167static int usb_hid_set_boot_kbd_subdriver(usb_hid_dev_t *hid_dev)
    6268{
    63         assert(hid_dev != NULL);
    64         assert(hid_dev->subdriver_count == 0);
    65 
    66         hid_dev->subdrivers = malloc(sizeof(usb_hid_subdriver_t));
     69        assert(hid_dev != NULL && hid_dev->subdriver_count == 0);
     70       
     71        hid_dev->subdrivers = (usb_hid_subdriver_t *)malloc(
     72            sizeof(usb_hid_subdriver_t));
    6773        if (hid_dev->subdrivers == NULL) {
    6874                return ENOMEM;
    6975        }
    70         hid_dev->subdriver_count = 1;
    71         // TODO 0 should be keyboard, but find a better way
    72         hid_dev->subdrivers[0] = usb_hid_subdrivers[0].subdriver;
    73 
     76       
     77        assert(hid_dev->subdriver_count >= 0);
     78       
     79        // set the init callback
     80        hid_dev->subdrivers[hid_dev->subdriver_count].init = usb_kbd_init;
     81       
     82        // set the polling callback
     83        hid_dev->subdrivers[hid_dev->subdriver_count].poll =
     84            usb_kbd_polling_callback;
     85       
     86        // set the polling ended callback
     87        hid_dev->subdrivers[hid_dev->subdriver_count].poll_end = NULL;
     88       
     89        // set the deinit callback
     90        hid_dev->subdrivers[hid_dev->subdriver_count].deinit = usb_kbd_deinit;
     91       
     92        // set subdriver count
     93        ++hid_dev->subdriver_count;
     94       
    7495        return EOK;
    7596}
    76 /*----------------------------------------------------------------------------*/
     97
     98/*----------------------------------------------------------------------------*/
     99
    77100static int usb_hid_set_boot_mouse_subdriver(usb_hid_dev_t *hid_dev)
    78101{
    79         assert(hid_dev != NULL);
    80         assert(hid_dev->subdriver_count == 0);
    81 
    82         hid_dev->subdrivers = malloc(sizeof(usb_hid_subdriver_t));
     102        assert(hid_dev != NULL && hid_dev->subdriver_count == 0);
     103       
     104        hid_dev->subdrivers = (usb_hid_subdriver_t *)malloc(
     105            sizeof(usb_hid_subdriver_t));
    83106        if (hid_dev->subdrivers == NULL) {
    84107                return ENOMEM;
    85108        }
    86         hid_dev->subdriver_count = 1;
    87         // TODO 2 should be mouse, but find a better way
    88         hid_dev->subdrivers[0] = usb_hid_subdrivers[2].subdriver;
    89 
     109       
     110        assert(hid_dev->subdriver_count >= 0);
     111       
     112        // set the init callback
     113        hid_dev->subdrivers[hid_dev->subdriver_count].init = usb_mouse_init;
     114       
     115        // set the polling callback
     116        hid_dev->subdrivers[hid_dev->subdriver_count].poll =
     117            usb_mouse_polling_callback;
     118       
     119        // set the polling ended callback
     120        hid_dev->subdrivers[hid_dev->subdriver_count].poll_end = NULL;
     121       
     122        // set the deinit callback
     123        hid_dev->subdrivers[hid_dev->subdriver_count].deinit = usb_mouse_deinit;
     124       
     125        // set subdriver count
     126        ++hid_dev->subdriver_count;
     127       
    90128        return EOK;
    91129}
    92 /*----------------------------------------------------------------------------*/
     130
     131/*----------------------------------------------------------------------------*/
     132
    93133static int usb_hid_set_generic_hid_subdriver(usb_hid_dev_t *hid_dev)
    94134{
    95         assert(hid_dev != NULL);
    96         assert(hid_dev->subdriver_count == 0);
    97 
    98         hid_dev->subdrivers = malloc(sizeof(usb_hid_subdriver_t));
     135        assert(hid_dev != NULL && hid_dev->subdriver_count == 0);
     136       
     137        hid_dev->subdrivers = (usb_hid_subdriver_t *)malloc(
     138            sizeof(usb_hid_subdriver_t));
    99139        if (hid_dev->subdrivers == NULL) {
    100140                return ENOMEM;
    101141        }
    102         hid_dev->subdriver_count = 1;
    103 
    104         /* Set generic hid subdriver routines */
    105         hid_dev->subdrivers[0].init = usb_generic_hid_init;
    106         hid_dev->subdrivers[0].poll = usb_generic_hid_polling_callback;
    107         hid_dev->subdrivers[0].poll_end = NULL;
    108         hid_dev->subdrivers[0].deinit = usb_generic_hid_deinit;
    109 
     142       
     143        assert(hid_dev->subdriver_count >= 0);
     144       
     145        // set the init callback
     146        hid_dev->subdrivers[hid_dev->subdriver_count].init =
     147            usb_generic_hid_init;
     148       
     149        // set the polling callback
     150        hid_dev->subdrivers[hid_dev->subdriver_count].poll =
     151            usb_generic_hid_polling_callback;
     152       
     153        // set the polling ended callback
     154        hid_dev->subdrivers[hid_dev->subdriver_count].poll_end = NULL;
     155       
     156        // set the deinit callback
     157        hid_dev->subdrivers[hid_dev->subdriver_count].deinit = NULL;
     158       
     159        // set subdriver count
     160        ++hid_dev->subdriver_count;
     161       
    110162        return EOK;
    111163}
    112 /*----------------------------------------------------------------------------*/
    113 static bool usb_hid_ids_match(const usb_hid_dev_t *hid_dev,
     164
     165/*----------------------------------------------------------------------------*/
     166
     167static bool usb_hid_ids_match(usb_hid_dev_t *hid_dev,
    114168    const usb_hid_subdriver_mapping_t *mapping)
    115169{
    116170        assert(hid_dev != NULL);
    117171        assert(hid_dev->usb_dev != NULL);
    118 
    119         return (hid_dev->usb_dev->descriptors.device.vendor_id
     172       
     173        return (hid_dev->usb_dev->descriptors.device.vendor_id 
    120174            == mapping->vendor_id
    121             && hid_dev->usb_dev->descriptors.device.product_id
     175            && hid_dev->usb_dev->descriptors.device.product_id 
    122176            == mapping->product_id);
    123177}
    124 /*----------------------------------------------------------------------------*/
    125 static bool usb_hid_path_matches(usb_hid_dev_t *hid_dev,
     178
     179/*----------------------------------------------------------------------------*/
     180
     181static bool usb_hid_path_matches(usb_hid_dev_t *hid_dev,
    126182    const usb_hid_subdriver_mapping_t *mapping)
    127183{
    128184        assert(hid_dev != NULL);
    129185        assert(mapping != NULL);
    130 
     186       
    131187        usb_hid_report_path_t *usage_path = usb_hid_report_path();
    132188        if (usage_path == NULL) {
     
    134190                return false;
    135191        }
    136 
    137         for (int i = 0; mapping->usage_path[i].usage != 0
    138             || mapping->usage_path[i].usage_page != 0; ++i) {
    139                 if (usb_hid_report_path_append_item(usage_path,
    140                     mapping->usage_path[i].usage_page,
     192        int i = 0;
     193        while (mapping->usage_path[i].usage != 0
     194            || mapping->usage_path[i].usage_page != 0) {
     195                if (usb_hid_report_path_append_item(usage_path, 
     196                    mapping->usage_path[i].usage_page, 
    141197                    mapping->usage_path[i].usage) != EOK) {
    142198                        usb_log_debug("Failed to append to usage path.\n");
     
    144200                        return false;
    145201                }
    146         }
    147 
     202                ++i;
     203        }
     204       
     205        assert(hid_dev->report != NULL);
     206       
    148207        usb_log_debug("Compare flags: %d\n", mapping->compare);
    149 
     208       
    150209        bool matches = false;
    151210        uint8_t report_id = mapping->report_id;
     
    153212        do {
    154213                usb_log_debug("Trying report id %u\n", report_id);
     214               
    155215                if (report_id != 0) {
    156216                        usb_hid_report_path_set_report_id(usage_path,
     
    158218                }
    159219
    160                 const usb_hid_report_field_t *field =
    161                     usb_hid_report_get_sibling(
    162                         &hid_dev->report, NULL, usage_path, mapping->compare,
    163                         USB_HID_REPORT_TYPE_INPUT);
    164 
     220                usb_hid_report_field_t *field = usb_hid_report_get_sibling(
     221                    hid_dev->report,
     222                    NULL, usage_path, mapping->compare,
     223                    USB_HID_REPORT_TYPE_INPUT);
     224               
    165225                usb_log_debug("Field: %p\n", field);
    166226
     
    169229                        break;
    170230                }
    171 
     231               
    172232                report_id = usb_hid_get_next_report_id(
    173                     &hid_dev->report, report_id, USB_HID_REPORT_TYPE_INPUT);
     233                    hid_dev->report, report_id,
     234                    USB_HID_REPORT_TYPE_INPUT);
    174235        } while (!matches && report_id != 0);
    175 
     236       
    176237        usb_hid_report_path_free(usage_path);
    177 
     238       
    178239        return matches;
    179240}
    180 /*----------------------------------------------------------------------------*/
    181 static int usb_hid_save_subdrivers(usb_hid_dev_t *hid_dev,
    182     const usb_hid_subdriver_t **subdrivers, unsigned count)
    183 {
    184         assert(hid_dev);
    185         assert(subdrivers);
    186 
    187         if (count == 0) {
     241
     242/*----------------------------------------------------------------------------*/
     243
     244static int usb_hid_save_subdrivers(usb_hid_dev_t *hid_dev,
     245    const usb_hid_subdriver_t **subdrivers, int count)
     246{
     247        int i;
     248       
     249        if (count <= 0) {
    188250                hid_dev->subdriver_count = 0;
    189251                hid_dev->subdrivers = NULL;
    190252                return EOK;
    191253        }
    192 
    193         /* +1 for generic hid subdriver */
    194         hid_dev->subdrivers = calloc((count + 1), sizeof(usb_hid_subdriver_t));
     254       
     255        // add one generic HID subdriver per device
     256       
     257        hid_dev->subdrivers = (usb_hid_subdriver_t *)malloc((count + 1) *
     258            sizeof(usb_hid_subdriver_t));
    195259        if (hid_dev->subdrivers == NULL) {
    196260                return ENOMEM;
    197261        }
    198 
    199         for (unsigned i = 0; i < count; ++i) {
    200                 hid_dev->subdrivers[i] = *subdrivers[i];
    201         }
    202 
    203         /* Add one generic HID subdriver per device */
     262       
     263        for (i = 0; i < count; ++i) {
     264                hid_dev->subdrivers[i].init = subdrivers[i]->init;
     265                hid_dev->subdrivers[i].deinit = subdrivers[i]->deinit;
     266                hid_dev->subdrivers[i].poll = subdrivers[i]->poll;
     267                hid_dev->subdrivers[i].poll_end = subdrivers[i]->poll_end;
     268        }
     269       
    204270        hid_dev->subdrivers[count].init = usb_generic_hid_init;
    205271        hid_dev->subdrivers[count].poll = usb_generic_hid_polling_callback;
    206         hid_dev->subdrivers[count].deinit = usb_generic_hid_deinit;
     272        hid_dev->subdrivers[count].deinit = NULL;
    207273        hid_dev->subdrivers[count].poll_end = NULL;
    208 
     274       
    209275        hid_dev->subdriver_count = count + 1;
    210 
     276       
    211277        return EOK;
    212278}
    213 /*----------------------------------------------------------------------------*/
     279
     280/*----------------------------------------------------------------------------*/
     281
    214282static int usb_hid_find_subdrivers(usb_hid_dev_t *hid_dev)
    215283{
    216284        assert(hid_dev != NULL);
    217 
     285       
    218286        const usb_hid_subdriver_t *subdrivers[USB_HID_MAX_SUBDRIVERS];
    219         unsigned count = 0;
    220 
    221         for (unsigned i = 0; i < USB_HID_MAX_SUBDRIVERS; ++i) {
    222                 const usb_hid_subdriver_mapping_t *mapping =
    223                     &usb_hid_subdrivers[i];
    224                 /* Check the vendor & product ID. */
     287       
     288        int i = 0, count = 0;
     289        const usb_hid_subdriver_mapping_t *mapping = &usb_hid_subdrivers[i];
     290
     291        bool ids_matched;
     292        bool matched;
     293       
     294        while (count < USB_HID_MAX_SUBDRIVERS &&
     295            (mapping->usage_path != NULL
     296            || mapping->vendor_id >= 0 || mapping->product_id >= 0)) {
     297                // check the vendor & product ID
    225298                if (mapping->vendor_id >= 0 && mapping->product_id < 0) {
    226                         usb_log_warning("Mapping[%d]: Missing Product ID for "
    227                             "Vendor ID %d\n", i, mapping->vendor_id);
     299                        usb_log_warning("Missing Product ID for Vendor ID %d\n",
     300                            mapping->vendor_id);
     301                        return EINVAL;
    228302                }
    229303                if (mapping->product_id >= 0 && mapping->vendor_id < 0) {
    230                         usb_log_warning("Mapping[%d]: Missing Vendor ID for "
    231                             "Product ID %d\n", i, mapping->product_id);
    232                 }
    233 
    234                 bool matched = false;
    235 
    236                 /* Check ID match. */
    237                 if (mapping->vendor_id >= 0 && mapping->product_id >= 0) {
     304                        usb_log_warning("Missing Vendor ID for Product ID %d\n",
     305                            mapping->product_id);
     306                        return EINVAL;
     307                }
     308               
     309                ids_matched = false;
     310                matched = false;
     311               
     312                if (mapping->vendor_id >= 0) {
     313                        assert(mapping->product_id >= 0);
    238314                        usb_log_debug("Comparing device against vendor ID %u"
    239315                            " and product ID %u.\n", mapping->vendor_id,
     
    241317                        if (usb_hid_ids_match(hid_dev, mapping)) {
    242318                                usb_log_debug("IDs matched.\n");
    243                                 matched = true;
     319                                ids_matched = true;
    244320                        }
    245321                }
    246 
    247                 /* Check usage match. */
     322               
    248323                if (mapping->usage_path != NULL) {
    249324                        usb_log_debug("Comparing device against usage path.\n");
    250325                        if (usb_hid_path_matches(hid_dev, mapping)) {
    251                                 /* Does not matter if IDs were matched. */
     326                                // does not matter if IDs were matched
    252327                                matched = true;
    253328                        }
    254                 }
    255 
     329                } else {
     330                        // matched only if IDs were matched and there is no path
     331                        matched = ids_matched;
     332                }
     333               
    256334                if (matched) {
    257335                        usb_log_debug("Subdriver matched.\n");
    258336                        subdrivers[count++] = &mapping->subdriver;
    259337                }
    260         }
    261 
    262         /* We have all subdrivers determined, save them into the hid device */
     338               
     339                mapping = &usb_hid_subdrivers[++i];
     340        }
     341       
     342        // we have all subdrivers determined, save them into the hid device
    263343        return usb_hid_save_subdrivers(hid_dev, subdrivers, count);
    264344}
    265 /*----------------------------------------------------------------------------*/
    266 static int usb_hid_check_pipes(usb_hid_dev_t *hid_dev, const usb_device_t *dev)
    267 {
    268         assert(hid_dev);
    269         assert(dev);
    270 
    271         static const struct {
    272                 unsigned ep_number;
    273                 const char* description;
    274         } endpoints[] = {
    275                 {USB_HID_KBD_POLL_EP_NO, "Keyboard endpoint"},
    276                 {USB_HID_MOUSE_POLL_EP_NO, "Mouse endpoint"},
    277                 {USB_HID_GENERIC_POLL_EP_NO, "Generic HID endpoint"},
    278         };
    279 
    280         for (unsigned i = 0; i < sizeof(endpoints)/sizeof(endpoints[0]); ++i) {
    281                 if (endpoints[i].ep_number >= dev->pipes_count) {
    282                         return EINVAL;
    283                 }
    284                 if (dev->pipes[endpoints[i].ep_number].present) {
    285                         usb_log_debug("Found: %s.\n", endpoints[i].description);
    286                         hid_dev->poll_pipe_index = endpoints[i].ep_number;
    287                         return EOK;
    288                 }
    289         }
    290         return ENOTSUP;
    291 }
    292 /*----------------------------------------------------------------------------*/
     345
     346/*----------------------------------------------------------------------------*/
     347
     348static int usb_hid_check_pipes(usb_hid_dev_t *hid_dev, usb_device_t *dev)
     349{
     350        assert(hid_dev != NULL && dev != NULL);
     351       
     352        int rc = EOK;
     353       
     354        if (dev->pipes[USB_HID_KBD_POLL_EP_NO].present) {
     355                usb_log_debug("Found keyboard endpoint.\n");
     356                // save the pipe index
     357                hid_dev->poll_pipe_index = USB_HID_KBD_POLL_EP_NO;
     358        } else if (dev->pipes[USB_HID_MOUSE_POLL_EP_NO].present) {
     359                usb_log_debug("Found mouse endpoint.\n");
     360                // save the pipe index
     361                hid_dev->poll_pipe_index = USB_HID_MOUSE_POLL_EP_NO;
     362        } else if (dev->pipes[USB_HID_GENERIC_POLL_EP_NO].present) {
     363                usb_log_debug("Found generic HID endpoint.\n");
     364                // save the pipe index
     365                hid_dev->poll_pipe_index = USB_HID_GENERIC_POLL_EP_NO;
     366        } else {
     367                usb_log_error("None of supported endpoints found - probably"
     368                    " not a supported device.\n");
     369                rc = ENOTSUP;
     370        }
     371       
     372        return rc;
     373}
     374
     375/*----------------------------------------------------------------------------*/
     376
    293377static int usb_hid_init_report(usb_hid_dev_t *hid_dev)
    294378{
    295         assert(hid_dev != NULL);
    296 
     379        assert(hid_dev != NULL && hid_dev->report != NULL);
     380       
    297381        uint8_t report_id = 0;
     382        size_t size;
     383       
    298384        size_t max_size = 0;
    299 
     385       
    300386        do {
    301387                usb_log_debug("Getting size of the report.\n");
    302                 const size_t size =
    303                     usb_hid_report_byte_size(&hid_dev->report, report_id,
    304                         USB_HID_REPORT_TYPE_INPUT);
     388                size = usb_hid_report_byte_size(hid_dev->report, report_id,
     389                    USB_HID_REPORT_TYPE_INPUT);
    305390                usb_log_debug("Report ID: %u, size: %zu\n", report_id, size);
    306391                max_size = (size > max_size) ? size : max_size;
    307392                usb_log_debug("Getting next report ID\n");
    308                 report_id = usb_hid_get_next_report_id(&hid_dev->report,
     393                report_id = usb_hid_get_next_report_id(hid_dev->report,
    309394                    report_id, USB_HID_REPORT_TYPE_INPUT);
    310395        } while (report_id != 0);
    311 
     396       
    312397        usb_log_debug("Max size of input report: %zu\n", max_size);
    313 
     398       
     399        hid_dev->max_input_report_size = max_size;
    314400        assert(hid_dev->input_report == NULL);
    315 
    316         hid_dev->input_report = calloc(1, max_size);
     401       
     402        hid_dev->input_report = malloc(max_size);
    317403        if (hid_dev->input_report == NULL) {
    318404                return ENOMEM;
    319405        }
    320         hid_dev->max_input_report_size = max_size;
    321 
     406        memset(hid_dev->input_report, 0, max_size);
     407       
    322408        return EOK;
    323409}
    324 /*----------------------------------------------------------------------------*/
    325 /*
    326  * This functions initializes required structures from the device's descriptors
    327  * and starts new fibril for polling the keyboard for events and another one for
    328  * handling auto-repeat of keys.
    329  *
    330  * During initialization, the keyboard is switched into boot protocol, the idle
    331  * rate is set to 0 (infinity), resulting in the keyboard only reporting event
    332  * when a key is pressed or released. Finally, the LED lights are turned on
    333  * according to the default setup of lock keys.
    334  *
    335  * @note By default, the keyboards is initialized with Num Lock turned on and
    336  *       other locks turned off.
    337  *
    338  * @param hid_dev Device to initialize, non-NULL.
    339  * @param dev USB device, non-NULL.
    340  * @return Error code.
    341  */
     410
     411/*----------------------------------------------------------------------------*/
     412
     413usb_hid_dev_t *usb_hid_new(void)
     414{
     415        usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)calloc(1,
     416            sizeof(usb_hid_dev_t));
     417       
     418        if (hid_dev == NULL) {
     419                usb_log_fatal("No memory!\n");
     420                return NULL;
     421        }
     422       
     423        hid_dev->report = (usb_hid_report_t *)(malloc(sizeof(
     424            usb_hid_report_t)));
     425        if (hid_dev->report == NULL) {
     426                usb_log_fatal("No memory!\n");
     427                free(hid_dev);
     428                return NULL;
     429        }
     430       
     431        hid_dev->poll_pipe_index = -1;
     432       
     433        return hid_dev;
     434}
     435
     436/*----------------------------------------------------------------------------*/
     437
    342438int usb_hid_init(usb_hid_dev_t *hid_dev, usb_device_t *dev)
    343439{
    344         assert(hid_dev);
    345         assert(dev);
    346 
     440        int rc, i;
     441       
    347442        usb_log_debug("Initializing HID structure...\n");
    348 
    349         usb_hid_report_init(&hid_dev->report);
    350 
     443       
     444        if (hid_dev == NULL) {
     445                usb_log_error("Failed to init HID structure: no structure given"
     446                    ".\n");
     447                return EINVAL;
     448        }
     449       
     450        if (dev == NULL) {
     451                usb_log_error("Failed to init HID structure: no USB device"
     452                    " given.\n");
     453                return EINVAL;
     454        }
     455       
    351456        /* The USB device should already be initialized, save it in structure */
    352457        hid_dev->usb_dev = dev;
    353         hid_dev->poll_pipe_index = -1;
    354 
    355         int rc = usb_hid_check_pipes(hid_dev, dev);
     458       
     459        rc = usb_hid_check_pipes(hid_dev, dev);
    356460        if (rc != EOK) {
    357461                return rc;
    358462        }
    359 
     463               
    360464        /* Get the report descriptor and parse it. */
    361         rc = usb_hid_process_report_descriptor(
    362             hid_dev->usb_dev, &hid_dev->report, &hid_dev->report_desc,
    363             &hid_dev->report_desc_size);
    364 
    365         /* If report parsing went well, find subdrivers. */
     465        rc = usb_hid_process_report_descriptor(hid_dev->usb_dev,
     466            hid_dev->report, &hid_dev->report_desc, &hid_dev->report_desc_size);
     467       
     468        bool fallback = false;
     469       
    366470        if (rc == EOK) {
    367                 usb_hid_find_subdrivers(hid_dev);
     471                // try to find subdrivers that may want to handle this device
     472                rc = usb_hid_find_subdrivers(hid_dev);
     473                if (rc != EOK || hid_dev->subdriver_count == 0) {
     474                        // try to fall back to the boot protocol if available
     475                        usb_log_info("No subdrivers found to handle this"
     476                            " device.\n");
     477                        fallback = true;
     478                        assert(hid_dev->subdrivers == NULL);
     479                        assert(hid_dev->subdriver_count == 0);
     480                }
    368481        } else {
    369                 usb_log_error("Failed to parse report descriptor: fallback.\n");
    370                 hid_dev->subdrivers = NULL;
    371                 hid_dev->subdriver_count = 0;
    372         }
    373 
    374         usb_log_debug("Subdriver count(before trying boot protocol): %d\n",
    375             hid_dev->subdriver_count);
    376 
    377         /* No subdrivers, fall back to the boot protocol if available. */
    378         if (hid_dev->subdriver_count == 0) {
    379                 assert(hid_dev->subdrivers == NULL);
    380                 usb_log_info("No subdrivers found to handle device, trying "
    381                     "boot protocol.\n");
    382 
     482                usb_log_error("Failed to parse Report descriptor.\n");
     483                // try to fall back to the boot protocol if available
     484                fallback = true;
     485        }
     486       
     487        if (fallback) {
     488                // fall back to boot protocol
    383489                switch (hid_dev->poll_pipe_index) {
    384490                case USB_HID_KBD_POLL_EP_NO:
     
    386492                        rc = usb_kbd_set_boot_protocol(hid_dev);
    387493                        if (rc == EOK) {
    388                                 usb_hid_set_boot_kbd_subdriver(hid_dev);
     494                                rc = usb_hid_set_boot_kbd_subdriver(hid_dev);
    389495                        }
    390496                        break;
     
    393499                        rc = usb_mouse_set_boot_protocol(hid_dev);
    394500                        if (rc == EOK) {
    395                                 usb_hid_set_boot_mouse_subdriver(hid_dev);
     501                                rc = usb_hid_set_boot_mouse_subdriver(hid_dev);
    396502                        }
    397503                        break;
    398504                default:
    399                         assert(hid_dev->poll_pipe_index
     505                        assert(hid_dev->poll_pipe_index 
    400506                            == USB_HID_GENERIC_POLL_EP_NO);
     507                       
    401508                        usb_log_info("Falling back to generic HID driver.\n");
    402                         usb_hid_set_generic_hid_subdriver(hid_dev);
    403                 }
    404         }
    405 
    406         usb_log_debug("Subdriver count(after trying boot protocol): %d\n",
    407             hid_dev->subdriver_count);
    408 
    409         /* Still no subdrivers? */
    410         if (hid_dev->subdriver_count == 0) {
    411                 assert(hid_dev->subdrivers == NULL);
    412                 usb_log_error(
    413                     "No subdriver for handling this device could be found.\n");
    414                 return ENOTSUP;
    415         }
    416 
    417         /*
    418          * 1) subdriver vytvori vlastnu ddf_fun, vlastne ddf_dev_ops, ktore da
    419          *    do nej.
    420          * 2) do tych ops do .interfaces[DEV_IFACE_USBHID (asi)] priradi
    421          *    vyplnenu strukturu usbhid_iface_t.
    422          * 3) klientska aplikacia - musi si rucne vytvorit telefon
    423          *    (devman_device_connect() - cesta k zariadeniu (/hw/pci0/...) az
    424          *    k tej fcii.
    425          *    pouzit usb/classes/hid/iface.h - prvy int je telefon
    426          */
    427         bool ok = false;
    428         for (unsigned i = 0; i < hid_dev->subdriver_count; ++i) {
    429                 if (hid_dev->subdrivers[i].init != NULL) {
    430                         usb_log_debug("Initializing subdriver %d.\n",i);
    431                         const int pret = hid_dev->subdrivers[i].init(hid_dev,
    432                             &hid_dev->subdrivers[i].data);
    433                         if (pret != EOK) {
    434                                 usb_log_warning("Failed to initialize"
    435                                     " HID subdriver structure: %s.\n",
    436                                     str_error(pret));
    437                                 rc = pret;
     509                        rc = usb_hid_set_generic_hid_subdriver(hid_dev);
     510                }
     511        }
     512       
     513        if (rc != EOK) {
     514                usb_log_error("No subdriver for handling this device could be"
     515                    " initialized: %s.\n", str_error(rc));
     516                usb_log_debug("Subdriver count: %d\n",
     517                    hid_dev->subdriver_count);
     518               
     519        } else {
     520                bool ok = false;
     521               
     522                usb_log_debug("Subdriver count: %d\n",
     523                    hid_dev->subdriver_count);
     524               
     525                for (i = 0; i < hid_dev->subdriver_count; ++i) {
     526                        if (hid_dev->subdrivers[i].init != NULL) {
     527                                usb_log_debug("Initializing subdriver %d.\n",i);
     528                                rc = hid_dev->subdrivers[i].init(hid_dev,
     529                                    &hid_dev->subdrivers[i].data);
     530                                if (rc != EOK) {
     531                                        usb_log_warning("Failed to initialize"
     532                                            " HID subdriver structure.\n");
     533                                } else {
     534                                        // at least one subdriver initialized
     535                                        ok = true;
     536                                }
    438537                        } else {
    439                                 /* At least one subdriver initialized. */
    440538                                ok = true;
    441539                        }
    442                 } else {
    443                         /* Does not need initialization. */
    444                         ok = true;
    445                 }
    446         }
    447 
    448         if (ok) {
    449                 /* Save max input report size and
    450                  * allocate space for the report */
     540                }
     541               
     542                rc = (ok) ? EOK : -1;   // what error to report
     543        }
     544       
     545       
     546        if (rc == EOK) {
     547                // save max input report size and allocate space for the report
    451548                rc = usb_hid_init_report(hid_dev);
    452549                if (rc != EOK) {
     
    455552                }
    456553        }
    457 
     554       
     555       
    458556        return rc;
    459557}
    460 /*----------------------------------------------------------------------------*/
    461 bool usb_hid_polling_callback(usb_device_t *dev, uint8_t *buffer,
     558
     559/*----------------------------------------------------------------------------*/
     560
     561bool usb_hid_polling_callback(usb_device_t *dev, uint8_t *buffer,
    462562    size_t buffer_size, void *arg)
    463563{
     564        int i;
     565       
    464566        if (dev == NULL || arg == NULL || buffer == NULL) {
    465567                usb_log_error("Missing arguments to polling callback.\n");
    466568                return false;
    467569        }
    468         usb_hid_dev_t *hid_dev = arg;
    469 
     570       
     571        usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)arg;
     572       
    470573        assert(hid_dev->input_report != NULL);
    471 
    472574        usb_log_debug("New data [%zu/%zu]: %s\n", buffer_size,
    473575            hid_dev->max_input_report_size,
     
    480582                usb_hid_new_report(hid_dev);
    481583        }
    482 
    483         /* Parse the input report */
    484         const int rc = usb_hid_parse_report(
    485             &hid_dev->report, buffer, buffer_size, &hid_dev->report_id);
     584       
     585        // parse the input report
     586       
     587        int rc = usb_hid_parse_report(hid_dev->report, buffer, buffer_size,
     588            &hid_dev->report_id);
     589       
    486590        if (rc != EOK) {
    487591                usb_log_warning("Error in usb_hid_parse_report():"
    488592                    "%s\n", str_error(rc));
    489         }
    490 
     593        }       
     594       
    491595        bool cont = false;
    492         /* Continue if at least one of the subdrivers want to continue */
    493         for (unsigned i = 0; i < hid_dev->subdriver_count; ++i) {
    494                 if (hid_dev->subdrivers[i].poll != NULL) {
    495                         cont = cont || hid_dev->subdrivers[i].poll(
    496                             hid_dev, hid_dev->subdrivers[i].data);
    497                 }
    498         }
    499 
     596       
     597        // continue if at least one of the subdrivers want to continue
     598        for (i = 0; i < hid_dev->subdriver_count; ++i) {
     599                if (hid_dev->subdrivers[i].poll != NULL
     600                    && hid_dev->subdrivers[i].poll(hid_dev,
     601                        hid_dev->subdrivers[i].data)) {
     602                        cont = true;
     603                }
     604        }
     605       
    500606        return cont;
    501607}
    502 /*----------------------------------------------------------------------------*/
    503 void usb_hid_polling_ended_callback(usb_device_t *dev, bool reason, void *arg)
    504 {
    505         assert(dev);
    506         assert(arg);
    507 
    508         usb_hid_dev_t *hid_dev = arg;
    509 
    510         for (unsigned i = 0; i < hid_dev->subdriver_count; ++i) {
     608
     609/*----------------------------------------------------------------------------*/
     610
     611void usb_hid_polling_ended_callback(usb_device_t *dev, bool reason,
     612     void *arg)
     613{
     614        int i;
     615       
     616        if (dev == NULL || arg == NULL) {
     617                return;
     618        }
     619       
     620        usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)arg;
     621       
     622        for (i = 0; i < hid_dev->subdriver_count; ++i) {
    511623                if (hid_dev->subdrivers[i].poll_end != NULL) {
    512                         hid_dev->subdrivers[i].poll_end(
    513                             hid_dev, hid_dev->subdrivers[i].data, reason);
    514                 }
    515         }
    516 
    517         hid_dev->running = false;
    518 }
    519 /*----------------------------------------------------------------------------*/
     624                        hid_dev->subdrivers[i].poll_end(hid_dev,
     625                            hid_dev->subdrivers[i].data, reason);
     626                }
     627        }
     628       
     629        usb_hid_destroy(hid_dev);
     630}
     631
     632/*----------------------------------------------------------------------------*/
     633
    520634void usb_hid_new_report(usb_hid_dev_t *hid_dev)
    521635{
    522636        ++hid_dev->report_nr;
    523637}
    524 /*----------------------------------------------------------------------------*/
    525 int usb_hid_report_number(const usb_hid_dev_t *hid_dev)
     638
     639/*----------------------------------------------------------------------------*/
     640
     641int usb_hid_report_number(usb_hid_dev_t *hid_dev)
    526642{
    527643        return hid_dev->report_nr;
    528644}
    529 /*----------------------------------------------------------------------------*/
    530 void usb_hid_deinit(usb_hid_dev_t *hid_dev)
    531 {
    532         assert(hid_dev);
    533         assert(hid_dev->subdrivers != NULL || hid_dev->subdriver_count == 0);
    534 
    535 
     645
     646/*----------------------------------------------------------------------------*/
     647
     648void usb_hid_destroy(usb_hid_dev_t *hid_dev)
     649{
     650        int i;
     651       
     652        if (hid_dev == NULL) {
     653                return;
     654        }
     655       
    536656        usb_log_debug("Subdrivers: %p, subdriver count: %d\n",
    537657            hid_dev->subdrivers, hid_dev->subdriver_count);
    538 
    539         for (unsigned i = 0; i < hid_dev->subdriver_count; ++i) {
     658       
     659        assert(hid_dev->subdrivers != NULL
     660            || hid_dev->subdriver_count == 0);
     661       
     662        for (i = 0; i < hid_dev->subdriver_count; ++i) {
    540663                if (hid_dev->subdrivers[i].deinit != NULL) {
    541664                        hid_dev->subdrivers[i].deinit(hid_dev,
     
    543666                }
    544667        }
    545 
    546         /* Free allocated structures */
    547         free(hid_dev->subdrivers);
    548         free(hid_dev->report_desc);
    549 
    550         /* Destroy the parser */
    551         usb_hid_report_deinit(&hid_dev->report);
    552 
     668       
     669        // free the subdrivers info
     670        if (hid_dev->subdrivers != NULL) {
     671                free(hid_dev->subdrivers);
     672        }
     673
     674        // destroy the parser
     675        if (hid_dev->report != NULL) {
     676                usb_hid_free_report(hid_dev->report);
     677        }
     678
     679        if (hid_dev->report_desc != NULL) {
     680                free(hid_dev->report_desc);
     681        }
    553682}
    554683
Note: See TracChangeset for help on using the changeset viewer.