Changeset acdbd780 in mainline


Ignore:
Timestamp:
2011-05-06T07:51:28Z (13 years ago)
Author:
Matej Klonfar <maklf@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
10849ffc, 3b5d5b9d
Parents:
b9d7965 (diff), 054537b (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

development merge

Location:
uspace
Files:
15 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/usbhid/generic/hiddev.c

    rb9d7965 racdbd780  
    3737#include <usb/debug.h>
    3838#include <usb/classes/classes.h>
     39#include <errno.h>
     40#include <str_error.h>
     41
     42#include <usbhid_iface.h>
    3943
    4044#include "hiddev.h"
     
    5559/*----------------------------------------------------------------------------*/
    5660
     61static size_t usb_generic_hid_get_event_length(ddf_fun_t *fun);
     62
     63static int usb_generic_hid_get_event(ddf_fun_t *fun, int32_t *buffer,
     64    size_t size, size_t *act_size, unsigned int flags);
     65
     66/*----------------------------------------------------------------------------*/
     67
     68static usbhid_iface_t usb_generic_iface = {
     69        .get_event = usb_generic_hid_get_event,
     70        .get_event_length = usb_generic_hid_get_event_length
     71};
     72
     73static ddf_dev_ops_t usb_generic_hid_ops = {
     74        .interfaces[USBHID_DEV_IFACE] = &usb_generic_iface
     75};
     76
     77/*----------------------------------------------------------------------------*/
     78
     79static size_t usb_generic_hid_get_event_length(ddf_fun_t *fun)
     80{
     81        if (fun == NULL || fun->driver_data) {
     82                return 0;
     83        }
     84
     85        usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)fun->driver_data;
     86       
     87        return hid_dev->input_report_size;
     88}
     89
     90/*----------------------------------------------------------------------------*/
     91
     92static int usb_generic_hid_get_event(ddf_fun_t *fun, int32_t *buffer,
     93    size_t size, size_t *act_size, unsigned int flags)
     94{
     95        if (fun == NULL || fun->driver_data) {
     96                return EINVAL;
     97        }
     98
     99        usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)fun->driver_data;
     100       
     101        if (hid_dev->input_report_size > size) {
     102                return EINVAL;  // TODO: other error code
     103        }
     104       
     105        /*! @todo This should probably be atomic. */
     106        memcpy(buffer, hid_dev->input_report, hid_dev->input_report_size);
     107        *act_size = hid_dev->input_report_size;
     108       
     109        // clear the buffer so that it will not be received twice
     110        memset(hid_dev->input_report, 0, hid_dev->input_report_size);
     111       
     112        return EOK;
     113}
     114
     115/*----------------------------------------------------------------------------*/
     116
     117static int usb_generic_hid_create_function(usb_hid_dev_t *hid_dev)
     118{       
     119        /* Create the function exposed under /dev/devices. */
     120        /** @todo Generate numbers for the devices? */
     121        usb_log_debug("Creating DDF function %s...\n", HID_GENERIC_FUN_NAME);
     122        ddf_fun_t *fun = ddf_fun_create(hid_dev->usb_dev->ddf_dev, fun_exposed,
     123            HID_GENERIC_FUN_NAME);
     124        if (fun == NULL) {
     125                usb_log_error("Could not create DDF function node.\n");
     126                return ENOMEM;
     127        }
     128
     129        int rc = ddf_fun_bind(fun);
     130        if (rc != EOK) {
     131                usb_log_error("Could not bind DDF function: %s.\n",
     132                    str_error(rc));
     133                ddf_fun_destroy(fun);
     134                return rc;
     135        }
     136       
     137        fun->ops = &usb_generic_hid_ops;
     138        fun->driver_data = hid_dev;
     139       
     140        return EOK;
     141}
     142
     143/*----------------------------------------------------------------------------*/
     144
     145int usb_generic_hid_init(usb_hid_dev_t *hid_dev)
     146{
     147        if (hid_dev == NULL) {
     148                return EINVAL;
     149        }
     150       
     151        return usb_generic_hid_create_function(hid_dev);
     152}
     153
     154/*----------------------------------------------------------------------------*/
     155
    57156bool usb_generic_hid_polling_callback(usb_hid_dev_t *hid_dev,
    58157    uint8_t *buffer, size_t buffer_size)
  • uspace/drv/usbhid/generic/hiddev.h

    rb9d7965 racdbd780  
    4646const char *HID_GENERIC_CLASS_NAME;
    4747
     48/*----------------------------------------------------------------------------*/
     49
     50int usb_generic_hid_init(struct usb_hid_dev *hid_dev);
     51
    4852bool usb_generic_hid_polling_callback(struct usb_hid_dev *hid_dev,
    4953    uint8_t *buffer, size_t buffer_size);
  • uspace/drv/usbhid/kbd/kbddev.c

    rb9d7965 racdbd780  
    766766
    767767/*----------------------------------------------------------------------------*/
     768
     769static int usb_kbd_create_function(usb_hid_dev_t *hid_dev)
     770{
     771        assert(hid_dev != NULL);
     772        assert(hid_dev->usb_dev != NULL);
     773       
     774        /* Create the function exposed under /dev/devices. */
     775        usb_log_debug("Creating DDF function %s...\n", HID_KBD_FUN_NAME);
     776        ddf_fun_t *fun = ddf_fun_create(hid_dev->usb_dev->ddf_dev, fun_exposed,
     777            HID_KBD_FUN_NAME);
     778        if (fun == NULL) {
     779                usb_log_error("Could not create DDF function node.\n");
     780                return ENOMEM;
     781        }
     782       
     783        /*
     784         * Store the initialized HID device and HID ops
     785         * to the DDF function.
     786         */
     787        fun->ops = &hid_dev->ops;
     788        fun->driver_data = hid_dev;   // TODO: maybe change to hid_dev->data
     789
     790        int rc = ddf_fun_bind(fun);
     791        if (rc != EOK) {
     792                usb_log_error("Could not bind DDF function: %s.\n",
     793                    str_error(rc));
     794                ddf_fun_destroy(fun);
     795                return rc;
     796        }
     797       
     798        usb_log_debug("Adding DDF function to class %s...\n",
     799            HID_KBD_CLASS_NAME);
     800        rc = ddf_fun_add_to_class(fun, HID_KBD_CLASS_NAME);
     801        if (rc != EOK) {
     802                usb_log_error(
     803                    "Could not add DDF function to class %s: %s.\n",
     804                    HID_KBD_CLASS_NAME, str_error(rc));
     805                ddf_fun_destroy(fun);
     806                return rc;
     807        }
     808       
     809        return EOK;
     810}
     811
     812/*----------------------------------------------------------------------------*/
    768813/* API functions                                                              */
    769814/*----------------------------------------------------------------------------*/
     
    930975        usb_log_debug("HID/KBD device structure initialized.\n");
    931976       
     977        usb_log_debug("Creating KBD function...\n");
     978        int rc = usb_kbd_create_function(hid_dev);
     979        if (rc != EOK) {
     980                usb_kbd_free(&kbd_dev);
     981                return rc;
     982        }
     983       
    932984        return EOK;
    933985}
  • uspace/drv/usbhid/lgtch-ultrax/keymap.c

    rb9d7965 racdbd780  
    5555        [0xc] = KC_F6, /* Just for testing purposes */
    5656       
    57         [0xb5] = 0,  /* Scan Next Track */
    58         [0xb6] = 0,  /* Scan Previous Track */
    59         [0xb7] = 0,  /* Stop */
    60         [0xb8] = 0,  /* Eject */
    61         [0xcd] = KC_F2,  /* Play/Pause */
    62         [0xe2] = KC_F3,  /* Mute */
    63         [0xe9] = KC_F5,  /* Volume Increment */
    64         [0xea] = KC_F4,  /* Volume Decrement */
    65         [0x183] = 0, /* AL Consumer Control Configuration */
    66         [0x18a] = 0, /* AL Email Reader */
    67         [0x192] = 0, /* AL Calculator */
    68         [0x221] = 0, /* AC Search */
    69         [0x223] = 0, /* AC Home */
    70         [0x224] = 0, /* AC Back */
    71         [0x225] = 0, /* AC Forward */
    72         [0x226] = 0, /* AC Stop */
    73         [0x227] = KC_F1, /* AC Refresh */
    74         [0x22a] = KC_F6  /* AC Bookmarks */
     57        [0xb5] = 0,       /* Scan Next Track */
     58        [0xb6] = 0,       /* Scan Previous Track */
     59        [0xb7] = 0,       /* Stop */
     60        [0xb8] = 0,       /* Eject */
     61        [0xcd] = KC_F2,   /* Play/Pause */
     62        [0xe2] = KC_F3,   /* Mute */
     63        [0xe9] = KC_F5,   /* Volume Increment */
     64        [0xea] = KC_F4,   /* Volume Decrement */
     65        [0x183] = 0,      /* AL Consumer Control Configuration */
     66        [0x18a] = 0,      /* AL Email Reader */
     67        [0x192] = 0,      /* AL Calculator */
     68        [0x221] = 0,      /* AC Search */
     69        [0x223] = 0,      /* AC Home */
     70        [0x224] = 0,      /* AC Back */
     71        [0x225] = 0,      /* AC Forward */
     72        [0x226] = 0,      /* AC Stop */
     73        [0x227] = KC_F1,  /* AC Refresh */
     74        [0x22a] = KC_F6   /* AC Bookmarks */
    7575};
    7676
  • uspace/drv/usbhid/lgtch-ultrax/lgtch-ultrax.c

    rb9d7965 racdbd780  
    5858} usb_lgtch_flags;
    5959
     60/*----------------------------------------------------------------------------*/
     61/**
     62 * Logitech UltraX device type.
     63 */
     64typedef struct usb_lgtch_ultrax_t {
     65        /** Previously pressed keys (not translated to key codes). */
     66        int32_t *keys_old;
     67        /** Currently pressed keys (not translated to key codes). */
     68        int32_t *keys;
     69        /** Count of stored keys (i.e. number of keys in the report). */
     70        size_t key_count;
     71       
     72        /** IPC phone to the console device (for sending key events). */
     73        int console_phone;
     74
     75        /** Information for auto-repeat of keys. */
     76//      usb_kbd_repeat_t repeat;
     77       
     78        /** Mutex for accessing the information about auto-repeat. */
     79//      fibril_mutex_t *repeat_mtx;
     80
     81        /** State of the structure (for checking before use).
     82         *
     83         * 0 - not initialized
     84         * 1 - initialized
     85         * -1 - ready for destroying
     86         */
     87        int initialized;
     88} usb_lgtch_ultrax_t;
     89
    6090
    6191/*----------------------------------------------------------------------------*/
     
    208238/*----------------------------------------------------------------------------*/
    209239
    210 int usb_lgtch_init(struct usb_hid_dev *hid_dev)
    211 {
    212         if (hid_dev == NULL || hid_dev->usb_dev == NULL) {
    213                 return EINVAL; /*! @todo Other return code? */
    214         }
    215        
    216         usb_log_debug(NAME " Initializing HID/lgtch_ultrax structure...\n");
    217        
    218         usb_lgtch_ultrax_t *lgtch_dev = (usb_lgtch_ultrax_t *)malloc(
    219             sizeof(usb_lgtch_ultrax_t));
    220         if (lgtch_dev == NULL) {
    221                 return ENOMEM;
    222         }
    223        
    224         lgtch_dev->console_phone = -1;
    225        
    226         usb_hid_report_path_t *path = usb_hid_report_path();
    227         usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_CONSUMER, 0);
    228        
    229         usb_hid_report_path_set_report_id(path, 1);
    230        
    231         lgtch_dev->key_count = usb_hid_report_input_length(
    232             hid_dev->report, path,
    233             USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY);
    234         usb_hid_report_path_free(path);
    235        
    236         usb_log_debug(NAME " Size of the input report: %zu\n",
    237             lgtch_dev->key_count);
    238        
    239         lgtch_dev->keys = (int32_t *)calloc(lgtch_dev->key_count,
    240             sizeof(int32_t));
    241        
    242         if (lgtch_dev->keys == NULL) {
    243                 usb_log_fatal("No memory!\n");
    244                 free(lgtch_dev);
    245                 return ENOMEM;
    246         }
    247        
    248         lgtch_dev->keys_old =
    249                 (int32_t *)calloc(lgtch_dev->key_count, sizeof(int32_t));
    250        
    251         if (lgtch_dev->keys_old == NULL) {
    252                 usb_log_fatal("No memory!\n");
    253                 free(lgtch_dev->keys);
    254                 free(lgtch_dev);
    255                 return ENOMEM;
    256         }
    257        
    258         /*! @todo Autorepeat */
    259        
    260         // save the KBD device structure into the HID device structure
    261         hid_dev->data = lgtch_dev;
    262        
     240static int usb_lgtch_create_function(usb_hid_dev_t *hid_dev)
     241{
    263242        /* Create the function exposed under /dev/devices. */
    264243        ddf_fun_t *fun = ddf_fun_create(hid_dev->usb_dev->ddf_dev, fun_exposed,
     
    269248        }
    270249       
    271         lgtch_dev->initialized = USB_LGTCH_STATUS_INITIALIZED;
    272         usb_log_debug(NAME " HID/lgtch_ultrax device structure initialized.\n");
    273        
    274250        /*
    275251         * Store the initialized HID device and HID ops
     
    279255        fun->driver_data = hid_dev;   // TODO: maybe change to hid_dev->data
    280256       
    281         /*
    282          * 1) subdriver vytvori vlastnu ddf_fun, vlastne ddf_dev_ops, ktore da
    283          *    do nej.
    284          * 2) do tych ops do .interfaces[DEV_IFACE_USBHID (asi)] priradi
    285          *    vyplnenu strukturu usbhid_iface_t.
    286          * 3) klientska aplikacia - musi si rucne vytvorit telefon
    287          *    (devman_device_connect() - cesta k zariadeniu (/hw/pci0/...) az
    288          *    k tej fcii.
    289          *    pouzit usb/classes/hid/iface.h - prvy int je telefon
    290          */
    291 
    292257        int rc = ddf_fun_bind(fun);
    293258        if (rc != EOK) {
     
    296261                // TODO: Can / should I destroy the DDF function?
    297262                ddf_fun_destroy(fun);
    298                 usb_lgtch_free(&lgtch_dev);
    299263                return rc;
    300264        }
     
    307271                // TODO: Can / should I destroy the DDF function?
    308272                ddf_fun_destroy(fun);
     273                return rc;
     274        }
     275       
     276        return EOK;
     277}
     278
     279/*----------------------------------------------------------------------------*/
     280
     281int usb_lgtch_init(struct usb_hid_dev *hid_dev)
     282{
     283        if (hid_dev == NULL || hid_dev->usb_dev == NULL) {
     284                return EINVAL; /*! @todo Other return code? */
     285        }
     286       
     287        usb_log_debug(NAME " Initializing HID/lgtch_ultrax structure...\n");
     288       
     289        usb_lgtch_ultrax_t *lgtch_dev = (usb_lgtch_ultrax_t *)malloc(
     290            sizeof(usb_lgtch_ultrax_t));
     291        if (lgtch_dev == NULL) {
     292                return ENOMEM;
     293        }
     294       
     295        lgtch_dev->console_phone = -1;
     296       
     297        usb_hid_report_path_t *path = usb_hid_report_path();
     298        usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_CONSUMER, 0);
     299       
     300        usb_hid_report_path_set_report_id(path, 1);
     301       
     302        lgtch_dev->key_count = usb_hid_report_input_length(
     303            hid_dev->report, path,
     304            USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY);
     305        usb_hid_report_path_free(path);
     306       
     307        usb_log_debug(NAME " Size of the input report: %zu\n",
     308            lgtch_dev->key_count);
     309       
     310        lgtch_dev->keys = (int32_t *)calloc(lgtch_dev->key_count,
     311            sizeof(int32_t));
     312       
     313        if (lgtch_dev->keys == NULL) {
     314                usb_log_fatal("No memory!\n");
     315                free(lgtch_dev);
     316                return ENOMEM;
     317        }
     318       
     319        lgtch_dev->keys_old =
     320                (int32_t *)calloc(lgtch_dev->key_count, sizeof(int32_t));
     321       
     322        if (lgtch_dev->keys_old == NULL) {
     323                usb_log_fatal("No memory!\n");
     324                free(lgtch_dev->keys);
     325                free(lgtch_dev);
     326                return ENOMEM;
     327        }
     328       
     329        /*! @todo Autorepeat */
     330       
     331        // save the KBD device structure into the HID device structure
     332        hid_dev->data = lgtch_dev;
     333       
     334        lgtch_dev->initialized = USB_LGTCH_STATUS_INITIALIZED;
     335        usb_log_debug(NAME " HID/lgtch_ultrax device structure initialized.\n");
     336       
     337        int rc = usb_lgtch_create_function(hid_dev);
     338        if (rc != EOK) {
    309339                usb_lgtch_free(&lgtch_dev);
    310340                return rc;
     
    356386        int rc = usb_hid_parse_report(hid_dev->report, buffer, buffer_size,
    357387            &report_id);
     388       
     389        if (rc != EOK) {
     390                usb_log_warning(NAME "Error in usb_hid_parse_report(): %s\n",
     391                    str_error(rc));
     392                return true;
     393        }
     394       
    358395        usb_hid_report_path_set_report_id(path, report_id);
    359396
     
    383420        usb_hid_report_path_free(path);
    384421       
    385         if (rc != EOK) {
    386                 usb_log_warning(NAME "Error in usb_hid_boot_keyboard_input_report():"
    387                     "%s\n", str_error(rc));
    388         }
    389        
    390422        return true;
    391423}
  • uspace/drv/usbhid/lgtch-ultrax/lgtch-ultrax.h

    rb9d7965 racdbd780  
    4242
    4343/*----------------------------------------------------------------------------*/
    44 /**
    45  * USB/HID keyboard device type.
    46  *
    47  * Holds a reference to generic USB/HID device structure and keyboard-specific
    48  * data, such as currently pressed keys, modifiers and lock keys.
    49  *
    50  * Also holds a IPC phone to the console (since there is now no other way to
    51  * communicate with it).
    52  *
    53  * @note Storing active lock keys in this structure results in their setting
    54  *       being device-specific.
    55  */
    56 typedef struct usb_lgtch_ultrax_t {
    57         /** Previously pressed keys (not translated to key codes). */
    58         int32_t *keys_old;
    59         /** Currently pressed keys (not translated to key codes). */
    60         int32_t *keys;
    61         /** Count of stored keys (i.e. number of keys in the report). */
    62         size_t key_count;
    63        
    64         /** IPC phone to the console device (for sending key events). */
    65         int console_phone;
    66 
    67         /** Information for auto-repeat of keys. */
    68 //      usb_kbd_repeat_t repeat;
    69        
    70         /** Mutex for accessing the information about auto-repeat. */
    71 //      fibril_mutex_t *repeat_mtx;
    72 
    73         /** State of the structure (for checking before use).
    74          *
    75          * 0 - not initialized
    76          * 1 - initialized
    77          * -1 - ready for destroying
    78          */
    79         int initialized;
    80 } usb_lgtch_ultrax_t;
    81 
    82 /*----------------------------------------------------------------------------*/
    8344
    8445int usb_lgtch_init(struct usb_hid_dev *hid_dev);
  • uspace/drv/usbhid/main.c

    rb9d7965 racdbd780  
    9999        usb_log_debug("USB/HID device structure initialized.\n");
    100100       
    101         /* Create the function exposed under /dev/devices. */
    102         ddf_fun_t *hid_fun = ddf_fun_create(dev->ddf_dev, fun_exposed,
    103             usb_hid_get_function_name(hid_dev));
    104         if (hid_fun == NULL) {
    105                 usb_log_error("Could not create DDF function node.\n");
    106                 usb_hid_free(&hid_dev);
    107                 return ENOMEM;
    108         }
    109        
    110         /*
    111          * Store the initialized HID device and HID ops
    112          * to the DDF function.
    113          */
    114         hid_fun->ops = &hid_dev->ops;
    115         hid_fun->driver_data = hid_dev;   // TODO: maybe change to hid_dev->data
    116        
    117101        /*
    118102         * 1) subdriver vytvori vlastnu ddf_fun, vlastne ddf_dev_ops, ktore da
     
    125109         *    pouzit usb/classes/hid/iface.h - prvy int je telefon
    126110         */
    127 
    128         rc = ddf_fun_bind(hid_fun);
    129         if (rc != EOK) {
    130                 usb_log_error("Could not bind DDF function: %s.\n",
    131                     str_error(rc));
    132                 // TODO: Can / should I destroy the DDF function?
    133                 ddf_fun_destroy(hid_fun);
    134                 usb_hid_free(&hid_dev);
    135                 return rc;
    136         }
    137        
    138         rc = ddf_fun_add_to_class(hid_fun, usb_hid_get_class_name(hid_dev));
    139         if (rc != EOK) {
    140                 usb_log_error(
    141                     "Could not add DDF function to class 'hid': %s.\n",
    142                     str_error(rc));
    143                 // TODO: Can / should I destroy the DDF function?
    144                 ddf_fun_destroy(hid_fun);
    145                 usb_hid_free(&hid_dev);
    146                 return rc;
    147         }
    148111       
    149112        /* Start automated polling function.
  • uspace/drv/usbhid/mouse/mousedev.c

    rb9d7965 racdbd780  
    3939#include <usb/classes/hid.h>
    4040#include <usb/classes/hidreq.h>
     41#include <usb/classes/hidut.h>
    4142#include <errno.h>
    4243#include <str_error.h>
     
    4546#include "mousedev.h"
    4647#include "../usbhid.h"
     48
     49#define NAME "mouse"
    4750
    4851/*----------------------------------------------------------------------------*/
     
    6265/** Default idle rate for mouses. */
    6366static const uint8_t IDLE_RATE = 0;
     67static const size_t USB_MOUSE_BUTTON_COUNT = 3;
    6468
    6569/*----------------------------------------------------------------------------*/
     
    170174/*----------------------------------------------------------------------------*/
    171175
    172 static bool usb_mouse_process_boot_report(usb_mouse_t *mouse_dev,
     176static bool usb_mouse_process_boot_report(usb_hid_dev_t *hid_dev,
    173177    uint8_t *buffer, size_t buffer_size)
    174178{
     179        usb_mouse_t *mouse_dev = (usb_mouse_t *)hid_dev->data;
     180       
    175181        usb_log_debug2("got buffer: %s.\n",
    176182            usb_debug_str_buffer(buffer, buffer_size, 0));
    177 
    178         uint8_t butt = buffer[0];
    179         char str_buttons[4] = {
    180                 butt & 1 ? '#' : '.',
    181                 butt & 2 ? '#' : '.',
    182                 butt & 4 ? '#' : '.',
    183                 0
    184         };
    185 
    186         int shift_x = ((int) buffer[1]) - 127;
    187         int shift_y = ((int) buffer[2]) - 127;
    188         int wheel = ((int) buffer[3]) - 127;
    189 
    190         if (buffer[1] == 0) {
    191                 shift_x = 0;
    192         }
    193         if (buffer[2] == 0) {
    194                 shift_y = 0;
    195         }
    196         if (buffer[3] == 0) {
    197                 wheel = 0;
    198         }
    199        
    200         if (mouse_dev->console_phone >= 0) {
    201                 usb_log_debug("Console phone: %d\n", mouse_dev->console_phone);
    202                 if ((shift_x != 0) || (shift_y != 0)) {
    203                         /* FIXME: guessed for QEMU */
     183       
     184        if (mouse_dev->console_phone < 0) {
     185                usb_log_error(NAME " No console phone.\n");
     186                return false;   // ??
     187        }
     188
     189        /*
     190         * parse the input report
     191         */
     192       
     193        usb_log_debug(NAME " Calling usb_hid_parse_report() with "
     194            "buffer %s\n", usb_debug_str_buffer(buffer, buffer_size, 0));
     195       
     196        uint8_t report_id;
     197       
     198        int rc = usb_hid_parse_report(hid_dev->report, buffer, buffer_size,
     199            &report_id);
     200       
     201        if (rc != EOK) {
     202                usb_log_warning(NAME "Error in usb_hid_parse_report(): %s\n",
     203                    str_error(rc));
     204                return true;
     205        }
     206       
     207        /*
     208         * X
     209         */
     210        int shift_x = 0;
     211       
     212        usb_hid_report_path_t *path = usb_hid_report_path();
     213        usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_GENERIC_DESKTOP,
     214            USB_HIDUT_USAGE_GENERIC_DESKTOP_X);
     215
     216        usb_hid_report_path_set_report_id(path, report_id);
     217
     218        usb_hid_report_field_t *field = usb_hid_report_get_sibling(
     219            hid_dev->report, NULL, path, USB_HID_PATH_COMPARE_END,
     220            USB_HID_REPORT_TYPE_INPUT);
     221
     222        if (field != NULL) {
     223                usb_log_debug(NAME " VALUE(%X) USAGE(%X)\n", field->value,
     224                    field->usage);
     225                shift_x = field->value;
     226        }
     227
     228        usb_hid_report_path_free(path);
     229       
     230        /*
     231         * Y
     232         */
     233        int shift_y = 0;
     234       
     235        path = usb_hid_report_path();
     236        usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_GENERIC_DESKTOP,
     237            USB_HIDUT_USAGE_GENERIC_DESKTOP_Y);
     238
     239        usb_hid_report_path_set_report_id(path, report_id);
     240
     241        field = usb_hid_report_get_sibling(
     242            hid_dev->report, NULL, path, USB_HID_PATH_COMPARE_END,
     243            USB_HID_REPORT_TYPE_INPUT);
     244
     245        if (field != NULL) {
     246                usb_log_debug(NAME " VALUE(%X) USAGE(%X)\n", field->value,
     247                    field->usage);
     248                shift_y = field->value;
     249        }
     250
     251        usb_hid_report_path_free(path);
     252       
     253        if ((shift_x != 0) || (shift_y != 0)) {
     254                async_req_2_0(mouse_dev->console_phone,
     255                    MEVENT_MOVE, shift_x, shift_y);
     256        }
     257       
     258        /*
     259         * Buttons
     260         */
     261        path = usb_hid_report_path();
     262        usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_BUTTON, 0);
     263        usb_hid_report_path_set_report_id(path, report_id);
     264       
     265        field = usb_hid_report_get_sibling(
     266            hid_dev->report, NULL, path, USB_HID_PATH_COMPARE_END
     267            | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY,
     268            USB_HID_REPORT_TYPE_INPUT);
     269
     270        if (field != NULL) {
     271                usb_log_debug(NAME " VALUE(%X) USAGE(%X)\n", field->value,
     272                    field->usage);
     273               
     274                if (mouse_dev->buttons[field->usage - field->usage_minimum] == 0
     275                    && field->value != 0) {
    204276                        async_req_2_0(mouse_dev->console_phone,
    205                             MEVENT_MOVE,
    206                             - shift_x / 10,  - shift_y / 10);
    207                 } else {
    208                         usb_log_error("No move reported\n");
    209                 }
    210                 if (butt) {
    211                         /* FIXME: proper button clicking. */
    212                         async_req_2_0(mouse_dev->console_phone,
    213                             MEVENT_BUTTON, 1, 1);
    214                         async_req_2_0(mouse_dev->console_phone,
    215                             MEVENT_BUTTON, 1, 0);
    216                 }
    217         } else {
    218                 usb_log_error("No console phone in mouse!!\n");
    219         }
    220 
    221         usb_log_debug("buttons=%s  dX=%+3d  dY=%+3d  wheel=%+3d\n",
    222             str_buttons, shift_x, shift_y, wheel);
    223 
    224         /* Guess. */
    225         //async_usleep(1000);
    226         // no sleep right now
     277                            MEVENT_BUTTON, field->usage, 1);
     278                        mouse_dev->buttons[field->usage - field->usage_minimum]
     279                            = field->value;
     280                } else if (
     281                    mouse_dev->buttons[field->usage - field->usage_minimum] != 0
     282                    && field->value == 0) {
     283                       async_req_2_0(mouse_dev->console_phone,
     284                           MEVENT_BUTTON, field->usage, 0);
     285                       mouse_dev->buttons[field->usage - field->usage_minimum]
     286                           = field->value;
     287               }
     288               
     289                field = usb_hid_report_get_sibling(
     290                    hid_dev->report, field, path, USB_HID_PATH_COMPARE_END
     291                    | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY,
     292                    USB_HID_REPORT_TYPE_INPUT);
     293        }
     294       
     295        usb_hid_report_path_free(path);
    227296
    228297        return true;
     298}
     299
     300/*----------------------------------------------------------------------------*/
     301
     302static int usb_mouse_create_function(usb_hid_dev_t *hid_dev)
     303{
     304        /* Create the function exposed under /dev/devices. */
     305        usb_log_debug("Creating DDF function %s...\n", HID_MOUSE_FUN_NAME);
     306        ddf_fun_t *fun = ddf_fun_create(hid_dev->usb_dev->ddf_dev, fun_exposed,
     307            HID_MOUSE_FUN_NAME);
     308        if (fun == NULL) {
     309                usb_log_error("Could not create DDF function node.\n");
     310                return ENOMEM;
     311        }
     312       
     313        /*
     314         * Store the initialized HID device and HID ops
     315         * to the DDF function.
     316         */
     317        fun->ops = &hid_dev->ops;
     318        fun->driver_data = hid_dev;   // TODO: maybe change to hid_dev->data
     319
     320        int rc = ddf_fun_bind(fun);
     321        if (rc != EOK) {
     322                usb_log_error("Could not bind DDF function: %s.\n",
     323                    str_error(rc));
     324                ddf_fun_destroy(fun);
     325                return rc;
     326        }
     327       
     328        usb_log_debug("Adding DDF function to class %s...\n",
     329            HID_MOUSE_CLASS_NAME);
     330        rc = ddf_fun_add_to_class(fun, HID_MOUSE_CLASS_NAME);
     331        if (rc != EOK) {
     332                usb_log_error(
     333                    "Could not add DDF function to class %s: %s.\n",
     334                    HID_MOUSE_CLASS_NAME, str_error(rc));
     335                ddf_fun_destroy(fun);
     336                return rc;
     337        }
     338       
     339        return EOK;
    229340}
    230341
     
    248359        }
    249360       
     361        mouse_dev->buttons = (int32_t *)calloc(USB_MOUSE_BUTTON_COUNT,
     362            sizeof(int32_t));
     363       
     364        if (mouse_dev->buttons == NULL) {
     365                usb_log_fatal("No memory!\n");
     366                free(mouse_dev);
     367                return ENOMEM;
     368        }
     369       
    250370        // save the Mouse device structure into the HID device structure
    251371        hid_dev->data = mouse_dev;
     
    255375       
    256376        // TODO: how to know if the device supports the request???
    257         usbhid_req_set_idle(&hid_dev->usb_dev->ctrl_pipe,
    258             hid_dev->usb_dev->interface_no, IDLE_RATE);
     377//      usbhid_req_set_idle(&hid_dev->usb_dev->ctrl_pipe,
     378//          hid_dev->usb_dev->interface_no, IDLE_RATE);
     379       
     380        int rc = usb_mouse_create_function(hid_dev);
     381        if (rc != EOK) {
     382                usb_mouse_free(&mouse_dev);
     383                return rc;
     384        }
    259385       
    260386        return EOK;
     
    280406                return false;
    281407        }
    282         usb_mouse_t *mouse_dev = (usb_mouse_t *)hid_dev->data;
    283        
    284         return usb_mouse_process_boot_report(mouse_dev, buffer, buffer_size);
     408       
     409        return usb_mouse_process_boot_report(hid_dev, buffer, buffer_size);
    285410}
    286411
  • uspace/drv/usbhid/mouse/mousedev.h

    rb9d7965 racdbd780  
    4949        /** IPC phone to console (consumer). */
    5050        int console_phone;
     51       
     52        int32_t *buttons;
    5153} usb_mouse_t;
    5254
  • uspace/drv/usbhid/usbhid.c

    rb9d7965 racdbd780  
    136136       
    137137        // set the init callback
    138         hid_dev->subdrivers[0].init = NULL;
     138        hid_dev->subdrivers[0].init = usb_generic_hid_init;
    139139       
    140140        // set the polling callback
     
    490490        usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)arg;
    491491       
     492        int allocated = (hid_dev->input_report != NULL);
     493       
     494        if (!allocated
     495            || hid_dev->input_report_size < buffer_size) {
     496                uint8_t *input_old = hid_dev->input_report;
     497                uint8_t *input_new = (uint8_t *)malloc(buffer_size);
     498               
     499                if (input_new == NULL) {
     500                        usb_log_error("Failed to allocate space for input "
     501                            "buffer. This event may not be reported\n");
     502                        memset(hid_dev->input_report, 0,
     503                            hid_dev->input_report_size);
     504                } else {
     505                        memcpy(input_new, input_old,
     506                            hid_dev->input_report_size);
     507                        hid_dev->input_report = input_new;
     508                        if (allocated) {
     509                                free(input_old);
     510                        }
     511                }
     512        }
     513       
     514        /*! @todo This should probably be atomic. */
     515        memcpy(hid_dev->input_report, buffer, buffer_size);
     516        hid_dev->input_report_size = buffer_size;
     517       
    492518        bool cont = false;
    493519       
     
    528554/*----------------------------------------------------------------------------*/
    529555
    530 const char *usb_hid_get_function_name(const usb_hid_dev_t *hid_dev)
    531 {
    532         switch (hid_dev->poll_pipe_index) {
    533         case USB_HID_KBD_POLL_EP_NO:
    534                 return HID_KBD_FUN_NAME;
    535                 break;
    536         case USB_HID_MOUSE_POLL_EP_NO:
    537                 return HID_MOUSE_FUN_NAME;
    538                 break;
    539         default:
    540                 return HID_GENERIC_FUN_NAME;
    541         }
    542 }
    543 
    544 /*----------------------------------------------------------------------------*/
    545 
    546 const char *usb_hid_get_class_name(const usb_hid_dev_t *hid_dev)
    547 {
    548         // this means that only boot protocol keyboards will be connected
    549         // to the console; there is probably no better way to do this
    550        
    551         switch (hid_dev->poll_pipe_index) {
    552         case USB_HID_KBD_POLL_EP_NO:
    553                 return HID_KBD_CLASS_NAME;
    554                 break;
    555         case USB_HID_MOUSE_POLL_EP_NO:
    556                 return HID_MOUSE_CLASS_NAME;
    557                 break;
    558         default:
    559                 return HID_GENERIC_CLASS_NAME;
    560         }
    561 }
     556//const char *usb_hid_get_function_name(const usb_hid_dev_t *hid_dev)
     557//{
     558//      switch (hid_dev->poll_pipe_index) {
     559//      case USB_HID_KBD_POLL_EP_NO:
     560//              return HID_KBD_FUN_NAME;
     561//              break;
     562//      case USB_HID_MOUSE_POLL_EP_NO:
     563//              return HID_MOUSE_FUN_NAME;
     564//              break;
     565//      default:
     566//              return HID_GENERIC_FUN_NAME;
     567//      }
     568//}
     569
     570/*----------------------------------------------------------------------------*/
     571
     572//const char *usb_hid_get_class_name(const usb_hid_dev_t *hid_dev)
     573//{
     574//      // this means that only boot protocol keyboards will be connected
     575//      // to the console; there is probably no better way to do this
     576       
     577//      switch (hid_dev->poll_pipe_index) {
     578//      case USB_HID_KBD_POLL_EP_NO:
     579//              return HID_KBD_CLASS_NAME;
     580//              break;
     581//      case USB_HID_MOUSE_POLL_EP_NO:
     582//              return HID_MOUSE_CLASS_NAME;
     583//              break;
     584//      default:
     585//              return HID_GENERIC_CLASS_NAME;
     586//      }
     587//}
    562588
    563589/*----------------------------------------------------------------------------*/
  • uspace/drv/usbhid/usbhid.h

    rb9d7965 racdbd780  
    9393        usb_hid_report_t *report;
    9494       
     95        uint8_t *input_report;
     96       
     97        size_t input_report_size;
     98       
    9599        /** Arbitrary data (e.g. a special structure for handling keyboard). */
    96100        void *data;
     
    120124     void *arg);
    121125
    122 const char *usb_hid_get_function_name(const usb_hid_dev_t *hid_dev);
     126//const char *usb_hid_get_function_name(const usb_hid_dev_t *hid_dev);
    123127
    124 const char *usb_hid_get_class_name(const usb_hid_dev_t *hid_dev);
     128//const char *usb_hid_get_class_name(const usb_hid_dev_t *hid_dev);
    125129
    126130void usb_hid_free(usb_hid_dev_t **hid_dev);
  • uspace/drv/usbhub/usbhub.c

    rb9d7965 racdbd780  
    411411static int usb_process_hub_power_change(usb_hub_info_t * hub_info,
    412412    usb_hub_status_t status) {
    413         int opResult;
     413        int opResult = EOK;
    414414        if (!usb_hub_is_status(status,USB_HUB_FEATURE_HUB_LOCAL_POWER)) {
    415415                //restart power on hub
     
    431431                        }
    432432                }
    433                 opResult = usb_hub_clear_feature(hub_info->control_pipe,
    434                     USB_HUB_FEATURE_C_HUB_LOCAL_POWER);
     433        }
     434        if(opResult!=EOK){
     435                return opResult;//no feature clearing
     436        }
     437        opResult = usb_hub_clear_feature(hub_info->control_pipe,
     438            USB_HUB_FEATURE_C_HUB_LOCAL_POWER);
    435439                if (opResult != EOK) {
    436                         usb_log_error("cannnot clear hub power change flag: "
    437                             "%d\n",
    438                             opResult);
    439                 }
     440                usb_log_error("cannnot clear hub power change flag: "
     441                    "%d\n",
     442                    opResult);
    440443        }
    441444        return opResult;
  • uspace/lib/drv/include/usbhid_iface.h

    rb9d7965 racdbd780  
    7272/** USB HID device communication interface. */
    7373typedef struct {
    74         /** Get number of items in the event.
     74        /** Get size of the event in bytes.
    7575         *
    7676         * @param[in] fun DDF function answering the request.
    7777         * @return Number of events or error code.
    7878         */
    79         int (*get_event_length)(ddf_fun_t *fun);
     79        size_t (*get_event_length)(ddf_fun_t *fun);
    8080
    8181        /** Get single event from the HID device.
    8282         *
    8383         * @param[in] fun DDF function answering the request.
    84          * @param[out] usage_page Array of usage pages and usages.
    85          * @param[out] usage Array of data (1:1 with @p usage).
    86          * @param[in] size Size of @p usage and @p data arrays.
     84         * @param[out] buffer Buffer with raw data from the device.
    8785         * @param[out] act_size Actual number of returned events.
    8886         * @param[in] flags Flags (see USBHID_IFACE_FLAG_*).
    8987         * @return Error code.
    9088         */
    91         int (*get_event)(ddf_fun_t *fun,
    92             uint16_t *usage_page, uint16_t *usage, size_t size, size_t *act_size,
    93             unsigned int flags);
     89        int (*get_event)(ddf_fun_t *fun, int32_t *buffer, size_t size,
     90            size_t *act_size, unsigned int flags);
    9491} usbhid_iface_t;
    9592
  • uspace/lib/usb/include/usb/classes/hidut.h

    rb9d7965 racdbd780  
    5959        USB_HIDUT_USAGE_GENERIC_DESKTOP_GAMEPAD = 5,
    6060        USB_HIDUT_USAGE_GENERIC_DESKTOP_KEYBOARD = 6,
    61         USB_HIDUT_USAGE_GENERIC_DESKTOP_KEYPAD = 7
     61        USB_HIDUT_USAGE_GENERIC_DESKTOP_KEYPAD = 7,
     62        USB_HIDUT_USAGE_GENERIC_DESKTOP_X = 0x30,
     63        USB_HIDUT_USAGE_GENERIC_DESKTOP_Y = 0x31,
     64        USB_HIDUT_USAGE_GENERIC_DESKTOP_WHEEL = 0x38
    6265        /* USB_HIDUT_USAGE_GENERIC_DESKTOP_ = , */
    6366       
  • uspace/lib/usb/src/hiddescriptor.c

    rb9d7965 racdbd780  
    640640
    641641                usb_log_debug("\t\tOFFSET: %X\n", report_item->offset);
    642                 usb_log_debug("\t\tSIZE: %X\n", report_item->size);                             
     642                usb_log_debug("\t\tSIZE: %zu\n", report_item->size);
    643643                usb_log_debug("\t\tLOGMIN: %d\n", report_item->logical_minimum);
    644644                usb_log_debug("\t\tLOGMAX: %d\n", report_item->logical_maximum);               
     
    679679                usb_log_debug("Report ID: %d\n", report_des->report_id);
    680680                usb_log_debug("\tType: %d\n", report_des->type);
    681                 usb_log_debug("\tLength: %d\n", report_des->bit_length);               
    682                 usb_log_debug("\tItems: %d\n", report_des->item_length);               
     681                usb_log_debug("\tLength: %zu\n", report_des->bit_length);
     682                usb_log_debug("\tItems: %zu\n", report_des->item_length);
    683683
    684684                usb_hid_descriptor_print_list(&report_des->report_items);
Note: See TracChangeset for help on using the changeset viewer.