Ignore:
File:
1 edited

Legend:

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

    r5f6e25e r2d1ba51  
    5151#include "subdrivers.h"
    5252
    53 /*----------------------------------------------------------------------------*/
    54 
    5553/* Array of endpoints expected on the device, NULL terminated. */
    56 usb_endpoint_description_t *usb_hid_endpoints[USB_HID_POLL_EP_COUNT + 1] = {
     54const usb_endpoint_description_t *usb_hid_endpoints[] = {
    5755        &usb_hid_kbd_poll_endpoint_description,
    5856        &usb_hid_mouse_poll_endpoint_description,
     
    6058        NULL
    6159};
    62 
    63 static const int USB_HID_MAX_SUBDRIVERS = 10;
    64 
    65 /*----------------------------------------------------------------------------*/
    66 
     60/*----------------------------------------------------------------------------*/
    6761static int usb_hid_set_boot_kbd_subdriver(usb_hid_dev_t *hid_dev)
    6862{
    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));
     63        assert(hid_dev != NULL);
     64        assert(hid_dev->subdriver_count == 0);
     65
     66        hid_dev->subdrivers = malloc(sizeof(usb_hid_subdriver_t));
    7367        if (hid_dev->subdrivers == NULL) {
    7468                return ENOMEM;
    7569        }
    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        
     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
    9574        return EOK;
    9675}
    97 
    98 /*----------------------------------------------------------------------------*/
    99 
     76/*----------------------------------------------------------------------------*/
    10077static int usb_hid_set_boot_mouse_subdriver(usb_hid_dev_t *hid_dev)
    10178{
    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));
     79        assert(hid_dev != NULL);
     80        assert(hid_dev->subdriver_count == 0);
     81
     82        hid_dev->subdrivers = malloc(sizeof(usb_hid_subdriver_t));
    10683        if (hid_dev->subdrivers == NULL) {
    10784                return ENOMEM;
    10885        }
    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        
     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
    12890        return EOK;
    12991}
    130 
    131 /*----------------------------------------------------------------------------*/
    132 
     92/*----------------------------------------------------------------------------*/
    13393static int usb_hid_set_generic_hid_subdriver(usb_hid_dev_t *hid_dev)
    13494{
    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));
     95        assert(hid_dev != NULL);
     96        assert(hid_dev->subdriver_count == 0);
     97
     98        hid_dev->subdrivers = malloc(sizeof(usb_hid_subdriver_t));
    13999        if (hid_dev->subdrivers == NULL) {
    140100                return ENOMEM;
    141101        }
    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        
     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
    162110        return EOK;
    163111}
    164 
    165 /*----------------------------------------------------------------------------*/
    166 
    167 static bool usb_hid_ids_match(usb_hid_dev_t *hid_dev,
     112/*----------------------------------------------------------------------------*/
     113static bool usb_hid_ids_match(const usb_hid_dev_t *hid_dev,
    168114    const usb_hid_subdriver_mapping_t *mapping)
    169115{
    170116        assert(hid_dev != NULL);
    171117        assert(hid_dev->usb_dev != NULL);
    172        
    173         return (hid_dev->usb_dev->descriptors.device.vendor_id 
     118
     119        return (hid_dev->usb_dev->descriptors.device.vendor_id
    174120            == mapping->vendor_id
    175             && hid_dev->usb_dev->descriptors.device.product_id 
     121            && hid_dev->usb_dev->descriptors.device.product_id
    176122            == mapping->product_id);
    177123}
    178 
    179 /*----------------------------------------------------------------------------*/
    180 
    181 static bool usb_hid_path_matches(usb_hid_dev_t *hid_dev,
     124/*----------------------------------------------------------------------------*/
     125static bool usb_hid_path_matches(usb_hid_dev_t *hid_dev,
    182126    const usb_hid_subdriver_mapping_t *mapping)
    183127{
    184128        assert(hid_dev != NULL);
    185129        assert(mapping != NULL);
    186        
     130
    187131        usb_hid_report_path_t *usage_path = usb_hid_report_path();
    188132        if (usage_path == NULL) {
     
    190134                return false;
    191135        }
    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, 
     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,
    197141                    mapping->usage_path[i].usage) != EOK) {
    198142                        usb_log_debug("Failed to append to usage path.\n");
     
    200144                        return false;
    201145                }
    202                 ++i;
    203         }
    204        
    205         assert(hid_dev->report != NULL);
    206        
     146        }
     147
    207148        usb_log_debug("Compare flags: %d\n", mapping->compare);
    208        
     149
    209150        bool matches = false;
    210151        uint8_t report_id = mapping->report_id;
     
    212153        do {
    213154                usb_log_debug("Trying report id %u\n", report_id);
    214                
    215155                if (report_id != 0) {
    216156                        usb_hid_report_path_set_report_id(usage_path,
     
    218158                }
    219159
    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                
     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
    225165                usb_log_debug("Field: %p\n", field);
    226166
     
    229169                        break;
    230170                }
    231                
     171
    232172                report_id = usb_hid_get_next_report_id(
    233                     hid_dev->report, report_id,
    234                     USB_HID_REPORT_TYPE_INPUT);
     173                    &hid_dev->report, report_id, USB_HID_REPORT_TYPE_INPUT);
    235174        } while (!matches && report_id != 0);
    236        
     175
    237176        usb_hid_report_path_free(usage_path);
    238        
     177
    239178        return matches;
    240179}
    241 
    242 /*----------------------------------------------------------------------------*/
    243 
    244 static 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) {
     180/*----------------------------------------------------------------------------*/
     181static 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) {
    250188                hid_dev->subdriver_count = 0;
    251189                hid_dev->subdrivers = NULL;
    252190                return EOK;
    253191        }
    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));
     192
     193        /* +1 for generic hid subdriver */
     194        hid_dev->subdrivers = calloc((count + 1), sizeof(usb_hid_subdriver_t));
    259195        if (hid_dev->subdrivers == NULL) {
    260196                return ENOMEM;
    261197        }
    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        
     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 */
    270204        hid_dev->subdrivers[count].init = usb_generic_hid_init;
    271205        hid_dev->subdrivers[count].poll = usb_generic_hid_polling_callback;
    272         hid_dev->subdrivers[count].deinit = NULL;
     206        hid_dev->subdrivers[count].deinit = usb_generic_hid_deinit;
    273207        hid_dev->subdrivers[count].poll_end = NULL;
    274        
     208
    275209        hid_dev->subdriver_count = count + 1;
    276        
     210
    277211        return EOK;
    278212}
    279 
    280 /*----------------------------------------------------------------------------*/
    281 
     213/*----------------------------------------------------------------------------*/
    282214static int usb_hid_find_subdrivers(usb_hid_dev_t *hid_dev)
    283215{
    284216        assert(hid_dev != NULL);
    285        
     217
    286218        const usb_hid_subdriver_t *subdrivers[USB_HID_MAX_SUBDRIVERS];
    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
     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. */
    298225                if (mapping->vendor_id >= 0 && mapping->product_id < 0) {
    299                         usb_log_warning("Missing Product ID for Vendor ID %d\n",
    300                             mapping->vendor_id);
    301                         return EINVAL;
     226                        usb_log_warning("Mapping[%d]: Missing Product ID for "
     227                            "Vendor ID %d\n", i, mapping->vendor_id);
    302228                }
    303229                if (mapping->product_id >= 0 && mapping->vendor_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);
     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) {
    314238                        usb_log_debug("Comparing device against vendor ID %u"
    315239                            " and product ID %u.\n", mapping->vendor_id,
     
    317241                        if (usb_hid_ids_match(hid_dev, mapping)) {
    318242                                usb_log_debug("IDs matched.\n");
    319                                 ids_matched = true;
     243                                matched = true;
    320244                        }
    321245                }
    322                
     246
     247                /* Check usage match. */
    323248                if (mapping->usage_path != NULL) {
    324249                        usb_log_debug("Comparing device against usage path.\n");
    325250                        if (usb_hid_path_matches(hid_dev, mapping)) {
    326                                 // does not matter if IDs were matched
     251                                /* Does not matter if IDs were matched. */
    327252                                matched = true;
    328253                        }
    329                 } else {
    330                         // matched only if IDs were matched and there is no path
    331                         matched = ids_matched;
    332                 }
    333                
     254                }
     255
    334256                if (matched) {
    335257                        usb_log_debug("Subdriver matched.\n");
    336258                        subdrivers[count++] = &mapping->subdriver;
    337259                }
    338                
    339                 mapping = &usb_hid_subdrivers[++i];
    340         }
    341        
    342         // we have all subdrivers determined, save them into the hid device
     260        }
     261
     262        /* We have all subdrivers determined, save them into the hid device */
    343263        return usb_hid_save_subdrivers(hid_dev, subdrivers, count);
    344264}
    345 
    346 /*----------------------------------------------------------------------------*/
    347 
    348 static 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 
     265/*----------------------------------------------------------------------------*/
     266static 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/*----------------------------------------------------------------------------*/
    377293static int usb_hid_init_report(usb_hid_dev_t *hid_dev)
    378294{
    379         assert(hid_dev != NULL && hid_dev->report != NULL);
    380        
     295        assert(hid_dev != NULL);
     296
    381297        uint8_t report_id = 0;
    382         size_t size;
    383        
    384298        size_t max_size = 0;
    385        
     299
    386300        do {
    387301                usb_log_debug("Getting size of the report.\n");
    388                 size = usb_hid_report_byte_size(hid_dev->report, report_id,
    389                     USB_HID_REPORT_TYPE_INPUT);
     302                const size_t size =
     303                    usb_hid_report_byte_size(&hid_dev->report, report_id,
     304                        USB_HID_REPORT_TYPE_INPUT);
    390305                usb_log_debug("Report ID: %u, size: %zu\n", report_id, size);
    391306                max_size = (size > max_size) ? size : max_size;
    392307                usb_log_debug("Getting next report ID\n");
    393                 report_id = usb_hid_get_next_report_id(hid_dev->report,
     308                report_id = usb_hid_get_next_report_id(&hid_dev->report,
    394309                    report_id, USB_HID_REPORT_TYPE_INPUT);
    395310        } while (report_id != 0);
    396        
     311
    397312        usb_log_debug("Max size of input report: %zu\n", max_size);
    398        
    399         hid_dev->max_input_report_size = max_size;
     313
    400314        assert(hid_dev->input_report == NULL);
    401        
    402         hid_dev->input_report = malloc(max_size);
     315
     316        hid_dev->input_report = calloc(1, max_size);
    403317        if (hid_dev->input_report == NULL) {
    404318                return ENOMEM;
    405319        }
    406         memset(hid_dev->input_report, 0, max_size);
    407        
     320        hid_dev->max_input_report_size = max_size;
     321
    408322        return EOK;
    409323}
    410 
    411 /*----------------------------------------------------------------------------*/
    412 
    413 usb_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 
     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 */
    438342int usb_hid_init(usb_hid_dev_t *hid_dev, usb_device_t *dev)
    439343{
    440         int rc, i;
    441        
     344        assert(hid_dev);
     345        assert(dev);
     346
    442347        usb_log_debug("Initializing HID structure...\n");
    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        
     348
     349        usb_hid_report_init(&hid_dev->report);
     350
    456351        /* The USB device should already be initialized, save it in structure */
    457352        hid_dev->usb_dev = dev;
    458        
    459         rc = usb_hid_check_pipes(hid_dev, dev);
     353        hid_dev->poll_pipe_index = -1;
     354
     355        int rc = usb_hid_check_pipes(hid_dev, dev);
    460356        if (rc != EOK) {
    461357                return rc;
    462358        }
    463                
     359
    464360        /* Get the report descriptor and parse it. */
    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        
     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. */
    470366        if (rc == EOK) {
    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                 }
     367                usb_hid_find_subdrivers(hid_dev);
    481368        } else {
    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
     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
    489383                switch (hid_dev->poll_pipe_index) {
    490384                case USB_HID_KBD_POLL_EP_NO:
     
    492386                        rc = usb_kbd_set_boot_protocol(hid_dev);
    493387                        if (rc == EOK) {
    494                                 rc = usb_hid_set_boot_kbd_subdriver(hid_dev);
     388                                usb_hid_set_boot_kbd_subdriver(hid_dev);
    495389                        }
    496390                        break;
     
    499393                        rc = usb_mouse_set_boot_protocol(hid_dev);
    500394                        if (rc == EOK) {
    501                                 rc = usb_hid_set_boot_mouse_subdriver(hid_dev);
     395                                usb_hid_set_boot_mouse_subdriver(hid_dev);
    502396                        }
    503397                        break;
    504398                default:
    505                         assert(hid_dev->poll_pipe_index 
     399                        assert(hid_dev->poll_pipe_index
    506400                            == USB_HID_GENERIC_POLL_EP_NO);
    507                        
    508401                        usb_log_info("Falling back to generic HID driver.\n");
    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                                 }
     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;
    537438                        } else {
     439                                /* At least one subdriver initialized. */
    538440                                ok = true;
    539441                        }
    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
     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 */
    548451                rc = usb_hid_init_report(hid_dev);
    549452                if (rc != EOK) {
     
    552455                }
    553456        }
    554        
    555        
     457
    556458        return rc;
    557459}
    558 
    559 /*----------------------------------------------------------------------------*/
    560 
    561 bool usb_hid_polling_callback(usb_device_t *dev, uint8_t *buffer,
     460/*----------------------------------------------------------------------------*/
     461bool usb_hid_polling_callback(usb_device_t *dev, uint8_t *buffer,
    562462    size_t buffer_size, void *arg)
    563463{
    564         int i;
    565        
    566464        if (dev == NULL || arg == NULL || buffer == NULL) {
    567465                usb_log_error("Missing arguments to polling callback.\n");
    568466                return false;
    569467        }
    570        
    571         usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)arg;
    572        
     468        usb_hid_dev_t *hid_dev = arg;
     469
    573470        assert(hid_dev->input_report != NULL);
     471
    574472        usb_log_debug("New data [%zu/%zu]: %s\n", buffer_size,
    575473            hid_dev->max_input_report_size,
     
    582480                usb_hid_new_report(hid_dev);
    583481        }
    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        
     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);
    590486        if (rc != EOK) {
    591487                usb_log_warning("Error in usb_hid_parse_report():"
    592488                    "%s\n", str_error(rc));
    593         }       
    594        
     489        }
     490
    595491        bool cont = false;
    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        
     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
    606500        return cont;
    607501}
    608 
    609 /*----------------------------------------------------------------------------*/
    610 
    611 void 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) {
     502/*----------------------------------------------------------------------------*/
     503void 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) {
    623511                if (hid_dev->subdrivers[i].poll_end != NULL) {
    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 
     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/*----------------------------------------------------------------------------*/
    634520void usb_hid_new_report(usb_hid_dev_t *hid_dev)
    635521{
    636522        ++hid_dev->report_nr;
    637523}
    638 
    639 /*----------------------------------------------------------------------------*/
    640 
    641 int usb_hid_report_number(usb_hid_dev_t *hid_dev)
     524/*----------------------------------------------------------------------------*/
     525int usb_hid_report_number(const usb_hid_dev_t *hid_dev)
    642526{
    643527        return hid_dev->report_nr;
    644528}
    645 
    646 /*----------------------------------------------------------------------------*/
    647 
    648 void usb_hid_destroy(usb_hid_dev_t *hid_dev)
    649 {
    650         int i;
    651        
    652         if (hid_dev == NULL) {
    653                 return;
    654         }
    655        
     529/*----------------------------------------------------------------------------*/
     530void 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
    656536        usb_log_debug("Subdrivers: %p, subdriver count: %d\n",
    657537            hid_dev->subdrivers, hid_dev->subdriver_count);
    658        
    659         assert(hid_dev->subdrivers != NULL
    660             || hid_dev->subdriver_count == 0);
    661        
    662         for (i = 0; i < hid_dev->subdriver_count; ++i) {
     538
     539        for (unsigned i = 0; i < hid_dev->subdriver_count; ++i) {
    663540                if (hid_dev->subdrivers[i].deinit != NULL) {
    664541                        hid_dev->subdrivers[i].deinit(hid_dev,
     
    666543                }
    667544        }
    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         }
     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
    682553}
    683554
Note: See TracChangeset for help on using the changeset viewer.