Changes in / [4776ba9:c7bdfa7] in mainline


Ignore:
Location:
uspace
Files:
4 added
13 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/usbhid/Makefile

    r4776ba9 rc7bdfa7  
    4040        main.c \
    4141        usbhid.c \
     42        subdrivers.c \
    4243        kbd/conv.c \
    4344        kbd/kbddev.c \
    4445        kbd/kbdrepeat.c \
    4546        generic/hiddev.c \
     47        mouse/mousedev.c \
    4648        $(STOLEN_LAYOUT_SOURCES)
    4749
  • uspace/drv/usbhid/generic/hiddev.c

    r4776ba9 rc7bdfa7  
    3939
    4040#include "hiddev.h"
     41#include "usbhid.h"
    4142
    4243/*----------------------------------------------------------------------------*/
     
    5455/*----------------------------------------------------------------------------*/
    5556
    56 bool usb_hid_polling_callback(usb_device_t *dev, uint8_t *buffer,
    57      size_t buffer_size, void *arg)
     57bool usb_generic_hid_polling_callback(usb_hid_dev_t *hid_dev,
     58    uint8_t *buffer, size_t buffer_size)
    5859{
    59         usb_log_debug("usb_hid_polling_callback()\n");
     60        usb_log_debug("usb_hid_polling_callback(%p, %p, %zu)\n",
     61            hid_dev, buffer, buffer_size);
    6062        usb_debug_str_buffer(buffer, buffer_size, 0);
    6163        return true;
  • uspace/drv/usbhid/generic/hiddev.h

    r4776ba9 rc7bdfa7  
    3434 */
    3535
    36 #ifndef USB_HIDD_H_
    37 #define USB_HIDD_H_
     36#ifndef USB_HID_HIDDDEV_H_
     37#define USB_HID_HIDDDEV_H_
    3838
    3939#include <usb/devdrv.h>
     40
     41struct usb_hid_dev;
    4042
    4143usb_endpoint_description_t usb_hid_generic_poll_endpoint_description;
     
    4446const char *HID_GENERIC_CLASS_NAME;
    4547
    46 bool usb_hid_polling_callback(usb_device_t *dev, uint8_t *buffer,
    47      size_t buffer_size, void *arg);
     48bool usb_generic_hid_polling_callback(struct usb_hid_dev *hid_dev,
     49    uint8_t *buffer, size_t buffer_size);
    4850
    49 #endif // USB_HIDD_H_
     51#endif // USB_HID_HIDDDEV_H_
    5052
    5153/**
  • uspace/drv/usbhid/kbd/conv.h

    r4776ba9 rc7bdfa7  
    3434 */
    3535
    36 #ifndef USB_KBD_CONV_H_
    37 #define USB_KBD_CONV_H_
     36#ifndef USB_HID_CONV_H_
     37#define USB_HID_CONV_H_
    3838
    3939unsigned int usbhid_parse_scancode(int scancode);
    4040
    41 #endif /* USB_KBD_CONV_H_ */
     41#endif /* USB_HID_CONV_H_ */
    4242
    4343/**
  • uspace/drv/usbhid/kbd/kbddev.c

    r4776ba9 rc7bdfa7  
    238238 * @param icall Call data.
    239239 */
    240 void default_connection_handler(ddf_fun_t *fun,
     240static void default_connection_handler(ddf_fun_t *fun,
    241241    ipc_callid_t icallid, ipc_call_t *icall)
    242242{
     
    856856/*----------------------------------------------------------------------------*/
    857857
    858 bool usb_kbd_polling_callback(usb_device_t *dev, uint8_t *buffer,
    859      size_t buffer_size, void *arg)
    860 {
    861         if (dev == NULL || buffer == NULL || arg == NULL) {
     858bool usb_kbd_polling_callback(usb_hid_dev_t *hid_dev, uint8_t *buffer,
     859     size_t buffer_size)
     860{
     861        if (hid_dev == NULL || buffer == NULL) {
    862862                // do not continue polling (???)
    863863                return false;
    864864        }
    865        
    866         usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)arg;
    867865       
    868866        // TODO: add return value from this function
     
    916914/*----------------------------------------------------------------------------*/
    917915
    918 void usb_kbd_deinit(struct usb_hid_dev_t *hid_dev)
     916void usb_kbd_deinit(usb_hid_dev_t *hid_dev)
    919917{
    920918        if (hid_dev == NULL) {
  • uspace/drv/usbhid/kbd/kbddev.h

    r4776ba9 rc7bdfa7  
    3434 */
    3535
    36 #ifndef USB_KBDDEV_H_
    37 #define USB_KBDDEV_H_
     36#ifndef USB_HID_KBDDEV_H_
     37#define USB_HID_KBDDEV_H_
    3838
    3939#include <stdint.h>
     
    4949#include "kbdrepeat.h"
    5050
    51 struct usb_hid_dev_t;
     51struct usb_hid_dev;
    5252
    5353/*----------------------------------------------------------------------------*/
     
    6565 */
    6666typedef struct usb_kbd_t {
    67         /** Structure holding generic USB device information. */
    68         //usbhid_dev_t *hid_dev;
    69         //usb_device_t *usb_dev;
    70        
    7167        /** Currently pressed keys (not translated to key codes). */
    7268        uint8_t *keys;
     
    9187        fibril_mutex_t *repeat_mtx;
    9288       
    93         /** Report descriptor. */
    94         //uint8_t *report_desc;
    95 
    96         /** Report descriptor size. */
    97         //size_t report_desc_size;
    98        
    9989        uint8_t *output_buffer;
    10090       
     
    10696       
    10797        int32_t *led_data;
    108 
    109         /** HID Report parser. */
    110         //usb_hid_report_parser_t *parser;
    11198       
    11299        /** State of the structure (for checking before use).
     
    121108/*----------------------------------------------------------------------------*/
    122109
    123 //enum {
    124 //      USB_KBD_POLL_EP_NO = 0,
    125 //      USB_HID_POLL_EP_NO = 1,
    126 //      USB_KBD_POLL_EP_COUNT = 2
    127 //};
    128 
    129 //usb_endpoint_description_t *usb_kbd_endpoints[USB_KBD_POLL_EP_COUNT + 1];
    130 
    131 //ddf_dev_ops_t keyboard_ops;
    132 
    133110usb_endpoint_description_t usb_hid_kbd_poll_endpoint_description;
    134111
     
    138115/*----------------------------------------------------------------------------*/
    139116
    140 //usb_kbd_t *usb_kbd_new(void);
     117int usb_kbd_init(struct usb_hid_dev *hid_dev);
    141118
    142 int usb_kbd_init(struct usb_hid_dev_t *hid_dev);
    143 
    144 bool usb_kbd_polling_callback(usb_device_t *dev, uint8_t *buffer,
    145      size_t buffer_size, void *arg);
    146 
    147 //void usb_kbd_polling_ended_callback(usb_device_t *dev, bool reason,
    148 //     void *arg);
     119bool usb_kbd_polling_callback(struct usb_hid_dev *hid_dev, uint8_t *buffer,
     120    size_t buffer_size);
    149121
    150122int usb_kbd_is_initialized(const usb_kbd_t *kbd_dev);
     
    154126void usb_kbd_free(usb_kbd_t **kbd_dev);
    155127
    156 void usb_kbd_push_ev(struct usb_hid_dev_t *hid_dev, usb_kbd_t *kbd_dev,
     128void usb_kbd_push_ev(struct usb_hid_dev *hid_dev, usb_kbd_t *kbd_dev,
    157129    int type, unsigned int key);
    158130
     131void usb_kbd_deinit(struct usb_hid_dev *hid_dev);
    159132
    160 void usb_kbd_deinit(struct usb_hid_dev_t *hid_dev);
     133int usb_kbd_set_boot_protocol(struct usb_hid_dev *hid_dev);
    161134
    162 int usb_kbd_set_boot_protocol(struct usb_hid_dev_t *hid_dev);
    163 
    164 #endif /* USB_KBDDEV_H_ */
     135#endif /* USB_HID_KBDDEV_H_ */
    165136
    166137/**
  • uspace/drv/usbhid/kbd/kbdrepeat.h

    r4776ba9 rc7bdfa7  
    3434 */
    3535
    36 #ifndef USB_KBDREPEAT_H_
    37 #define USB_KBDREPEAT_H_
     36#ifndef USB_HID_KBDREPEAT_H_
     37#define USB_HID_KBDREPEAT_H_
    3838
    3939struct usb_kbd_t;
     
    6262void usb_kbd_repeat_stop(struct usb_kbd_t *kbd, unsigned int key);
    6363
    64 #endif /* USB_KBDREPEAT_H_ */
     64#endif /* USB_HID_KBDREPEAT_H_ */
    6565
    6666/**
  • uspace/drv/usbhid/layout.h

    r4776ba9 rc7bdfa7  
    3636 */
    3737
    38 #ifndef USB_KBD_LAYOUT_H_
    39 #define USB_KBD_LAYOUT_H_
     38#ifndef USB_HID_LAYOUT_H_
     39#define USB_HID_LAYOUT_H_
    4040
    4141#include <sys/types.h>
  • uspace/drv/usbhid/main.c

    r4776ba9 rc7bdfa7  
    9898        /* Create the function exposed under /dev/devices. */
    9999        ddf_fun_t *hid_fun = ddf_fun_create(dev->ddf_dev, fun_exposed,
    100             usb_hid_get_function_name(hid_dev->device_type));
     100            usb_hid_get_function_name(hid_dev));
    101101        if (hid_fun == NULL) {
    102102                usb_log_error("Could not create DDF function node.\n");
     
    122122        }
    123123       
    124         rc = ddf_fun_add_to_class(hid_fun,
    125             usb_hid_get_class_name(hid_dev->device_type));
     124        rc = ddf_fun_add_to_class(hid_fun, usb_hid_get_class_name(hid_dev));
    126125        if (rc != EOK) {
    127126                usb_log_error(
     
    142141           hid_dev->poll_pipe_index,
    143142           /* Callback when data arrives. */
    144            hid_dev->poll_callback,
     143           usb_hid_polling_callback,
    145144           /* How much data to request. */
    146145           dev->pipes[hid_dev->poll_pipe_index].pipe->max_packet_size,
  • uspace/drv/usbhid/usbhid.c

    r4776ba9 rc7bdfa7  
    4242#include <usb/classes/hidreq.h>
    4343#include <errno.h>
     44#include <str_error.h>
    4445
    4546#include "usbhid.h"
     
    4748#include "kbd/kbddev.h"
    4849#include "generic/hiddev.h"
    49 
    50 /*----------------------------------------------------------------------------*/
    51 
    52 /** Mouse polling endpoint description for boot protocol class. */
    53 static usb_endpoint_description_t usb_hid_mouse_poll_endpoint_description = {
    54         .transfer_type = USB_TRANSFER_INTERRUPT,
    55         .direction = USB_DIRECTION_IN,
    56         .interface_class = USB_CLASS_HID,
    57         .interface_subclass = USB_HID_SUBCLASS_BOOT,
    58         .interface_protocol = USB_HID_PROTOCOL_MOUSE,
    59         .flags = 0
    60 };
     50#include "mouse/mousedev.h"
     51#include "subdrivers.h"
     52
     53/*----------------------------------------------------------------------------*/
    6154
    6255/* Array of endpoints expected on the device, NULL terminated. */
     
    6861};
    6962
    70 static const char *HID_MOUSE_FUN_NAME = "mouse";
    71 static const char *HID_MOUSE_CLASS_NAME = "mouse";
     63static const int USB_HID_MAX_SUBDRIVERS = 10;
     64
     65/*----------------------------------------------------------------------------*/
     66
     67static int usb_hid_set_boot_kbd_subdriver(usb_hid_dev_t *hid_dev)
     68{
     69        assert(hid_dev->subdriver_count == 0);
     70       
     71        hid_dev->subdrivers = (usb_hid_subdriver_t *)malloc(
     72            sizeof(usb_hid_subdriver_t));
     73        if (hid_dev->subdrivers == NULL) {
     74                return ENOMEM;
     75        }
     76       
     77        // set the init callback
     78        hid_dev->subdrivers[0].init = usb_kbd_init;
     79       
     80        // set the polling callback
     81        hid_dev->subdrivers[0].poll = usb_kbd_polling_callback;
     82       
     83        // set the polling ended callback
     84        hid_dev->subdrivers[0].poll_end = NULL;
     85       
     86        // set the deinit callback
     87        hid_dev->subdrivers[0].deinit = usb_kbd_deinit;
     88       
     89        // set subdriver count
     90        hid_dev->subdriver_count = 1;
     91       
     92        return EOK;
     93}
     94
     95/*----------------------------------------------------------------------------*/
     96
     97static int usb_hid_set_boot_mouse_subdriver(usb_hid_dev_t *hid_dev)
     98{
     99        assert(hid_dev->subdriver_count == 0);
     100       
     101        hid_dev->subdrivers = (usb_hid_subdriver_t *)malloc(
     102            sizeof(usb_hid_subdriver_t));
     103        if (hid_dev->subdrivers == NULL) {
     104                return ENOMEM;
     105        }
     106       
     107        // set the init callback
     108        hid_dev->subdrivers[0].init = usb_mouse_init;
     109       
     110        // set the polling callback
     111        hid_dev->subdrivers[0].poll = usb_mouse_polling_callback;
     112       
     113        // set the polling ended callback
     114        hid_dev->subdrivers[0].poll_end = NULL;
     115       
     116        // set the deinit callback
     117        hid_dev->subdrivers[0].deinit = usb_mouse_deinit;
     118       
     119        // set subdriver count
     120        hid_dev->subdriver_count = 1;
     121       
     122        return EOK;
     123}
     124
     125/*----------------------------------------------------------------------------*/
     126
     127static int usb_hid_set_generic_hid_subdriver(usb_hid_dev_t *hid_dev)
     128{
     129        assert(hid_dev->subdriver_count == 0);
     130       
     131        hid_dev->subdrivers = (usb_hid_subdriver_t *)malloc(
     132            sizeof(usb_hid_subdriver_t));
     133        if (hid_dev->subdrivers == NULL) {
     134                return ENOMEM;
     135        }
     136       
     137        // set the init callback
     138        hid_dev->subdrivers[0].init = NULL;
     139       
     140        // set the polling callback
     141        hid_dev->subdrivers[0].poll = usb_generic_hid_polling_callback;
     142       
     143        // set the polling ended callback
     144        hid_dev->subdrivers[0].poll_end = NULL;
     145       
     146        // set the deinit callback
     147        hid_dev->subdrivers[0].deinit = NULL;
     148       
     149        // set subdriver count
     150        hid_dev->subdriver_count = 1;
     151       
     152        return EOK;
     153}
     154
     155/*----------------------------------------------------------------------------*/
     156
     157static bool usb_hid_ids_match(usb_hid_dev_t *hid_dev,
     158    const usb_hid_subdriver_mapping_t *mapping)
     159{
     160        return false;
     161}
     162
     163/*----------------------------------------------------------------------------*/
     164
     165static bool usb_hid_path_matches(usb_hid_dev_t *hid_dev,
     166    const usb_hid_subdriver_usage_t *path, int path_size, int compare)
     167{
     168        assert(hid_dev != NULL);
     169        assert(path != NULL);
     170       
     171        usb_hid_report_path_t *usage_path = usb_hid_report_path();
     172        if (usage_path == NULL) {
     173                usb_log_debug("Failed to create usage path.\n");
     174                return false;
     175        }
     176        int i;
     177        for (i = 0; i < path_size; ++i) {
     178                if (usb_hid_report_path_append_item(usage_path,
     179                    path[i].usage_page, path[i].usage) != EOK) {
     180                        usb_log_debug("Failed to append to usage path.\n");
     181                        usb_hid_report_path_free(usage_path);
     182                        return false;
     183                }
     184        }
     185       
     186        assert(hid_dev->parser != NULL);
     187       
     188        usb_log_debug("Compare flags: %d\n", compare);
     189        size_t size = usb_hid_report_input_length(hid_dev->parser, usage_path,
     190            compare);
     191        usb_log_debug("Size of the input report: %d\n", size);
     192       
     193        usb_hid_report_path_free(usage_path);
     194       
     195        return (size > 0);
     196}
     197
     198/*----------------------------------------------------------------------------*/
     199
     200static int usb_hid_save_subdrivers(usb_hid_dev_t *hid_dev,
     201    const usb_hid_subdriver_t **subdrivers, int count)
     202{
     203        int i;
     204       
     205        if (count <= 0) {
     206                hid_dev->subdriver_count = 0;
     207                hid_dev->subdrivers = NULL;
     208                return EOK;
     209        }
     210       
     211        hid_dev->subdrivers = (usb_hid_subdriver_t *)malloc(count *
     212            sizeof(usb_hid_subdriver_t));
     213        if (hid_dev->subdrivers == NULL) {
     214                return ENOMEM;
     215        }
     216       
     217        for (i = 0; i < count; ++i) {
     218                hid_dev->subdrivers[i].init = subdrivers[i]->init;
     219                hid_dev->subdrivers[i].deinit = subdrivers[i]->deinit;
     220                hid_dev->subdrivers[i].poll = subdrivers[i]->poll;
     221                hid_dev->subdrivers[i].poll_end = subdrivers[i]->poll_end;
     222        }
     223       
     224        hid_dev->subdriver_count = count;
     225       
     226        return EOK;
     227}
     228
     229/*----------------------------------------------------------------------------*/
     230
     231static int usb_hid_find_subdrivers(usb_hid_dev_t *hid_dev)
     232{
     233        const usb_hid_subdriver_t *subdrivers[USB_HID_MAX_SUBDRIVERS];
     234       
     235        int i = 0, count = 0;
     236        const usb_hid_subdriver_mapping_t *mapping = &usb_hid_subdrivers[i];
     237       
     238        while (count < USB_HID_MAX_SUBDRIVERS &&
     239            (mapping->usage_path != NULL
     240            || mapping->vendor_id != NULL
     241            || mapping->product_id != NULL)) {
     242                // check the vendor & product ID
     243                if (mapping->vendor_id != NULL && mapping->product_id == NULL) {
     244                        usb_log_warning("Missing Product ID for Vendor ID %s\n",
     245                            mapping->vendor_id);
     246                        return EINVAL;
     247                }
     248                if (mapping->product_id != NULL && mapping->vendor_id == NULL) {
     249                        usb_log_warning("Missing Vendor ID for Product ID %s\n",
     250                            mapping->product_id);
     251                        return EINVAL;
     252                }
     253               
     254                if (mapping->vendor_id != NULL) {
     255                        assert(mapping->product_id != NULL);
     256                        usb_log_debug("Comparing device against vendor ID %s"
     257                            " and product ID %s.\n", mapping->vendor_id,
     258                            mapping->product_id);
     259                        if (usb_hid_ids_match(hid_dev, mapping)) {
     260                                usb_log_debug("Matched.\n");
     261                                subdrivers[count++] = &mapping->subdriver;
     262                                // skip the checking of usage path
     263                                goto next;
     264                        }
     265                }
     266               
     267                if (mapping->usage_path != NULL) {
     268                        usb_log_debug("Comparing device against usage path.\n");
     269                        if (usb_hid_path_matches(hid_dev,
     270                            mapping->usage_path, mapping->path_size,
     271                            mapping->compare)) {
     272                                subdrivers[count++] = &mapping->subdriver;
     273                        } else {
     274                                usb_log_debug("Not matched.\n");
     275                        }
     276                }
     277        next:
     278                mapping = &usb_hid_subdrivers[++i];
     279        }
     280       
     281        // we have all subdrivers determined, save them into the hid device
     282        return usb_hid_save_subdrivers(hid_dev, subdrivers, count);
     283}
     284
     285/*----------------------------------------------------------------------------*/
     286
     287static int usb_hid_check_pipes(usb_hid_dev_t *hid_dev, usb_device_t *dev)
     288{
     289        int rc = EOK;
     290       
     291        if (dev->pipes[USB_HID_KBD_POLL_EP_NO].present) {
     292                usb_log_debug("Found keyboard endpoint.\n");
     293                // save the pipe index
     294                hid_dev->poll_pipe_index = USB_HID_KBD_POLL_EP_NO;
     295        } else if (dev->pipes[USB_HID_MOUSE_POLL_EP_NO].present) {
     296                usb_log_debug("Found mouse endpoint.\n");
     297                // save the pipe index
     298                hid_dev->poll_pipe_index = USB_HID_MOUSE_POLL_EP_NO;
     299        } else if (dev->pipes[USB_HID_GENERIC_POLL_EP_NO].present) {
     300                usb_log_debug("Found generic HID endpoint.\n");
     301                // save the pipe index
     302                hid_dev->poll_pipe_index = USB_HID_GENERIC_POLL_EP_NO;
     303        } else {
     304                usb_log_error("None of supported endpoints found - probably"
     305                    " not a supported device.\n");
     306                rc = ENOTSUP;
     307        }
     308       
     309        return rc;
     310}
    72311
    73312/*----------------------------------------------------------------------------*/
     
    91330        }
    92331       
     332        hid_dev->poll_pipe_index = -1;
     333       
    93334        return hid_dev;
    94335}
     
    96337/*----------------------------------------------------------------------------*/
    97338
    98 static bool usb_dummy_polling_callback(usb_device_t *dev, uint8_t *buffer,
    99      size_t buffer_size, void *arg)
    100 {
    101         usb_log_debug("Dummy polling callback.\n");
    102         return false;
    103 }
    104 
    105 /*----------------------------------------------------------------------------*/
    106 
    107 static int usb_hid_check_pipes(usb_hid_dev_t *hid_dev, usb_device_t *dev)
    108 {
    109         if (dev->pipes[USB_HID_KBD_POLL_EP_NO].present) {
    110                 usb_log_debug("Found keyboard endpoint.\n");
    111                
    112                 // save the pipe index and device type
    113                 hid_dev->poll_pipe_index = USB_HID_KBD_POLL_EP_NO;
    114                 hid_dev->device_type = USB_HID_PROTOCOL_KEYBOARD;
    115                
    116                 // set the polling callback
    117                 hid_dev->poll_callback = usb_kbd_polling_callback;
    118 
    119         } else if (dev->pipes[USB_HID_MOUSE_POLL_EP_NO].present) {
    120                 usb_log_debug("Found mouse endpoint.\n");
    121                
    122                 // save the pipe index and device type
    123                 hid_dev->poll_pipe_index = USB_HID_MOUSE_POLL_EP_NO;
    124                 hid_dev->device_type = USB_HID_PROTOCOL_MOUSE;
    125                
    126                 // set the polling callback
    127                 hid_dev->poll_callback = usb_dummy_polling_callback;
    128                
    129         } else if (dev->pipes[USB_HID_GENERIC_POLL_EP_NO].present) {
    130                 usb_log_debug("Found generic HID endpoint.\n");
    131                
    132                 // save the pipe index and device type
    133                 hid_dev->poll_pipe_index = USB_HID_GENERIC_POLL_EP_NO;
    134                 hid_dev->device_type = USB_HID_PROTOCOL_NONE;
    135                
    136                 // set the polling callback
    137                 hid_dev->poll_callback = usb_hid_polling_callback;
    138                
    139         } else {
    140                 usb_log_warning("None of supported endpoints found - probably"
    141                     " not a supported device.\n");
    142                 return ENOTSUP;
    143         }
    144        
    145         return EOK;
    146 }
    147 
    148 /*----------------------------------------------------------------------------*/
    149 
    150 static int usb_hid_init_parser(usb_hid_dev_t *hid_dev)
    151 {
    152         /* Initialize the report parser. */
    153         int rc = usb_hid_parser_init(hid_dev->parser);
    154         if (rc != EOK) {
    155                 usb_log_error("Failed to initialize report parser.\n");
    156                 return rc;
    157         }
    158        
    159         /* Get the report descriptor and parse it. */
    160         rc = usb_hid_process_report_descriptor(hid_dev->usb_dev,
    161             hid_dev->parser);
    162        
    163         if (rc != EOK) {
    164                 usb_log_warning("Could not process report descriptor.\n");
    165                
    166                 if (hid_dev->device_type == USB_HID_PROTOCOL_KEYBOARD) {
    167                         usb_log_warning("Falling back to boot protocol.\n");
    168                        
    169                         rc = usb_kbd_set_boot_protocol(hid_dev);
    170                        
    171                 } else if (hid_dev->device_type == USB_HID_PROTOCOL_MOUSE) {
    172                         usb_log_warning("No boot protocol for mouse yet.\n");
    173                         rc = ENOTSUP;
    174                 }
    175         }
    176        
    177         return rc;
    178 }
    179 
    180 /*----------------------------------------------------------------------------*/
    181 
    182339int usb_hid_init(usb_hid_dev_t *hid_dev, usb_device_t *dev)
    183340{
    184         int rc;
     341        int rc, i;
    185342       
    186343        usb_log_debug("Initializing HID structure...\n");
     
    203360        rc = usb_hid_check_pipes(hid_dev, dev);
    204361        if (rc != EOK) {
     362                usb_hid_free(&hid_dev);
    205363                return rc;
    206364        }
    207365       
    208         rc = usb_hid_init_parser(hid_dev);
     366        /* Initialize the report parser. */
     367        rc = usb_hid_parser_init(hid_dev->parser);
    209368        if (rc != EOK) {
    210                 usb_log_error("Failed to initialize HID parser.\n");
     369                usb_log_error("Failed to initialize report parser.\n");
     370                usb_hid_free(&hid_dev);
    211371                return rc;
    212372        }
    213373       
    214         switch (hid_dev->device_type) {
    215         case USB_HID_PROTOCOL_KEYBOARD:
    216                 // initialize the keyboard structure
    217                 rc = usb_kbd_init(hid_dev);
    218                 if (rc != EOK) {
    219                         usb_log_warning("Failed to initialize KBD structure."
    220                             "\n");
    221                 }
    222                 break;
    223         case USB_HID_PROTOCOL_MOUSE:
    224                 break;
    225         default:
    226 //              usbhid_req_set_idle(&hid_dev->usb_dev->ctrl_pipe,
    227 //                  hid_dev->usb_dev->interface_no, 0);
    228                 break;
     374        /* Get the report descriptor and parse it. */
     375        rc = usb_hid_process_report_descriptor(hid_dev->usb_dev,
     376            hid_dev->parser);
     377       
     378        bool fallback = false;
     379       
     380        if (rc == EOK) {
     381                // try to find subdrivers that may want to handle this device
     382                rc = usb_hid_find_subdrivers(hid_dev);
     383                if (rc != EOK || hid_dev->subdriver_count == 0) {
     384                        // try to fall back to the boot protocol if available
     385                        usb_log_info("No subdrivers found to handle this"
     386                            " device.\n");
     387                        fallback = true;
     388                }
     389        } else {
     390                usb_log_error("Failed to parse Report descriptor.\n");
     391                // try to fall back to the boot protocol if available
     392                fallback = true;
     393        }
     394       
     395        // TODO: remove the mouse hack
     396        if (hid_dev->poll_pipe_index == USB_HID_MOUSE_POLL_EP_NO ||
     397            fallback) {
     398                // fall back to boot protocol
     399                switch (hid_dev->poll_pipe_index) {
     400                case USB_HID_KBD_POLL_EP_NO:
     401                        usb_log_info("Falling back to kbd boot protocol.\n");
     402                        rc = usb_kbd_set_boot_protocol(hid_dev);
     403                        if (rc == EOK) {
     404                                rc = usb_hid_set_boot_kbd_subdriver(hid_dev);
     405                        }
     406                        break;
     407                case USB_HID_MOUSE_POLL_EP_NO:
     408                        usb_log_info("Falling back to mouse boot protocol.\n");
     409                        rc = usb_mouse_set_boot_protocol(hid_dev);
     410                        if (rc == EOK) {
     411                                rc = usb_hid_set_boot_mouse_subdriver(hid_dev);
     412                        }
     413                        break;
     414                default:
     415                        assert(hid_dev->poll_pipe_index
     416                            == USB_HID_GENERIC_POLL_EP_NO);
     417                       
     418                        /* TODO: this has no meaning if the report descriptor
     419                                 is not parsed */
     420                        usb_log_info("Falling back to generic HID driver.\n");
     421                        rc = usb_hid_set_generic_hid_subdriver(hid_dev);
     422                }
     423        }
     424       
     425        if (rc != EOK) {
     426                usb_log_error("No subdriver for handling this device could be"
     427                    " initialized: %s.\n", str_error(rc));
     428                usb_hid_free(&hid_dev);
     429        } else {
     430                bool ok = false;
     431               
     432                usb_log_debug("Subdriver count: %d\n",
     433                    hid_dev->subdriver_count);
     434               
     435                for (i = 0; i < hid_dev->subdriver_count; ++i) {
     436                        if (hid_dev->subdrivers[i].init != NULL) {
     437                                usb_log_debug("Initializing subdriver %d.\n",i);
     438                                rc = hid_dev->subdrivers[i].init(hid_dev);
     439                                if (rc != EOK) {
     440                                        usb_log_warning("Failed to initialize"
     441                                            " HID subdriver structure.\n");
     442                                } else {
     443                                        // at least one subdriver initialized
     444                                        ok = true;
     445                                }
     446                        } else {
     447                                ok = true;
     448                        }
     449                }
     450               
     451                rc = (ok) ? EOK : -1;   // what error to report
    229452        }
    230453       
    231454        return rc;
     455}
     456
     457/*----------------------------------------------------------------------------*/
     458
     459bool usb_hid_polling_callback(usb_device_t *dev, uint8_t *buffer,
     460    size_t buffer_size, void *arg)
     461{
     462        int i;
     463       
     464        if (dev == NULL || arg == NULL || buffer == NULL) {
     465                usb_log_error("Missing arguments to polling callback.\n");
     466                return false;
     467        }
     468       
     469        usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)arg;
     470       
     471        bool cont = false;
     472       
     473        // continue if at least one of the subdrivers want to continue
     474        for (i = 0; i < hid_dev->subdriver_count; ++i) {
     475                if (hid_dev->subdrivers[i].poll != NULL
     476                    && hid_dev->subdrivers[i].poll(hid_dev, buffer,
     477                    buffer_size)) {
     478                        cont = true;
     479                }
     480        }
     481       
     482        return cont;
    232483}
    233484
     
    237488     void *arg)
    238489{
     490        int i;
     491       
    239492        if (dev == NULL || arg == NULL) {
    240493                return;
     
    243496        usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)arg;
    244497       
     498        for (i = 0; i < hid_dev->subdriver_count; ++i) {
     499                if (hid_dev->subdrivers[i].poll_end != NULL) {
     500                        hid_dev->subdrivers[i].poll_end(hid_dev, reason);
     501                }
     502        }
     503       
    245504        usb_hid_free(&hid_dev);
    246505}
     
    248507/*----------------------------------------------------------------------------*/
    249508
    250 const char *usb_hid_get_function_name(usb_hid_iface_protocol_t device_type)
    251 {
    252         switch (device_type) {
    253         case USB_HID_PROTOCOL_KEYBOARD:
     509const char *usb_hid_get_function_name(const usb_hid_dev_t *hid_dev)
     510{
     511        switch (hid_dev->poll_pipe_index) {
     512        case USB_HID_KBD_POLL_EP_NO:
    254513                return HID_KBD_FUN_NAME;
    255514                break;
    256         case USB_HID_PROTOCOL_MOUSE:
     515        case USB_HID_MOUSE_POLL_EP_NO:
    257516                return HID_MOUSE_FUN_NAME;
    258517                break;
     
    264523/*----------------------------------------------------------------------------*/
    265524
    266 const char *usb_hid_get_class_name(usb_hid_iface_protocol_t device_type)
    267 {
    268         switch (device_type) {
    269         case USB_HID_PROTOCOL_KEYBOARD:
     525const char *usb_hid_get_class_name(const usb_hid_dev_t *hid_dev)
     526{
     527        // this means that only boot protocol keyboards will be connected
     528        // to the console; there is probably no better way to do this
     529       
     530        switch (hid_dev->poll_pipe_index) {
     531        case USB_HID_KBD_POLL_EP_NO:
    270532                return HID_KBD_CLASS_NAME;
    271533                break;
    272         case USB_HID_PROTOCOL_MOUSE:
     534        case USB_HID_MOUSE_POLL_EP_NO:
    273535                return HID_MOUSE_CLASS_NAME;
    274536                break;
     
    282544void usb_hid_free(usb_hid_dev_t **hid_dev)
    283545{
     546        int i;
     547       
    284548        if (hid_dev == NULL || *hid_dev == NULL) {
    285549                return;
    286550        }
    287551       
    288         switch ((*hid_dev)->device_type) {
    289         case USB_HID_PROTOCOL_KEYBOARD:
    290                 usb_kbd_deinit(*hid_dev);
    291                 break;
    292         case USB_HID_PROTOCOL_MOUSE:
    293                 break;
    294         default:
    295                 break;
     552        assert((*hid_dev)->subdrivers != NULL
     553            || (*hid_dev)->subdriver_count == 0);
     554       
     555        for (i = 0; i < (*hid_dev)->subdriver_count; ++i) {
     556                if ((*hid_dev)->subdrivers[i].deinit != NULL) {
     557                        (*hid_dev)->subdrivers[i].deinit(*hid_dev);
     558                }
     559        }
     560       
     561        // free the subdrivers info
     562        if ((*hid_dev)->subdrivers != NULL) {
     563                free((*hid_dev)->subdrivers);
    296564        }
    297565
  • uspace/drv/usbhid/usbhid.h

    r4776ba9 rc7bdfa7  
    3434 */
    3535
    36 #ifndef USB_USBHID_H_
    37 #define USB_USBHID_H_
     36#ifndef USB_HID_USBHID_H_
     37#define USB_HID_USBHID_H_
    3838
    3939#include <stdint.h>
     
    4545#include <usb/classes/hid.h>
    4646
     47struct usb_hid_dev;
     48
     49typedef int (*usb_hid_driver_init_t)(struct usb_hid_dev *);
     50typedef void (*usb_hid_driver_deinit_t)(struct usb_hid_dev *);
     51typedef bool (*usb_hid_driver_poll)(struct usb_hid_dev *, uint8_t *, size_t);
     52typedef int (*usb_hid_driver_poll_ended)(struct usb_hid_dev *, bool reason);
     53
     54// TODO: add function and class name??
     55typedef struct usb_hid_subdriver {     
     56        /** Function to be called when initializing HID device. */
     57        usb_hid_driver_init_t init;
     58        /** Function to be called when destroying the HID device structure. */
     59        usb_hid_driver_deinit_t deinit;
     60        /** Function to be called when data arrives from the device. */
     61        usb_hid_driver_poll poll;
     62        /** Function to be called when polling ends. */
     63        usb_hid_driver_poll_ended poll_end;
     64} usb_hid_subdriver_t;
     65
    4766/*----------------------------------------------------------------------------*/
    4867/**
    4968 * Structure for holding general HID device data.
    5069 */
    51 typedef struct usb_hid_dev_t {
     70typedef struct usb_hid_dev {
    5271        /** Structure holding generic USB device information. */
    5372        usb_device_t *usb_dev;
     
    5978        int poll_pipe_index;
    6079       
    61         /** Function to be called when data arrives from the device. */
    62         usb_polling_callback_t poll_callback;
     80        /** Subdrivers. */
     81        usb_hid_subdriver_t *subdrivers;
     82       
     83        /** Number of subdrivers. */
     84        int subdriver_count;
    6385       
    6486        /** Report descriptor. */
     
    7395        /** Arbitrary data (e.g. a special structure for handling keyboard). */
    7496        void *data;
    75        
    76         /** Type of the device (keyboard, mouse, generic HID device). */
    77         usb_hid_iface_protocol_t device_type;
    7897} usb_hid_dev_t;
    7998
     
    95114int usb_hid_init(usb_hid_dev_t *hid_dev, usb_device_t *dev);
    96115
     116bool usb_hid_polling_callback(usb_device_t *dev, uint8_t *buffer,
     117    size_t buffer_size, void *arg);
     118
    97119void usb_hid_polling_ended_callback(usb_device_t *dev, bool reason,
    98120     void *arg);
    99121
    100 const char *usb_hid_get_function_name(usb_hid_iface_protocol_t device_type);
     122const char *usb_hid_get_function_name(const usb_hid_dev_t *hid_dev);
    101123
    102 const char *usb_hid_get_class_name(usb_hid_iface_protocol_t device_type);
     124const char *usb_hid_get_class_name(const usb_hid_dev_t *hid_dev);
    103125
    104126void usb_hid_free(usb_hid_dev_t **hid_dev);
    105127
    106 #endif /* USB_USBHID_H_ */
     128#endif /* USB_HID_USBHID_H_ */
    107129
    108130/**
  • uspace/drv/usbhid/usbhid.ma

    r4776ba9 rc7bdfa7  
    11100 usb&interface&class=HID&subclass=0x01&protocol=0x01
    2 100 usb&interface&class=HID&subclass=0x01&protocol=0x02
     21000 usb&interface&class=HID&subclass=0x01&protocol=0x02
    33100 usb&interface&class=HID
  • uspace/lib/usb/src/hidparser.c

    r4776ba9 rc7bdfa7  
    900900        item->usage_page = usage_page;
    901901       
     902        usb_log_debug("Appending usage %d, usage page %d\n", usage, usage_page);
     903       
    902904        list_append (&usage_path->link, &item->link);
    903905        usage_path->depth++;
Note: See TracChangeset for help on using the changeset viewer.