Changes in / [6bfaab5:88be3a0b] in mainline


Ignore:
Files:
23 added
11 deleted
75 edited

Legend:

Unmodified
Added
Removed
  • .bzrignore

    r6bfaab5 r88be3a0b  
    77*.map
    88*.disasm
    9 *.lo
    10 *.la
    11 *.so.*
    12 *.so0
    139_link.ld
    1410./*.iso
     
    5753./uspace/app/klog/klog
    5854./uspace/app/lsusb/lsusb
    59 ./uspace/app/mkbd/mkbd
    6055./uspace/app/mkfat/mkfat
    6156./uspace/app/netstart/netstart
  • boot/Makefile.common

    r6bfaab5 r88be3a0b  
    157157        $(USPACE_PATH)/app/usbinfo/usbinfo \
    158158        $(USPACE_PATH)/app/vuhid/vuh \
    159         $(USPACE_PATH)/app/mkbd/mkbd \
    160159        $(USPACE_PATH)/app/websrv/websrv
    161160
  • boot/arch/amd64/Makefile.inc

    r6bfaab5 r88be3a0b  
    4949        usbflbk \
    5050        usbhub \
     51        usbkbd \
    5152        usbhid \
    5253        usbmast \
  • kernel/generic/src/ipc/irq.c

    r6bfaab5 r88be3a0b  
    370370        if (AS != irq->driver_as) \
    371371                as_switch(AS, irq->driver_as); \
     372        printf("Copying data from address: %p.\n", va); \
    372373        memcpy_from_uspace(&target, va, (sizeof(target))); \
    373374        if (dstarg) \
     
    380381        if (AS != irq->driver_as) \
    381382                as_switch(AS, irq->driver_as); \
     383        printf("Writing data to address: %p.\n", va); \
    382384        memcpy_to_uspace(va, &val, sizeof(val)); \
    383385} while (0)
     
    455457                        uint32_t val;
    456458                        CMD_MEM_READ(val);
     459                        printf("mem READ value: %x.\n", val);
    457460                        break;
    458461                        }
  • uspace/Makefile

    r6bfaab5 r88be3a0b  
    5959        app/websrv \
    6060        app/sysinfo \
    61         app/mkbd \
    6261        srv/clip \
    6362        srv/devmap \
     
    123122                drv/uhci-rhd \
    124123                drv/usbflbk \
     124                drv/usbkbd \
    125125                drv/usbhid \
    126126                drv/usbhub \
     
    144144                drv/uhci-rhd \
    145145                drv/usbflbk \
     146                drv/usbkbd \
    146147                drv/usbhid \
    147148                drv/usbhub \
  • uspace/Makefile.common

    r6bfaab5 r88be3a0b  
    131131        endif
    132132endif
    133 # Build static whenever we use libusb because that library uses
    134 # thread local variables
    135 ifneq ($(findstring usb, $(LIBS)),)
    136         STATIC_BUILD = y
    137 endif
    138133
    139134ifeq ($(STATIC_BUILD), y)
  • uspace/app/lsusb/main.c

    r6bfaab5 r88be3a0b  
    4545#include <devmap.h>
    4646#include <usb/dev/hub.h>
    47 #include <usb/hc.h>
     47#include <usb/host.h>
    4848
    4949#define NAME "lsusb"
  • uspace/app/usbinfo/main.c

    r6bfaab5 r88be3a0b  
    4343#include <devman.h>
    4444#include <devmap.h>
    45 #include <usb/hc.h>
     45#include <usb/dev/hc.h>
    4646#include <usb/dev/pipes.h>
     47#include <usb/host.h>
     48#include <usb/driver.h>
    4749#include "usbinfo.h"
     50
     51static bool try_parse_class_and_address(const char *path,
     52    devman_handle_t *out_hc_handle, usb_address_t *out_device_address)
     53{
     54        size_t class_index;
     55        size_t address;
     56        int rc;
     57        char *ptr;
     58
     59        rc = str_size_t(path, &ptr, 10, false, &class_index);
     60        if (rc != EOK) {
     61                return false;
     62        }
     63        if ((*ptr == ':') || (*ptr == '.')) {
     64                ptr++;
     65        } else {
     66                return false;
     67        }
     68        rc = str_size_t(ptr, NULL, 10, true, &address);
     69        if (rc != EOK) {
     70                return false;
     71        }
     72        rc = usb_ddf_get_hc_handle_by_class(class_index, out_hc_handle);
     73        if (rc != EOK) {
     74                return false;
     75        }
     76        if (out_device_address != NULL) {
     77                *out_device_address = (usb_address_t) address;
     78        }
     79        return true;
     80}
     81
     82static bool resolve_hc_handle_and_dev_addr(const char *devpath,
     83    devman_handle_t *out_hc_handle, usb_address_t *out_device_address)
     84{
     85        int rc;
     86
     87        /* Hack for QEMU to save-up on typing ;-). */
     88        if (str_cmp(devpath, "qemu") == 0) {
     89                devpath = "/hw/pci0/00:01.2/uhci-rh/usb00_a1";
     90        }
     91
     92        /* Hack for virtual keyboard. */
     93        if (str_cmp(devpath, "virt") == 0) {
     94                devpath = "/virt/usbhc/usb00_a1/usb00_a2";
     95        }
     96
     97        if (try_parse_class_and_address(devpath,
     98            out_hc_handle, out_device_address)) {
     99                return true;
     100        }
     101
     102        char *path = str_dup(devpath);
     103        if (path == NULL) {
     104                return ENOMEM;
     105        }
     106
     107        devman_handle_t hc = 0;
     108        bool hc_found = false;
     109        usb_address_t addr = 0;
     110        bool addr_found = false;
     111
     112        /* Remove suffixes and hope that we will encounter device node. */
     113        while (str_length(path) > 0) {
     114                /* Get device handle first. */
     115                devman_handle_t dev_handle;
     116                rc = devman_device_get_handle(path, &dev_handle, 0);
     117                if (rc != EOK) {
     118                        free(path);
     119                        return false;
     120                }
     121
     122                /* Try to find its host controller. */
     123                if (!hc_found) {
     124                        rc = usb_hc_find(dev_handle, &hc);
     125                        if (rc == EOK) {
     126                                hc_found = true;
     127                        }
     128                }
     129                /* Try to get its address. */
     130                if (!addr_found) {
     131                        addr = usb_device_get_assigned_address(dev_handle);
     132                        if (addr >= 0) {
     133                                addr_found = true;
     134                        }
     135                }
     136
     137                /* Speed-up. */
     138                if (hc_found && addr_found) {
     139                        break;
     140                }
     141
     142                /* Remove the last suffix. */
     143                char *slash_pos = str_rchr(path, '/');
     144                if (slash_pos != NULL) {
     145                        *slash_pos = 0;
     146                }
     147        }
     148
     149        free(path);
     150
     151        if (hc_found && addr_found) {
     152                if (out_hc_handle != NULL) {
     153                        *out_hc_handle = hc;
     154                }
     155                if (out_device_address != NULL) {
     156                        *out_device_address = addr;
     157                }
     158                return true;
     159        } else {
     160                return false;
     161        }
     162}
    48163
    49164static void print_usage(char *app_name)
     
    185300                devman_handle_t hc_handle = 0;
    186301                usb_address_t dev_addr = 0;
    187                 int rc = usb_resolve_device_handle(devpath,
    188                     &hc_handle, &dev_addr, NULL);
    189                 if (rc != EOK) {
     302                bool found = resolve_hc_handle_and_dev_addr(devpath,
     303                    &hc_handle, &dev_addr);
     304                if (!found) {
    190305                        fprintf(stderr, NAME ": device `%s' not found "
    191306                            "or not of USB kind, skipping.\n",
  • uspace/drv/ohci/batch.c

    r6bfaab5 r88be3a0b  
    4444#include "hw_struct/transfer_descriptor.h"
    4545
    46 /** OHCI specific data required for USB transfer */
    4746typedef struct ohci_transfer_batch {
    48         /** Endpoint descriptor of the target endpoint. */
    4947        ed_t *ed;
    50         /** List of TDs needed for the transfer */
    5148        td_t **tds;
    52         /** Number of TDs used by the transfer */
    5349        size_t td_count;
    54         /** Dummy TD to be left at the ED and used by the next transfer */
    5550        size_t leave_td;
    56         /** Data buffer, must be accessible byb the OHCI hw. */
    57         void *device_buffer;
     51        char *device_buffer;
    5852} ohci_transfer_batch_t;
    59 /*----------------------------------------------------------------------------*/
    60 static void batch_control(usb_transfer_batch_t *instance,
    61     usb_direction_t data_dir, usb_direction_t status_dir);
    62 static void batch_data(usb_transfer_batch_t *instance);
    63 /*----------------------------------------------------------------------------*/
    64 /** Safely destructs ohci_transfer_batch_t structure
    65  *
    66  * @param[in] ohci_batch Instance to destroy.
    67  */
     53
    6854static void ohci_transfer_batch_dispose(void *ohci_batch)
    6955{
     
    8369}
    8470/*----------------------------------------------------------------------------*/
    85 /** Allocate memory initialize internal structures
    86  *
    87  * @param[in] fun DDF function to pass to callback.
    88  * @param[in] ep Communication target
    89  * @param[in] buffer Data source/destination.
    90  * @param[in] buffer_size Size of the buffer.
    91  * @param[in] setup_buffer Setup data source (if not NULL)
    92  * @param[in] setup_size Size of setup_buffer (should be always 8)
    93  * @param[in] func_in function to call on inbound transfer completion
    94  * @param[in] func_out function to call on outbound transfer completion
    95  * @param[in] arg additional parameter to func_in or func_out
    96  * @return Valid pointer if all structures were successfully created,
    97  * NULL otherwise.
    98  *
    99  * Allocates and initializes structures needed by the OHCI hw for the transfer.
    100  */
     71static void batch_control(usb_transfer_batch_t *instance,
     72    usb_direction_t data_dir, usb_direction_t status_dir);
     73static void batch_data(usb_transfer_batch_t *instance);
     74/*----------------------------------------------------------------------------*/
    10175usb_transfer_batch_t * batch_get(ddf_fun_t *fun, endpoint_t *ep,
    102     char *buffer, size_t buffer_size,
    103     const char *setup_buffer, size_t setup_size,
     76    char *buffer, size_t buffer_size, char* setup_buffer, size_t setup_size,
    10477    usbhc_iface_transfer_in_callback_t func_in,
    10578    usbhc_iface_transfer_out_callback_t func_out, void *arg)
     
    12194            ohci_transfer_batch_dispose);
    12295
    123         const hcd_endpoint_t *hcd_ep = hcd_endpoint_get(ep);
     96        hcd_endpoint_t *hcd_ep = hcd_endpoint_get(ep);
    12497        assert(hcd_ep);
    12598
     
    130103        data->td_count =
    131104            ((buffer_size + OHCI_TD_MAX_TRANSFER - 1) / OHCI_TD_MAX_TRANSFER);
    132         /* Control transfer need Setup and Status stage */
    133105        if (ep->transfer_type == USB_TRANSFER_CONTROL) {
    134106                data->td_count += 2;
    135107        }
    136108
    137         /* We need an extra place for TD that is currently assigned to hcd_ep*/
     109        /* we need one extra place for td that is currently assigned to hcd_ep*/
    138110        data->tds = calloc(sizeof(td_t*), data->td_count + 1);
    139111        CHECK_NULL_DISPOSE_RETURN(data->tds,
    140112            "Failed to allocate transfer descriptors.\n");
    141113
    142         /* Add TD left over by the previous transfer */
    143114        data->tds[0] = hcd_ep->td;
    144115        data->leave_td = 0;
     
    152123        data->ed = hcd_ep->ed;
    153124
    154         /* NOTE: OHCI is capable of handling buffer that crosses page boundaries
    155          * it is, however, not capable of handling buffer that occupies more
    156          * than two pages (the first page is computed using start pointer, the
    157          * other using the end pointer) */
    158125        if (setup_size + buffer_size > 0) {
    159126                data->device_buffer = malloc32(setup_size + buffer_size);
     
    168135}
    169136/*----------------------------------------------------------------------------*/
    170 /** Check batch TDs' status.
    171  *
    172  * @param[in] instance Batch structure to use.
    173  * @return False, if there is an active TD, true otherwise.
    174  *
    175  * Walk all TDs (usually there is just one). Stop with false if there is an
    176  * active TD. Stop with true if an error is found. Return true if the walk
    177  * completes with the last TD.
    178  */
    179137bool batch_is_complete(usb_transfer_batch_t *instance)
    180138{
     
    182140        ohci_transfer_batch_t *data = instance->private_data;
    183141        assert(data);
     142        size_t tds = data->td_count;
    184143        usb_log_debug("Batch(%p) checking %zu td(s) for completion.\n",
    185             instance, data->td_count);
     144            instance, tds);
    186145        usb_log_debug("ED: %x:%x:%x:%x.\n",
    187146            data->ed->status, data->ed->td_head, data->ed->td_tail,
     
    189148        size_t i = 0;
    190149        instance->transfered_size = instance->buffer_size;
    191         for (; i < data->td_count; ++i) {
     150        for (; i < tds; ++i) {
    192151                assert(data->tds[i] != NULL);
    193152                usb_log_debug("TD %zu: %x:%x:%x:%x.\n", i,
     
    214173        assert(hcd_ep);
    215174        hcd_ep->td = data->tds[i];
    216         assert(i > 0);
    217         for (--i;i < data->td_count; ++i)
    218                 instance->transfered_size -= td_remain_size(data->tds[i]);
     175        if (i > 0)
     176                instance->transfered_size -= td_remain_size(data->tds[i - 1]);
    219177
    220178        /* Clear possible ED HALT */
    221179        data->ed->td_head &= ~ED_TDHEAD_HALTED_FLAG;
    222         const uint32_t pa = addr_to_phys(hcd_ep->td);
     180        uint32_t pa = addr_to_phys(hcd_ep->td);
    223181        assert(pa == (data->ed->td_head & ED_TDHEAD_PTR_MASK));
    224182        assert(pa == (data->ed->td_tail & ED_TDTAIL_PTR_MASK));
     
    227185}
    228186/*----------------------------------------------------------------------------*/
    229 /** Starts execution of the TD list
    230  *
    231  * @param[in] instance Batch structure to use
    232  */
    233187void batch_commit(usb_transfer_batch_t *instance)
    234188{
     
    239193}
    240194/*----------------------------------------------------------------------------*/
    241 /** Prepares control write transfer.
    242  *
    243  * @param[in] instance Batch structure to use.
    244  *
    245  * Uses generic control transfer using direction OUT(data stage) and
    246  * IN(status stage).
    247  */
    248195void batch_control_write(usb_transfer_batch_t *instance)
    249196{
     
    256203}
    257204/*----------------------------------------------------------------------------*/
    258 /** Prepares control read transfer.
    259  *
    260  * @param[in] instance Batch structure to use.
    261  *
    262  * Uses generic control transfer using direction IN(data stage) and
    263  * OUT(status stage).
    264  */
    265205void batch_control_read(usb_transfer_batch_t *instance)
    266206{
     
    271211}
    272212/*----------------------------------------------------------------------------*/
    273 /** Prepare interrupt in transfer.
    274  *
    275  * @param[in] instance Batch structure to use.
    276  *
    277  * Data transfer.
    278  */
    279213void batch_interrupt_in(usb_transfer_batch_t *instance)
    280214{
     
    285219}
    286220/*----------------------------------------------------------------------------*/
    287 /** Prepare interrupt out transfer.
    288  *
    289  * @param[in] instance Batch structure to use.
    290  *
    291  * Data transfer.
    292  */
    293221void batch_interrupt_out(usb_transfer_batch_t *instance)
    294222{
     
    301229}
    302230/*----------------------------------------------------------------------------*/
    303 /** Prepare bulk in transfer.
    304  *
    305  * @param[in] instance Batch structure to use.
    306  *
    307  * Data transfer.
    308  */
    309231void batch_bulk_in(usb_transfer_batch_t *instance)
    310232{
     
    315237}
    316238/*----------------------------------------------------------------------------*/
    317 /** Prepare bulk out transfer.
    318  *
    319  * @param[in] instance Batch structure to use.
    320  *
    321  * Data transfer.
    322  */
    323239void batch_bulk_out(usb_transfer_batch_t *instance)
    324240{
     
    331247}
    332248/*----------------------------------------------------------------------------*/
    333 /** Prepare generic control transfer
    334  *
    335  * @param[in] instance Batch structure to use.
    336  * @param[in] data_dir Direction to use for data stage.
    337  * @param[in] status_dir Direction to use for status stage.
    338  *
    339  * Setup stage with toggle 0 and direction BOTH(SETUP_PID)
    340  * Data stage with alternating toggle and direction supplied by parameter.
    341  * Status stage with toggle 1 and direction supplied by parameter.
    342  */
     249ed_t * batch_ed(usb_transfer_batch_t *instance)
     250{
     251        assert(instance);
     252        ohci_transfer_batch_t *data = instance->private_data;
     253        assert(data);
     254        return data->ed;
     255}
     256/*----------------------------------------------------------------------------*/
    343257void batch_control(usb_transfer_batch_t *instance,
    344258    usb_direction_t data_dir, usb_direction_t status_dir)
     
    389303}
    390304/*----------------------------------------------------------------------------*/
    391 /** Prepare generic data transfer
    392  *
    393  * @param[in] instance Batch structure to use.
    394  *
    395  * Direction is supplied by the associated ep and toggle is maintained by the
    396  * OHCI hw in ED.
    397  */
    398305void batch_data(usb_transfer_batch_t *instance)
    399306{
     
    409316        char *buffer = instance->data_buffer;
    410317        while (remain_size > 0) {
    411                 const size_t transfer_size = remain_size > OHCI_TD_MAX_TRANSFER
    412                     ? OHCI_TD_MAX_TRANSFER : remain_size;
     318                size_t transfer_size = remain_size > OHCI_TD_MAX_TRANSFER ?
     319                    OHCI_TD_MAX_TRANSFER : remain_size;
    413320
    414321                td_init(data->tds[td_current], instance->ep->direction,
  • uspace/drv/ohci/batch.h

    r6bfaab5 r88be3a0b  
    4141#include <usb/host/batch.h>
    4242
     43#include "hw_struct/endpoint_descriptor.h"
     44
    4345usb_transfer_batch_t * batch_get(
    4446    ddf_fun_t *fun, endpoint_t *ep, char *buffer, size_t size,
    45     const char *setup_buffer, size_t setup_size,
     47    char *setup_buffer, size_t setup_size,
    4648    usbhc_iface_transfer_in_callback_t func_in,
    4749    usbhc_iface_transfer_out_callback_t func_out,
     
    6365
    6466void batch_bulk_out(usb_transfer_batch_t *instance);
     67
     68ed_t * batch_ed(usb_transfer_batch_t *instance);
    6569#endif
    6670/**
  • uspace/drv/ohci/endpoint_list.c

    r6bfaab5 r88be3a0b  
    3434#include <errno.h>
    3535#include <usb/debug.h>
    36 #include <arch/barrier.h>
    3736
    3837#include "endpoint_list.h"
     
    4443 * @return Error code
    4544 *
    46  * Allocates memory for internal ed_t structure.
     45 * Allocates memory for internal qh_t structure.
    4746 */
    4847int endpoint_list_init(endpoint_list_t *instance, const char *name)
     
    6968 * @param[in] instance List to lead.
    7069 * @param[in] next List to append.
    71  *
    72  * Does not check whether this replaces an existing list.
     70 * @return Error code
     71 *
     72 * Does not check whether this replaces an existing list .
    7373 */
    7474void endpoint_list_set_next(endpoint_list_t *instance, endpoint_list_t *next)
     
    7979}
    8080/*----------------------------------------------------------------------------*/
    81 /** Add endpoint to the list and queue.
    82  *
    83  * @param[in] instance List to use.
    84  * @param[in] endpoint Endpoint to add.
     81/** Submit transfer endpoint to the list and queue.
     82 *
     83 * @param[in] instance List to use.
     84 * @param[in] endpoint Transfer endpoint to submit.
     85 * @return Error code
    8586 *
    8687 * The endpoint is added to the end of the list and queue.
     
    9899        /* Add to the hardware queue. */
    99100        if (list_empty(&instance->endpoint_list)) {
    100                 /* There are no active EDs */
     101                /* There is nothing scheduled */
    101102                last_ed = instance->list_head;
    102103        } else {
    103                 /* There are active EDs, get the last one */
     104                /* There is something scheduled */
    104105                hcd_endpoint_t *last = list_get_instance(
    105106                    instance->endpoint_list.prev, hcd_endpoint_t, link);
    106                 assert(last);
    107107                last_ed = last->ed;
    108108        }
    109         /* Keep link */
     109        /* keep link */
    110110        hcd_ep->ed->next = last_ed->next;
    111         /* Make sure ED is written to the memory */
    112         write_barrier();
    113 
    114         /* Add ed to the hw queue */
    115111        ed_append_ed(last_ed, hcd_ep->ed);
    116         /* Make sure ED is updated */
    117         write_barrier();
    118 
    119         /* Add to the sw list */
     112
     113        asm volatile ("": : :"memory");
     114
     115        /* Add to the driver list */
    120116        list_append(&hcd_ep->link, &instance->endpoint_list);
    121117
     
    133129}
    134130/*----------------------------------------------------------------------------*/
    135 /** Remove endpoint from the list and queue.
    136  *
    137  * @param[in] instance List to use.
    138  * @param[in] endpoint Endpoint to remove.
     131#if 0
     132/** Create list for finished endpoints.
     133 *
     134 * @param[in] instance List to use.
     135 * @param[in] done list to fill
     136 */
     137void endpoint_list_remove_finished(endpoint_list_t *instance, link_t *done)
     138{
     139        assert(instance);
     140        assert(done);
     141
     142        fibril_mutex_lock(&instance->guard);
     143        usb_log_debug2("Checking list %s for completed endpointes(%d).\n",
     144            instance->name, list_count(&instance->endpoint_list));
     145        link_t *current = instance->endpoint_list.next;
     146        while (current != &instance->endpoint_list) {
     147                link_t *next = current->next;
     148                hcd_endpoint_t *endpoint =
     149                    list_get_instance(current, hcd_endpoint_t, link);
     150
     151                if (endpoint_is_complete(endpoint)) {
     152                        /* Save for post-processing */
     153                        endpoint_list_remove_endpoint(instance, endpoint);
     154                        list_append(current, done);
     155                }
     156                current = next;
     157        }
     158        fibril_mutex_unlock(&instance->guard);
     159}
     160/*----------------------------------------------------------------------------*/
     161/** Walk the list and abort all endpointes.
     162 *
     163 * @param[in] instance List to use.
     164 */
     165void endpoint_list_abort_all(endpoint_list_t *instance)
     166{
     167        fibril_mutex_lock(&instance->guard);
     168        while (!list_empty(&instance->endpoint_list)) {
     169                link_t *current = instance->endpoint_list.next;
     170                hcd_endpoint_t *endpoint =
     171                    list_get_instance(current, hcd_endpoint_t, link);
     172                endpoint_list_remove_endpoint(instance, endpoint);
     173                hcd_endpoint_finish_error(endpoint, EIO);
     174        }
     175        fibril_mutex_unlock(&instance->guard);
     176}
     177#endif
     178/*----------------------------------------------------------------------------*/
     179/** Remove a transfer endpoint from the list and queue.
     180 *
     181 * @param[in] instance List to use.
     182 * @param[in] endpoint Transfer endpoint to remove.
     183 * @return Error code
     184 *
     185 * Does not lock the transfer list, caller is responsible for that.
    139186 */
    140187void endpoint_list_remove_ep(endpoint_list_t *instance, hcd_endpoint_t *hcd_ep)
     
    165212        assert((prev_ed->next & ED_NEXT_PTR_MASK) == addr_to_phys(hcd_ep->ed));
    166213        prev_ed->next = hcd_ep->ed->next;
    167         /* Make sure ED is updated */
    168         write_barrier();
    169 
     214
     215        asm volatile ("": : :"memory");
    170216        usb_log_debug("HCD EP(%p) removed (%s) from %s, next %x.\n",
    171217            hcd_ep, qpos, instance->name, hcd_ep->ed->next);
  • uspace/drv/ohci/endpoint_list.h

    r6bfaab5 r88be3a0b  
    4141#include "utils/malloc32.h"
    4242
    43 /** Structure maintains both OHCI queue and software list of active endpoints.*/
    4443typedef struct endpoint_list {
    45         /** Guard against add/remove races */
    4644        fibril_mutex_t guard;
    47         /** OHCI hw structure at the beginning of the queue */
    4845        ed_t *list_head;
    49         /** Physical address of the first(dummy) ED */
    5046        uint32_t list_head_pa;
    51         /** Assigned name, provides nicer debug output */
    5247        const char *name;
    53         /** Sw list of all active EDs */
    5448        link_t endpoint_list;
    5549} endpoint_list_t;
     
    5953 * @param[in] instance Memory place to use.
    6054 *
    61  * Frees memory of the internal ed_t structure.
     55 * Frees memory for internal qh_t structure.
    6256 */
    6357static inline void endpoint_list_fini(endpoint_list_t *instance)
     
    6862
    6963int endpoint_list_init(endpoint_list_t *instance, const char *name);
     64
    7065void endpoint_list_set_next(endpoint_list_t *instance, endpoint_list_t *next);
     66
    7167void endpoint_list_add_ep(endpoint_list_t *instance, hcd_endpoint_t *hcd_ep);
     68
    7269void endpoint_list_remove_ep(endpoint_list_t *instance, hcd_endpoint_t *hcd_ep);
     70#if 0
     71void endpoint_list_remove_finished(endpoint_list_t *instance, link_t *done);
     72
     73void endpoint_list_abort_all(endpoint_list_t *instance);
     74#endif
    7375#endif
    7476/**
  • uspace/drv/ohci/hc.c

    r6bfaab5 r88be3a0b  
    5151static int hc_init_memory(hc_t *instance);
    5252/*----------------------------------------------------------------------------*/
    53 /** Announce OHCI root hub to the DDF
    54  *
    55  * @param[in] instance OHCI driver intance
    56  * @param[in] hub_fun DDF fuction representing OHCI root hub
    57  * @return Error code
    58  */
    5953int hc_register_hub(hc_t *instance, ddf_fun_t *hub_fun)
    6054{
     
    6256        assert(hub_fun);
    6357
    64         const usb_address_t hub_address =
     58        int ret;
     59
     60        usb_address_t hub_address =
    6561            device_keeper_get_free_address(&instance->manager, USB_SPEED_FULL);
    6662        if (hub_address <= 0) {
    67                 usb_log_error("Failed(%d) to get OHCI root hub address.\n",
    68                     hub_address);
     63                usb_log_error("Failed to get OHCI root hub address.\n");
    6964                return hub_address;
    7065        }
     
    7368            &instance->manager, hub_address, hub_fun->handle);
    7469
    75 #define CHECK_RET_RELEASE(ret, message...) \
    76 if (ret != EOK) { \
    77         usb_log_error(message); \
    78         hc_remove_endpoint(instance, hub_address, 0, USB_DIRECTION_BOTH); \
    79         usb_device_keeper_release(&instance->manager, hub_address); \
    80         return ret; \
    81 } else (void)0
    82 
    83         int ret = hc_add_endpoint(instance, hub_address, 0, USB_SPEED_FULL,
     70        ret = hc_add_endpoint(instance, hub_address, 0, USB_SPEED_FULL,
    8471            USB_TRANSFER_CONTROL, USB_DIRECTION_BOTH, 64, 0, 0);
    85         CHECK_RET_RELEASE(ret, "Failed(%d) to add OHCI rh endpoint 0.\n", ret);
     72        if (ret != EOK) {
     73                usb_log_error("Failed to add OHCI rh endpoint 0.\n");
     74                usb_device_keeper_release(&instance->manager, hub_address);
     75                return ret;
     76        }
    8677
    8778        char *match_str = NULL;
    8879        /* DDF needs heap allocated string */
    8980        ret = asprintf(&match_str, "usb&class=hub");
    90         ret = ret > 0 ? 0 : ret;
    91         CHECK_RET_RELEASE(ret, "Failed(%d) to create match-id string.\n", ret);
     81        if (ret < 0) {
     82                usb_log_error(
     83                    "Failed(%d) to create root hub match-id string.\n", ret);
     84                usb_device_keeper_release(&instance->manager, hub_address);
     85                return ret;
     86        }
    9287
    9388        ret = ddf_fun_add_match_id(hub_fun, match_str, 100);
    94         CHECK_RET_RELEASE(ret, "Failed(%d) add root hub match-id.\n", ret);
    95 
     89        if (ret != EOK) {
     90                usb_log_error("Failed add root hub match-id.\n");
     91        }
    9692        ret = ddf_fun_bind(hub_fun);
    97         CHECK_RET_RELEASE(ret, "Failed(%d) to bind root hub function.\n", ret);
    98 
    99         return EOK;
    100 #undef CHECK_RET_RELEASE
    101 }
    102 /*----------------------------------------------------------------------------*/
    103 /** Initialize OHCI hc driver structure
    104  *
    105  * @param[in] instance Memory place for the structure.
    106  * @param[in] regs Address of the memory mapped I/O registers.
    107  * @param[in] reg_size Size of the memory mapped area.
    108  * @param[in] interrupts True if w interrupts should be used
    109  * @return Error code
    110  */
     93        return ret;
     94}
     95/*----------------------------------------------------------------------------*/
    11196int hc_init(hc_t *instance, uintptr_t regs, size_t reg_size, bool interrupts)
    11297{
     
    136121#undef CHECK_RET_RETURN
    137122
     123
     124//      hc_init_hw(instance);
     125        hc_gain_control(instance);
    138126        fibril_mutex_initialize(&instance->guard);
    139         hc_gain_control(instance);
    140127
    141128        rh_init(&instance->rh, instance->registers);
     
    150137}
    151138/*----------------------------------------------------------------------------*/
    152 /** Create end register endpoint structures
    153  *
    154  * @param[in] instance OHCI driver structure.
    155  * @param[in] address USB address of the device.
    156  * @param[in] endpoint USB endpoint number.
    157  * @param[in] speed Communication speeed of the device.
    158  * @param[in] type Endpoint's transfer type.
    159  * @param[in] direction Endpoint's direction.
    160  * @param[in] mps Maximum packet size the endpoint accepts.
    161  * @param[in] size Maximum allowed buffer size.
    162  * @param[in] interval Time between transfers(interrupt transfers only).
    163  * @return Error code
    164  */
    165139int hc_add_endpoint(
    166140    hc_t *instance, usb_address_t address, usb_endpoint_t endpoint,
     
    220194}
    221195/*----------------------------------------------------------------------------*/
    222 /** Dequeue and delete endpoint structures
    223  *
    224  * @param[in] instance OHCI hc driver structure.
    225  * @param[in] address USB address of the device.
    226  * @param[in] endpoint USB endpoint number.
    227  * @param[in] direction Direction of the endpoint.
    228  * @return Error code
    229  */
    230196int hc_remove_endpoint(hc_t *instance, usb_address_t address,
    231197    usb_endpoint_t endpoint, usb_direction_t direction)
     
    278244}
    279245/*----------------------------------------------------------------------------*/
    280 /** Get access to endpoint structures
    281  *
    282  * @param[in] instance OHCI hc driver structure.
    283  * @param[in] address USB address of the device.
    284  * @param[in] endpoint USB endpoint number.
    285  * @param[in] direction Direction of the endpoint.
    286  * @param[out] bw Reserved bandwidth.
    287  * @return Error code
    288  */
    289246endpoint_t * hc_get_endpoint(hc_t *instance, usb_address_t address,
    290247    usb_endpoint_t endpoint, usb_direction_t direction, size_t *bw)
     
    298255}
    299256/*----------------------------------------------------------------------------*/
    300 /** Add USB transfer to the schedule.
    301  *
    302  * @param[in] instance OHCI hc driver structure.
    303  * @param[in] batch Batch representing the transfer.
    304  * @return Error code.
    305  */
    306257int hc_schedule(hc_t *instance, usb_transfer_batch_t *batch)
    307258{
     
    310261        assert(batch->ep);
    311262
    312         /* Check for root hub communication */
     263        /* check for root hub communication */
    313264        if (batch->ep->address == instance->rh.address) {
    314265                return rh_request(&instance->rh, batch);
     
    318269        list_append(&batch->link, &instance->pending_batches);
    319270        batch_commit(batch);
    320 
    321         /* Control and bulk schedules need a kick to start working */
    322         switch (batch->ep->transfer_type)
    323         {
     271        switch (batch->ep->transfer_type) {
    324272        case USB_TRANSFER_CONTROL:
    325273                instance->registers->command_status |= CS_CLF;
     
    331279                break;
    332280        }
     281
    333282        fibril_mutex_unlock(&instance->guard);
    334283        return EOK;
    335284}
    336285/*----------------------------------------------------------------------------*/
    337 /** Interrupt handling routine
    338  *
    339  * @param[in] instance OHCI hc driver structure.
    340  * @param[in] status Value of the status register at the time of interrupt.
    341  */
    342286void hc_interrupt(hc_t *instance, uint32_t status)
    343287{
     
    348292        if (status & I_RHSC)
    349293                rh_interrupt(&instance->rh);
     294
    350295
    351296        if (status & I_WDH) {
     
    371316                fibril_mutex_unlock(&instance->guard);
    372317        }
    373 
    374         if (status & I_UE) {
    375                 hc_start_hw(instance);
    376         }
    377 
    378 }
    379 /*----------------------------------------------------------------------------*/
    380 /** Check status register regularly
    381  *
    382  * @param[in] instance OHCI hc driver structure.
    383  * @return Error code
    384  */
     318}
     319/*----------------------------------------------------------------------------*/
    385320int interrupt_emulator(hc_t *instance)
    386321{
     
    391326                instance->registers->interrupt_status = status;
    392327                hc_interrupt(instance, status);
    393                 async_usleep(10000);
     328                async_usleep(50000);
    394329        }
    395330        return EOK;
    396331}
    397332/*----------------------------------------------------------------------------*/
    398 /** Turn off any (BIOS)driver that might be in control of the device.
    399  *
    400  * @param[in] instance OHCI hc driver structure.
    401  */
    402333void hc_gain_control(hc_t *instance)
    403334{
     
    449380}
    450381/*----------------------------------------------------------------------------*/
    451 /** OHCI hw initialization routine.
    452  *
    453  * @param[in] instance OHCI hc driver structure.
    454  */
    455382void hc_start_hw(hc_t *instance)
    456383{
     
    520447}
    521448/*----------------------------------------------------------------------------*/
    522 /** Initialize schedule queues
    523  *
    524  * @param[in] instance OHCI hc driver structure
    525  * @return Error code
    526  */
    527449int hc_init_transfer_lists(hc_t *instance)
    528450{
    529451        assert(instance);
     452
    530453#define SETUP_ENDPOINT_LIST(type) \
    531454do { \
     
    535458                usb_log_error("Failed(%d) to setup %s endpoint list.\n", \
    536459                    ret, name); \
    537                 endpoint_list_fini(&instance->lists[USB_TRANSFER_ISOCHRONOUS]);\
     460                endpoint_list_fini(&instance->lists[USB_TRANSFER_ISOCHRONOUS]); \
    538461                endpoint_list_fini(&instance->lists[USB_TRANSFER_INTERRUPT]); \
    539462                endpoint_list_fini(&instance->lists[USB_TRANSFER_CONTROL]); \
    540463                endpoint_list_fini(&instance->lists[USB_TRANSFER_BULK]); \
    541                 return ret; \
    542464        } \
    543465} while (0)
     
    554476}
    555477/*----------------------------------------------------------------------------*/
    556 /** Initialize memory structures used by the OHCI hcd.
    557  *
    558  * @param[in] instance OHCI hc driver structure.
    559  * @return Error code.
    560  */
    561478int hc_init_memory(hc_t *instance)
    562479{
     
    565482        bzero(&instance->rh, sizeof(instance->rh));
    566483        /* Init queues */
    567         const int ret = hc_init_transfer_lists(instance);
    568         if (ret != EOK) {
    569                 return ret;
    570         }
     484        hc_init_transfer_lists(instance);
    571485
    572486        /*Init HCCA */
     
    588502        /* Init interrupt code */
    589503        instance->interrupt_code.cmds = instance->interrupt_commands;
    590         instance->interrupt_code.cmdcount = OHCI_NEEDED_IRQ_COMMANDS;
    591504        {
    592505                /* Read status register */
     
    608521                instance->interrupt_commands[2].srcarg = 2;
    609522
    610                 /* Write-clean status register */
     523                /* Write clean status register */
    611524                instance->interrupt_commands[3].cmd = CMD_MEM_WRITE_A_32;
    612525                instance->interrupt_commands[3].srcarg = 1;
     
    616529                /* Accept interrupt */
    617530                instance->interrupt_commands[4].cmd = CMD_ACCEPT;
     531
     532                instance->interrupt_code.cmdcount = OHCI_NEEDED_IRQ_COMMANDS;
    618533        }
    619534
  • uspace/drv/ohci/hc.h

    r6bfaab5 r88be3a0b  
    5353#define OHCI_NEEDED_IRQ_COMMANDS 5
    5454
    55 /** Main OHCI drier structure */
    5655typedef struct hc {
    57         /** USB bus driver, devices and addresses */
    58         usb_device_keeper_t manager;
    59         /** USB bus driver, endpoints */
    60         usb_endpoint_manager_t ep_manager;
    61 
    62         /** Memory mapped I/O registers area */
    6356        ohci_regs_t *registers;
    64         /** Host controller communication area structure */
    6557        hcca_t *hcca;
    6658
    67         /** Transfer schedules */
     59        usb_address_t rh_address;
     60        rh_t rh;
     61
    6862        endpoint_list_t lists[4];
    69         /** List of active transfers */
    7063        link_t pending_batches;
    7164
    72         /** Fibril for periodic checks if interrupts can't be used */
     65        usb_device_keeper_t manager;
     66        usb_endpoint_manager_t ep_manager;
    7367        fid_t interrupt_emulator;
    74 
    75         /** Guards schedule and endpoint manipulation */
    7668        fibril_mutex_t guard;
    7769
     
    8173        /** Commands that form interrupt code */
    8274        irq_cmd_t interrupt_commands[OHCI_NEEDED_IRQ_COMMANDS];
    83 
    84         /** USB hub emulation structure */
    85         rh_t rh;
    8675} hc_t;
    8776
    8877int hc_register_hub(hc_t *instance, ddf_fun_t *hub_fun);
     78
    8979int hc_init(hc_t *instance, uintptr_t regs, size_t reg_size, bool interrupts);
     80
    9081void hc_start_hw(hc_t *instance);
    9182
     
    9485 * @param[in] instance Host controller structure to use.
    9586 */
    96 static inline void hc_fini(hc_t *instance)
    97         { /* TODO: implement*/ };
     87static inline void hc_fini(hc_t *instance) { /* TODO: implement*/ };
    9888
    9989int hc_add_endpoint(hc_t *instance, usb_address_t address, usb_endpoint_t ep,
    10090    usb_speed_t speed, usb_transfer_type_t type, usb_direction_t direction,
    10191    size_t max_packet_size, size_t size, unsigned interval);
     92
    10293int hc_remove_endpoint(hc_t *instance, usb_address_t address,
    10394    usb_endpoint_t endpoint, usb_direction_t direction);
     95
    10496endpoint_t * hc_get_endpoint(hc_t *instance, usb_address_t address,
    10597    usb_endpoint_t endpoint, usb_direction_t direction, size_t *bw);
    10698
    10799int hc_schedule(hc_t *instance, usb_transfer_batch_t *batch);
     100
    108101void hc_interrupt(hc_t *instance, uint32_t status);
    109102
     
    114107 */
    115108static inline hc_t * fun_to_hc(ddf_fun_t *fun)
    116         { return fun->driver_data; }
     109        { return (hc_t*)fun->driver_data; }
    117110#endif
    118111/**
  • uspace/drv/ohci/hcd_endpoint.c

    r6bfaab5 r88be3a0b  
    3535#include "hcd_endpoint.h"
    3636
    37 /** Callback to set toggle on ED.
    38  *
    39  * @param[in] hcd_ep hcd endpoint structure
    40  * @param[in] toggle new value of toggle bit
    41  */
    4237static void hcd_ep_toggle_set(void *hcd_ep, int toggle)
    4338{
     
    4742        ed_toggle_set(instance->ed, toggle);
    4843}
    49 /*----------------------------------------------------------------------------*/
    50 /** Callback to get value of toggle bit.
    51  *
    52  * @param[in] hcd_ep hcd endpoint structure
    53  * @return Current value of toggle bit.
    54  */
    5544static int hcd_ep_toggle_get(void *hcd_ep)
    5645{
     
    6049        return ed_toggle_get(instance->ed);
    6150}
    62 /*----------------------------------------------------------------------------*/
    63 /** Creates new hcd endpoint representation.
    64  *
    65  * @param[in] ep USBD endpoint structure
    66  * @return pointer to a new hcd endpoint structure, NULL on failure.
    67  */
     51
     52
    6853hcd_endpoint_t * hcd_endpoint_assign(endpoint_t *ep)
    6954{
     
    9378}
    9479/*----------------------------------------------------------------------------*/
    95 /** Disposes assigned hcd endpoint structure
    96  *
    97  * @param[in] ep USBD endpoint structure
    98  */
     80hcd_endpoint_t * hcd_endpoint_get(endpoint_t *ep)
     81{
     82        assert(ep);
     83        return ep->hc_data.data;
     84}
     85/*----------------------------------------------------------------------------*/
    9986void hcd_endpoint_clear(endpoint_t *ep)
    10087{
  • uspace/drv/ohci/hcd_endpoint.h

    r6bfaab5 r88be3a0b  
    3737#include <assert.h>
    3838#include <adt/list.h>
     39
    3940#include <usb/host/endpoint.h>
    4041
     
    4243#include "hw_struct/transfer_descriptor.h"
    4344
    44 /** Connector structure linking ED to to prepared TD. */
    4545typedef struct hcd_endpoint {
    46         /** OHCI endpoint descriptor */
    4746        ed_t *ed;
    48         /** Currently enqueued transfer descriptor */
    4947        td_t *td;
    50         /** Linked list used by driver software */
    5148        link_t link;
    5249} hcd_endpoint_t;
    5350
    5451hcd_endpoint_t * hcd_endpoint_assign(endpoint_t *ep);
     52
     53hcd_endpoint_t * hcd_endpoint_get(endpoint_t *ep);
     54
    5555void hcd_endpoint_clear(endpoint_t *ep);
    56 
    57 /** Get and convert assigned hcd_endpoint_t structure
    58  * @param[in] ep USBD endpoint structure.
    59  * @return Pointer to assigned hcd endpoint structure
    60  */
    61 static inline hcd_endpoint_t * hcd_endpoint_get(endpoint_t *ep)
    62 {
    63         assert(ep);
    64         return ep->hc_data.data;
    65 }
    66 
    6756#endif
    6857/**
  • uspace/drv/ohci/hw_struct/transfer_descriptor.c

    r6bfaab5 r88be3a0b  
    4444        assert(instance);
    4545        bzero(instance, sizeof(td_t));
    46         instance->status = 0
     46        instance-> status = 0
    4747            | ((dp[dir] & TD_STATUS_DP_MASK) << TD_STATUS_DP_SHIFT)
    4848            | ((CC_NOACCESS2 & TD_STATUS_CC_MASK) << TD_STATUS_CC_SHIFT);
  • uspace/drv/ohci/hw_struct/transfer_descriptor.h

    r6bfaab5 r88be3a0b  
    4141#include "completion_codes.h"
    4242
    43 /* OHCI TDs can handle up to 8KB buffers, however, it can use max 2 pages.
    44  * Using 4KB buffers guarantees the page count condition.
    45  * (OHCI assumes 4KB pages) */
    46 #define OHCI_TD_MAX_TRANSFER (4 * 1024)
     43/* OHCI TDs can handle up to 8KB buffers */
     44#define OHCI_TD_MAX_TRANSFER (8 * 1024)
    4745
    4846typedef struct td {
  • uspace/drv/ohci/ohci_regs.h

    r6bfaab5 r88be3a0b  
    3636#include <stdint.h>
    3737
    38 /** OHCI memory mapped registers structure */
    39 typedef struct ohci_regs {
     38typedef struct ohci_regs
     39{
    4040        const volatile uint32_t revision;
    4141        volatile uint32_t control;
  • uspace/drv/uhci-hcd/Makefile

    r6bfaab5 r88be3a0b  
    4848        root_hub.c \
    4949        hw_struct/transfer_descriptor.c \
     50        utils/slab.c \
    5051        pci.c \
    5152        batch.c
  • uspace/drv/uhci-hcd/batch.c

    r6bfaab5 r88be3a0b  
    4545#define DEFAULT_ERROR_COUNT 3
    4646
    47 /** UHCI specific data required for USB transfer */
    4847typedef struct uhci_transfer_batch {
    49         /** Queue head
    50          * This QH is used to maintain UHCI schedule structure and the element
    51          * pointer points to the first TD of this batch.
    52          */
    5348        qh_t *qh;
    54         /** List of TDs needed for the transfer */
    5549        td_t *tds;
    56         /** Number of TDs used by the transfer */
     50        void *device_buffer;
    5751        size_t td_count;
    58         /** Data buffer, must be accessible by the UHCI hw */
    59         void *device_buffer;
    6052} uhci_transfer_batch_t;
    6153/*----------------------------------------------------------------------------*/
     54static void uhci_transfer_batch_dispose(void *uhci_batch)
     55{
     56        uhci_transfer_batch_t *instance = uhci_batch;
     57        assert(instance);
     58        free32(instance->device_buffer);
     59        free(instance);
     60}
     61/*----------------------------------------------------------------------------*/
     62
    6263static void batch_control(usb_transfer_batch_t *instance,
    6364    usb_packet_id data_stage, usb_packet_id status_stage);
    6465static void batch_data(usb_transfer_batch_t *instance, usb_packet_id pid);
    65 /*----------------------------------------------------------------------------*/
    66 /** Safely destructs uhci_transfer_batch_t structure
    67  *
    68  * @param[in] uhci_batch Instance to destroy.
    69  */
    70 static void uhci_transfer_batch_dispose(void *uhci_batch)
    71 {
    72         uhci_transfer_batch_t *instance = uhci_batch;
    73         assert(instance);
    74         free32(instance->device_buffer);
    75         free(instance);
    76 }
    77 /*----------------------------------------------------------------------------*/
     66
    7867/** Allocate memory and initialize internal data structure.
    7968 *
     
    9584 */
    9685usb_transfer_batch_t * batch_get(ddf_fun_t *fun, endpoint_t *ep,
    97     char *buffer, size_t buffer_size,
    98     const char* setup_buffer, size_t setup_size,
     86    char *buffer, size_t buffer_size, char* setup_buffer, size_t setup_size,
    9987    usbhc_iface_transfer_in_callback_t func_in,
    10088    usbhc_iface_transfer_out_callback_t func_out, void *arg)
     
    185173                instance->error = td_status(&data->tds[i]);
    186174                if (instance->error != EOK) {
    187                         usb_log_debug("Batch(%p) found error TD(%zu):%"
    188                             PRIx32 ".\n", instance, i, data->tds[i].status);
     175                        usb_log_debug("Batch(%p) found error TD(%zu):%" PRIx32 ".\n",
     176                            instance, i, data->tds[i].status);
    189177                        td_print_status(&data->tds[i]);
    190178
     
    409397/*----------------------------------------------------------------------------*/
    410398/** Provides access to QH data structure.
    411  *
    412399 * @param[in] instance Batch pointer to use.
    413400 * @return Pointer to the QH used by the batch.
  • uspace/drv/uhci-hcd/batch.h

    r6bfaab5 r88be3a0b  
    3535#define DRV_UHCI_BATCH_H
    3636
     37#include <usbhc_iface.h>
     38#include <usb/usb.h>
     39#include <usb/host/device_keeper.h>
     40#include <usb/host/endpoint.h>
    3741#include <usb/host/batch.h>
    3842
     
    4145usb_transfer_batch_t * batch_get(
    4246    ddf_fun_t *fun, endpoint_t *ep, char *buffer, size_t size,
    43     const char *setup_buffer, size_t setup_size,
     47    char *setup_buffer, size_t setup_size,
    4448    usbhc_iface_transfer_in_callback_t func_in,
    4549    usbhc_iface_transfer_out_callback_t func_out,
     
    5155
    5256void batch_control_write(usb_transfer_batch_t *instance);
     57
    5358void batch_control_read(usb_transfer_batch_t *instance);
    5459
    5560void batch_interrupt_in(usb_transfer_batch_t *instance);
     61
    5662void batch_interrupt_out(usb_transfer_batch_t *instance);
    5763
    5864void batch_bulk_in(usb_transfer_batch_t *instance);
     65
    5966void batch_bulk_out(usb_transfer_batch_t *instance);
    6067
  • uspace/drv/uhci-hcd/hc.c

    r6bfaab5 r88be3a0b  
    3939#include <usb/debug.h>
    4040#include <usb/usb.h>
     41#include <usb/ddfiface.h>
     42#include <usb_iface.h>
    4143
    4244#include "hc.h"
     
    5557static int hc_debug_checker(void *arg);
    5658/*----------------------------------------------------------------------------*/
    57 /** Initialize UHCI hc driver structure
     59/** Initialize UHCI hcd driver structure
    5860 *
    5961 * @param[in] instance Memory place to initialize.
     
    8385        /* allow access to hc control registers */
    8486        regs_t *io;
    85         ret = pio_enable(regs, reg_size, (void **)&io);
     87        ret = pio_enable(regs, reg_size, (void**)&io);
    8688        CHECK_RET_RETURN(ret,
    8789            "Failed(%d) to gain access to registers at %p: %s.\n",
     
    141143        }
    142144
    143         const uint16_t status = pio_read_16(&registers->usbcmd);
     145        uint16_t status = pio_read_16(&registers->usbcmd);
    144146        if (status != 0)
    145147                usb_log_warning("Previous command value: %x.\n", status);
     
    210212        /* Init USB frame list page*/
    211213        instance->frame_list = get_page();
    212         ret = instance->frame_list ? EOK : ENOMEM;
     214        ret = instance ? EOK : ENOMEM;
    213215        CHECK_RET_RETURN(ret, "Failed to get frame list page.\n");
    214216        usb_log_debug("Initialized frame list at %p.\n", instance->frame_list);
     
    275277                &instance->transfers_control_slow);
    276278
    277         /*FSBR, This feature is not needed (adds no benefit) and is supposedly
    278          * buggy on certain hw, enable at your own risk. */
     279        /*FSBR*/
    279280#ifdef FSBR
    280281        transfer_list_set_next(&instance->transfers_bulk_full,
     
    427428                }
    428429
    429                 const uintptr_t frame_list =
     430                uintptr_t frame_list =
    430431                    pio_read_32(&instance->registers->flbaseadd) & ~0xfff;
    431432                if (frame_list != addr_to_phys(instance->frame_list)) {
  • uspace/drv/uhci-hcd/hc.h

    r6bfaab5 r88be3a0b  
    3737
    3838#include <fibril.h>
     39#include <fibril_synch.h>
     40#include <adt/list.h>
    3941#include <ddi.h>
    4042
     43#include <usbhc_iface.h>
    4144#include <usb/host/device_keeper.h>
    4245#include <usb/host/usb_endpoint_manager.h>
    43 #include <usb/host/batch.h>
    4446
     47#include "batch.h"
    4548#include "transfer_list.h"
    4649
     
    9295#define UHCI_NEEDED_IRQ_COMMANDS 5
    9396
    94 /** Main UHCI driver structure */
     97/* Main HC driver structure */
    9598typedef struct hc {
    9699        /** USB bus driver, devices and addresses */
     
    151154 */
    152155static inline hc_t * fun_to_hc(ddf_fun_t *fun)
    153 {
    154         assert(fun);
    155         return fun->driver_data;
    156 }
     156        { return (hc_t*)fun->driver_data; }
    157157#endif
    158158/**
  • uspace/drv/uhci-hcd/iface.c

    r6bfaab5 r88be3a0b  
    3939
    4040#include "iface.h"
    41 #include "batch.h"
    4241#include "hc.h"
    4342
     
    123122        return EOK;
    124123}
    125 /*----------------------------------------------------------------------------*/
     124
    126125/** Find device handle by address interface function.
    127126 *
     
    137136        hc_t *hc = fun_to_hc(fun);
    138137        assert(hc);
    139         const bool found =
     138        bool found =
    140139            usb_device_keeper_find_by_address(&hc->manager, address, handle);
    141140        return found ? EOK : ENOENT;
    142141}
     142
    143143/*----------------------------------------------------------------------------*/
    144144/** Release address interface function
     
    164164    size_t max_packet_size, unsigned int interval)
    165165{
    166         assert(fun);
    167166        hc_t *hc = fun_to_hc(fun);
    168167        assert(hc);
     
    184183    usb_endpoint_t endpoint, usb_direction_t direction)
    185184{
    186         assert(fun);
    187185        hc_t *hc = fun_to_hc(fun);
    188186        assert(hc);
     
    213211        if (ret != EOK)
    214212                return ret;
    215         assert(batch);
    216         assert(hc);
    217213        batch_interrupt_out(batch);
    218214        ret = hc_schedule(hc, batch);
     
    243239        if (ret != EOK)
    244240                return ret;
    245         assert(batch);
    246         assert(hc);
    247241        batch_interrupt_in(batch);
    248242        ret = hc_schedule(hc, batch);
     
    273267        if (ret != EOK)
    274268                return ret;
    275         assert(batch);
    276         assert(hc);
    277269        batch_bulk_out(batch);
    278270        ret = hc_schedule(hc, batch);
     
    303295        if (ret != EOK)
    304296                return ret;
    305         assert(batch);
    306         assert(hc);
    307297        batch_bulk_in(batch);
    308298        ret = hc_schedule(hc, batch);
     
    337327        if (ret != EOK)
    338328                return ret;
    339         assert(batch);
    340         assert(hc);
    341329        usb_endpoint_manager_reset_if_need(&hc->ep_manager, target, setup_data);
    342330        batch_control_write(batch);
     
    372360        if (ret != EOK)
    373361                return ret;
    374         assert(batch);
    375         assert(hc);
    376362        batch_control_read(batch);
    377363        ret = hc_schedule(hc, batch);
  • uspace/drv/uhci-hcd/pci.c

    r6bfaab5 r88be3a0b  
    5252 * @return Error code.
    5353 */
    54 int pci_get_my_registers(const ddf_dev_t *dev,
     54int pci_get_my_registers(ddf_dev_t *dev,
    5555    uintptr_t *io_reg_address, size_t *io_reg_size, int *irq_no)
    5656{
    57         assert(dev);
    58         assert(io_reg_address);
    59         assert(io_reg_size);
    60         assert(irq_no);
     57        assert(dev != NULL);
    6158
    6259        int parent_phone =
     
    6966        int rc = hw_res_get_resource_list(parent_phone, &hw_resources);
    7067        if (rc != EOK) {
    71                 async_hangup(parent_phone);
    72                 return rc;
     68                goto leave;
    7369        }
    7470
     
    8278        size_t i;
    8379        for (i = 0; i < hw_resources.count; i++) {
    84                 const hw_resource_t *res = &hw_resources.resources[i];
     80                hw_resource_t *res = &hw_resources.resources[i];
    8581                switch (res->type)
    8682                {
     
    10399                }
    104100        }
    105         async_hangup(parent_phone);
    106101
    107         if (!io_found || !irq_found)
    108                 return ENOENT;
     102        if (!io_found || !irq_found) {
     103                rc = ENOENT;
     104                goto leave;
     105        }
    109106
    110107        *io_reg_address = io_address;
     
    112109        *irq_no = irq;
    113110
    114         return EOK;
     111        rc = EOK;
     112leave:
     113        async_hangup(parent_phone);
     114        return rc;
    115115}
    116116/*----------------------------------------------------------------------------*/
     
    120120 * @return Error code.
    121121 */
    122 int pci_enable_interrupts(const ddf_dev_t *device)
     122int pci_enable_interrupts(ddf_dev_t *device)
    123123{
    124         const int parent_phone =
    125             devman_parent_device_connect(device->handle, IPC_FLAG_BLOCKING);
    126         if (parent_phone < 0) {
    127                 return parent_phone;
    128         }
    129         const bool enabled = hw_res_enable_interrupt(parent_phone);
     124        int parent_phone = devman_parent_device_connect(device->handle,
     125            IPC_FLAG_BLOCKING);
     126        bool enabled = hw_res_enable_interrupt(parent_phone);
    130127        async_hangup(parent_phone);
    131128        return enabled ? EOK : EIO;
     
    137134 * @return Error code.
    138135 */
    139 int pci_disable_legacy(const ddf_dev_t *device)
     136int pci_disable_legacy(ddf_dev_t *device)
    140137{
    141138        assert(device);
    142         const int parent_phone =
     139        int parent_phone =
    143140            devman_parent_device_connect(device->handle, IPC_FLAG_BLOCKING);
    144141        if (parent_phone < 0) {
     
    148145        /* See UHCI design guide for these values p.45,
    149146         * write all WC bits in USB legacy register */
    150         const sysarg_t address = 0xc0;
    151         const sysarg_t value = 0xaf00;
     147        sysarg_t address = 0xc0;
     148        sysarg_t value = 0xaf00;
    152149
    153         const int rc = async_req_3_0(parent_phone, DEV_IFACE_ID(PCI_DEV_IFACE),
     150        int rc = async_req_3_0(parent_phone, DEV_IFACE_ID(PCI_DEV_IFACE),
    154151            IPC_M_CONFIG_SPACE_WRITE_16, address, value);
    155152        async_hangup(parent_phone);
  • uspace/drv/uhci-hcd/pci.h

    r6bfaab5 r88be3a0b  
    3838#include <ddf/driver.h>
    3939
    40 int pci_get_my_registers(const ddf_dev_t *, uintptr_t *, size_t *, int *);
    41 int pci_enable_interrupts(const ddf_dev_t *);
    42 int pci_disable_legacy(const ddf_dev_t *);
     40int pci_get_my_registers(ddf_dev_t *, uintptr_t *, size_t *, int *);
     41int pci_enable_interrupts(ddf_dev_t *);
     42int pci_disable_legacy(ddf_dev_t *);
    4343
    4444#endif
  • uspace/drv/uhci-hcd/root_hub.c

    r6bfaab5 r88be3a0b  
    6060                return ret;
    6161        }
    62         assert(match_str);
    6362
    6463        ret = ddf_fun_add_match_id(fun, match_str, 100);
  • uspace/drv/uhci-hcd/root_hub.h

    r6bfaab5 r88be3a0b  
    4343        /** List of resources available to the root hub. */
    4444        hw_resource_list_t resource_list;
    45         /** The only resource in the RH resource list */
     45        /** The only resource in the above list */
    4646        hw_resource_t io_regs;
    4747} rh_t;
  • uspace/drv/uhci-hcd/transfer_list.c

    r6bfaab5 r88be3a0b  
    3434#include <errno.h>
    3535#include <usb/debug.h>
    36 #include <arch/barrier.h>
    37 
    3836
    3937#include "transfer_list.h"
    40 #include "batch.h"
    4138
    4239static void transfer_list_remove_batch(
     
    6057                return ENOMEM;
    6158        }
    62         const uint32_t queue_head_pa = addr_to_phys(instance->queue_head);
     59        uint32_t queue_head_pa = addr_to_phys(instance->queue_head);
    6360        usb_log_debug2("Transfer list %s setup with QH: %p (%#" PRIx32" ).\n",
    6461            name, instance->queue_head, queue_head_pa);
     
    7471 * @param[in] instance Memory place to use.
    7572 *
    76  * Frees memory of the internal qh_t structure.
     73 * Frees memory for internal qh_t structure.
    7774 */
    7875void transfer_list_fini(transfer_list_t *instance)
     
    9289{
    9390        assert(instance);
    94         assert(instance->queue_head);
    9591        assert(next);
     92        if (!instance->queue_head)
     93                return;
    9694        /* Set queue_head.next to point to the follower */
    9795        qh_set_next_qh(instance->queue_head, next->queue_head);
     
    128126        assert((pa & LINK_POINTER_ADDRESS_MASK) == pa);
    129127
    130         /* Make sure all data in the batch are written */
    131         write_barrier();
    132 
    133128        /* keep link */
    134129        batch_qh(batch)->next = last_qh->next;
    135130        qh_set_next_qh(last_qh, batch_qh(batch));
    136131
    137         /* Make sure the pointer is updated */
    138         write_barrier();
    139 
    140         /* Add to the driver's list */
     132        asm volatile ("": : :"memory");
     133
     134        /* Add to the driver list */
    141135        list_append(&batch->link, &instance->batch_list);
    142136
     
    161155        link_t *current = instance->batch_list.next;
    162156        while (current != &instance->batch_list) {
    163                 link_t * const next = current->next;
     157                link_t *next = current->next;
    164158                usb_transfer_batch_t *batch =
    165159                    usb_transfer_batch_from_link(current);
     
    183177        fibril_mutex_lock(&instance->guard);
    184178        while (!list_empty(&instance->batch_list)) {
    185                 link_t * const current = instance->batch_list.next;
     179                link_t *current = instance->batch_list.next;
    186180                usb_transfer_batch_t *batch =
    187181                    usb_transfer_batch_from_link(current);
     
    228222            == addr_to_phys(batch_qh(batch)));
    229223        prev_qh->next = batch_qh(batch)->next;
    230 
    231         /* Make sure the pointer is updated */
    232         write_barrier();
    233 
     224        asm volatile ("": : :"memory");
    234225        /* Remove from the batch list */
    235226        list_remove(&batch->link);
  • uspace/drv/uhci-hcd/transfer_list.h

    r6bfaab5 r88be3a0b  
    3636
    3737#include <fibril_synch.h>
    38 #include <usb/host/batch.h>
    3938
     39#include "batch.h"
    4040#include "hw_struct/queue_head.h"
    4141
     
    4343 * of currently executed transfers
    4444 */
    45 typedef struct transfer_list {
     45typedef struct transfer_list
     46{
    4647        /** Guard against multiple add/remove races */
    4748        fibril_mutex_t guard;
  • uspace/drv/uhci-hcd/uhci.c

    r6bfaab5 r88be3a0b  
    7777{
    7878        assert(dev);
    79         uhci_t *uhci = dev->driver_data;
    80         assert(uhci);
    81         hc_t *hc = &uhci->hc;
     79        hc_t *hc = &((uhci_t*)dev->driver_data)->hc;
    8280        uint16_t status = IPC_GET_ARG1(*call);
    8381        assert(hc);
     
    146144{
    147145        assert(fun);
    148         rh_t *rh = fun->driver_data;
    149         assert(rh);
    150         return &rh->resource_list;
     146        return &((rh_t*)fun->driver_data)->resource_list;
    151147}
    152148/*----------------------------------------------------------------------------*/
  • uspace/drv/uhci-hcd/uhci.h

    r6bfaab5 r88be3a0b  
    3535#ifndef DRV_UHCI_UHCI_H
    3636#define DRV_UHCI_UHCI_H
     37#include <ddi.h>
    3738#include <ddf/driver.h>
    3839
  • uspace/drv/uhci-hcd/utils/malloc32.h

    r6bfaab5 r88be3a0b  
    4141#include <as.h>
    4242
     43#include "slab.h"
     44
    4345#define UHCI_STRCUTURES_ALIGNMENT 16
    4446#define UHCI_REQUIRED_PAGE_SIZE 4096
     
    5759        uintptr_t result;
    5860        const int ret = as_get_physical_mapping(addr, &result);
     61        assert(ret == EOK);
     62
    5963        if (ret != EOK)
    6064                return 0;
     
    6872 */
    6973static inline void * malloc32(size_t size) {
    70         /* This works only when the host has less than 4GB of memory as
    71          * physical address needs to fit into 32 bits */
    72 
    73         /* If we need more than one page there is no guarantee that the
    74          * memory will be continuous */
    75         if (size > PAGE_SIZE)
    76                 return NULL;
    77         /* Calculate alignment to make sure the block won't cross page
    78          * boundary */
    79         size_t alignment = UHCI_STRCUTURES_ALIGNMENT;
    80         while (alignment < size)
    81                 alignment *= 2;
    82         return memalign(alignment, size);
     74        if (size <= SLAB_ELEMENT_SIZE)
     75                return slab_malloc_g();
     76        assert(false);
     77        return memalign(UHCI_STRCUTURES_ALIGNMENT, size);
    8378}
    8479/*----------------------------------------------------------------------------*/
     
    9085        if (!addr)
    9186                return;
     87        if (slab_in_range_g(addr))
     88                return slab_free_g(addr);
    9289        free(addr);
    9390}
     
    10097{
    10198        void *free_address = as_get_mappable_page(UHCI_REQUIRED_PAGE_SIZE);
     99        assert(free_address); /* TODO: remove this assert */
    102100        if (free_address == 0)
    103101                return NULL;
  • uspace/drv/uhci-rhd/main.c

    r6bfaab5 r88be3a0b  
    3737#include <errno.h>
    3838#include <str_error.h>
    39 
    4039#include <usb_iface.h>
    4140#include <usb/ddfiface.h>
     
    4645#define NAME "uhci-rhd"
    4746
    48 static int hc_get_my_registers(const ddf_dev_t *dev,
     47static int hc_get_my_registers(ddf_dev_t *dev,
    4948    uintptr_t *io_reg_address, size_t *io_reg_size);
    5049/*----------------------------------------------------------------------------*/
     
    131130 */
    132131int hc_get_my_registers(
    133     const ddf_dev_t *dev, uintptr_t *io_reg_address, size_t *io_reg_size)
     132    ddf_dev_t *dev, uintptr_t *io_reg_address, size_t *io_reg_size)
    134133{
    135         assert(dev);
     134        assert(dev != NULL);
    136135
    137         const int parent_phone = devman_parent_device_connect(dev->handle,
     136        int parent_phone = devman_parent_device_connect(dev->handle,
    138137            IPC_FLAG_BLOCKING);
    139138        if (parent_phone < 0) {
     
    142141
    143142        hw_resource_list_t hw_resources;
    144         const int ret = hw_res_get_resource_list(parent_phone, &hw_resources);
     143        int ret = hw_res_get_resource_list(parent_phone, &hw_resources);
    145144        if (ret != EOK) {
    146145                async_hangup(parent_phone);
  • uspace/drv/uhci-rhd/port.c

    r6bfaab5 r88be3a0b  
    3636#include <errno.h>
    3737#include <str_error.h>
     38#include <time.h>
    3839#include <async.h>
    3940
     
    8182 * @param[in] number Port number.
    8283 * @param[in] usec Polling interval.
    83  * @param[in] rh Pointer to ddf instance of the root hub driver.
     84 * @param[in] rh Pointer to ddf instance fo the root hub driver.
    8485 * @return Error code.
    8586 *
     
    9091{
    9192        assert(port);
    92         char *id_string;
    93         asprintf(&id_string, "Port (%p - %u)", port, number);
    94         if (id_string == NULL) {
     93        asprintf(&port->id_string, "Port (%p - %u)", port, number);
     94        if (port->id_string == NULL) {
    9595                return ENOMEM;
    9696        }
    9797
    98         port->id_string = id_string;
    9998        port->address = address;
    10099        port->number = number;
     
    106105            usb_hc_connection_initialize_from_device(&port->hc_connection, rh);
    107106        if (ret != EOK) {
    108                 usb_log_error("%s: failed to initialize connection to HC.",
    109                     port->id_string);
    110                 free(id_string);
     107                usb_log_error("Failed to initialize connection to HC.");
    111108                return ret;
    112109        }
     
    116113                usb_log_error("%s: failed to create polling fibril.",
    117114                    port->id_string);
    118                 free(id_string);
    119115                return ENOMEM;
    120116        }
     
    136132        assert(port);
    137133        free(port->id_string);
    138         // TODO: Kill fibril here
     134        /* TODO: Kill fibril here */
    139135        return;
    140136}
     
    154150
    155151                /* Read register value */
    156                 const port_status_t port_status =
    157                     uhci_port_read_status(instance);
     152                port_status_t port_status = uhci_port_read_status(instance);
    158153
    159154                /* Print the value if it's interesting */
     
    166161                usb_log_debug("%s: Connected change detected: %x.\n",
    167162                    instance->id_string, port_status);
     163
     164                int rc =
     165                    usb_hc_connection_open(&instance->hc_connection);
     166                if (rc != EOK) {
     167                        usb_log_error("%s: Failed to connect to HC.",
     168                            instance->id_string);
     169                        continue;
     170                }
    168171
    169172                /* Remove any old device */
     
    172175                            instance->id_string);
    173176                        uhci_port_remove_device(instance);
    174                 }
    175 
    176                 int ret =
    177                     usb_hc_connection_open(&instance->hc_connection);
    178                 if (ret != EOK) {
    179                         usb_log_error("%s: Failed to connect to HC.",
    180                             instance->id_string);
    181                         continue;
    182177                }
    183178
     
    195190                }
    196191
    197                 ret = usb_hc_connection_close(&instance->hc_connection);
    198                 if (ret != EOK) {
     192                rc = usb_hc_connection_close(&instance->hc_connection);
     193                if (rc != EOK) {
    199194                        usb_log_error("%s: Failed to disconnect.",
    200195                            instance->id_string);
     
    214209int uhci_port_reset_enable(int portno, void *arg)
    215210{
    216         uhci_port_t *port = arg;
    217         assert(port);
     211        uhci_port_t *port = (uhci_port_t *) arg;
    218212
    219213        usb_log_debug2("%s: new_device_enable_port.\n", port->id_string);
     
    233227                while (uhci_port_read_status(port) & STATUS_IN_RESET);
    234228        }
    235         /* PIO delay, should not be longer than 3ms as the device might
    236          * enter suspend state. */
    237229        udelay(10);
    238230        /* Enable the port. */
    239231        uhci_port_set_enabled(port, true);
     232
     233        /* Reset recovery period,
     234         * devices do not have to respond during this period
     235         */
     236        async_usleep(10000);
    240237        return EOK;
    241238}
     
    289286        usb_log_error("%s: Don't know how to remove device %" PRIun ".\n",
    290287            port->id_string, port->attached_device);
    291         port->attached_device = 0;
    292288        return ENOTSUP;
    293289}
  • uspace/drv/uhci-rhd/port.h

    r6bfaab5 r88be3a0b  
    3838#include <fibril.h>
    3939#include <ddf/driver.h>
    40 #include <usb/hc.h> /* usb_hc_connection_t */
     40#include <usb/dev/hc.h> /* usb_hc_connection_t */
    4141
    4242typedef uint16_t port_status_t;
     
    5757typedef struct uhci_port
    5858{
    59         const char *id_string;
     59        char *id_string;
    6060        port_status_t *address;
    6161        unsigned number;
  • uspace/drv/usbhid/Makefile

    r6bfaab5 r88be3a0b  
    5757        generic/hiddev.c \
    5858        mouse/mousedev.c \
    59         multimedia/multimedia.c \
    60         multimedia/keymap.c \
     59        lgtch-ultrax/lgtch-ultrax.c \
     60        lgtch-ultrax/keymap.c \
    6161        $(STOLEN_LAYOUT_SOURCES)
    6262
  • uspace/drv/usbhid/generic/hiddev.c

    r6bfaab5 r88be3a0b  
    6262static size_t usb_generic_hid_get_event_length(ddf_fun_t *fun);
    6363
    64 static int usb_generic_hid_get_event(ddf_fun_t *fun, uint8_t *buffer,
    65     size_t size, size_t *act_size, int *event_nr, unsigned int flags);
     64static int usb_generic_hid_get_event(ddf_fun_t *fun, int32_t *buffer,
     65    size_t size, size_t *act_size, unsigned int flags);
    6666
    6767static int usb_generic_hid_client_connected(ddf_fun_t *fun);
    68 
    69 static size_t usb_generic_get_report_descriptor_length(ddf_fun_t *fun);
    70 
    71 static int usb_generic_get_report_descriptor(ddf_fun_t *fun, uint8_t *desc,
    72     size_t size, size_t *actual_size);
    7368
    7469/*----------------------------------------------------------------------------*/
     
    7671static usbhid_iface_t usb_generic_iface = {
    7772        .get_event = usb_generic_hid_get_event,
    78         .get_event_length = usb_generic_hid_get_event_length,
    79         .get_report_descriptor_length = usb_generic_get_report_descriptor_length,
    80         .get_report_descriptor = usb_generic_get_report_descriptor
     73        .get_event_length = usb_generic_hid_get_event_length
    8174};
    8275
     
    9083static size_t usb_generic_hid_get_event_length(ddf_fun_t *fun)
    9184{
    92         usb_log_debug2("Generic HID: Get event length (fun: %p, "
    93             "fun->driver_data: %p.\n", fun, fun->driver_data);
    94        
    95         if (fun == NULL || fun->driver_data == NULL) {
     85        if (fun == NULL || fun->driver_data) {
    9686                return 0;
    9787        }
     
    9989        usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)fun->driver_data;
    10090       
    101         usb_log_debug2("hid_dev: %p, Max input report size (%d).\n",
    102             hid_dev, hid_dev->max_input_report_size);
    103        
    104         return hid_dev->max_input_report_size;
     91        return hid_dev->input_report_size;
    10592}
    10693
    10794/*----------------------------------------------------------------------------*/
    10895
    109 static int usb_generic_hid_get_event(ddf_fun_t *fun, uint8_t *buffer,
    110     size_t size, size_t *act_size, int *event_nr, unsigned int flags)
     96static int usb_generic_hid_get_event(ddf_fun_t *fun, int32_t *buffer,
     97    size_t size, size_t *act_size, unsigned int flags)
    11198{
    112         usb_log_debug2("Generic HID: Get event.\n");
    113        
    114         if (fun == NULL || fun->driver_data == NULL || buffer == NULL
    115             || act_size == NULL || event_nr == NULL) {
    116                 usb_log_debug("No function");
     99        if (fun == NULL || fun->driver_data) {
    117100                return EINVAL;
    118101        }
     
    121104       
    122105        if (hid_dev->input_report_size > size) {
    123                 usb_log_debug("input_report_size > size (%zu, %zu)\n",
    124                     hid_dev->input_report_size, size);
    125106                return EINVAL;  // TODO: other error code
    126107        }
    127108       
    128109        /*! @todo This should probably be atomic. */
    129 //      if (usb_hid_report_ready()) {
    130 //              usb_log_debug2("Report ready, size: %zu\n",
    131 //                  hid_dev->input_report_size);
    132                
    133 //              usb_hid_report_received();
    134 //      } else {
    135 //              memset(buffer, 0, hid_dev->input_report_size);
    136 //      }
    137         memcpy(buffer, hid_dev->input_report,
    138             hid_dev->input_report_size);
    139         *act_size = hid_dev->input_report_size;
    140         *event_nr = usb_hid_report_number(hid_dev);
     110        if (usb_hid_report_ready()) {
     111                memcpy(buffer, hid_dev->input_report,
     112                    hid_dev->input_report_size);
     113                *act_size = hid_dev->input_report_size;
     114                usb_hid_report_received();
     115        }
    141116       
    142117        // clear the buffer so that it will not be received twice
     
    145120        // note that we already received this report
    146121//      report_received = true;
    147         usb_log_debug2("OK\n");
    148        
    149         return EOK;
    150 }
    151 
    152 /*----------------------------------------------------------------------------*/
    153 
    154 static size_t usb_generic_get_report_descriptor_length(ddf_fun_t *fun)
    155 {
    156         usb_log_debug("Generic HID: Get report descriptor length.\n");
    157        
    158         if (fun == NULL || fun->driver_data == NULL) {
    159                 usb_log_debug("No function");
    160                 return EINVAL;
    161         }
    162        
    163         usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)fun->driver_data;
    164        
    165         usb_log_debug2("hid_dev->report_desc_size = %zu\n",
    166             hid_dev->report_desc_size);
    167        
    168         return hid_dev->report_desc_size;
    169 }
    170 
    171 /*----------------------------------------------------------------------------*/
    172 
    173 static int usb_generic_get_report_descriptor(ddf_fun_t *fun, uint8_t *desc,
    174     size_t size, size_t *actual_size)
    175 {
    176         usb_log_debug2("Generic HID: Get report descriptor.\n");
    177        
    178         if (fun == NULL || fun->driver_data == NULL) {
    179                 usb_log_debug("No function");
    180                 return EINVAL;
    181         }
    182        
    183         usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)fun->driver_data;
    184        
    185         if (hid_dev->report_desc_size > size) {
    186                 return EINVAL;  // TODO: other error code
    187         }
    188        
    189         memcpy(desc, hid_dev->report_desc, hid_dev->report_desc_size);
    190         *actual_size = hid_dev->report_desc_size;
    191122       
    192123        return EOK;
     
    197128static int usb_generic_hid_client_connected(ddf_fun_t *fun)
    198129{
    199         usb_log_debug("Generic HID: Client connected.\n");
     130        usb_hid_report_received();
    200131        return EOK;
    201132}
     
    214145                return ENOMEM;
    215146        }
    216        
    217         fun->ops = &usb_generic_hid_ops;
    218         fun->driver_data = hid_dev;
    219147
    220148        int rc = ddf_fun_bind(fun);
     
    226154        }
    227155       
    228         usb_log_debug("HID function created. Handle: %d\n", fun->handle);
     156        fun->ops = &usb_generic_hid_ops;
     157        fun->driver_data = hid_dev;
    229158       
    230159        return EOK;
     
    233162/*----------------------------------------------------------------------------*/
    234163
    235 int usb_generic_hid_init(usb_hid_dev_t *hid_dev, void **data)
     164int usb_generic_hid_init(usb_hid_dev_t *hid_dev)
    236165{
    237166        if (hid_dev == NULL) {
     
    244173/*----------------------------------------------------------------------------*/
    245174
    246 bool usb_generic_hid_polling_callback(usb_hid_dev_t *hid_dev, void *data,
     175bool usb_generic_hid_polling_callback(usb_hid_dev_t *hid_dev,
    247176    uint8_t *buffer, size_t buffer_size)
    248177{
    249         usb_log_debug2("usb_hid_polling_callback(%p, %p, %zu)\n",
     178        usb_log_debug("usb_hid_polling_callback(%p, %p, %zu)\n",
    250179            hid_dev, buffer, buffer_size);
    251180        usb_debug_str_buffer(buffer, buffer_size, 0);
  • uspace/drv/usbhid/generic/hiddev.h

    r6bfaab5 r88be3a0b  
    4848/*----------------------------------------------------------------------------*/
    4949
    50 int usb_generic_hid_init(struct usb_hid_dev *hid_dev, void **data);
     50int usb_generic_hid_init(struct usb_hid_dev *hid_dev);
    5151
    52 bool usb_generic_hid_polling_callback(struct usb_hid_dev *hid_dev, void *data,
     52bool usb_generic_hid_polling_callback(struct usb_hid_dev *hid_dev,
    5353    uint8_t *buffer, size_t buffer_size);
    5454
  • uspace/drv/usbhid/kbd/kbddev.c

    r6bfaab5 r88be3a0b  
    252252        sysarg_t method = IPC_GET_IMETHOD(*icall);
    253253       
    254         usb_kbd_t *kbd_dev = (usb_kbd_t *)fun->driver_data;
    255         if (kbd_dev == NULL) {
     254        usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)fun->driver_data;
     255       
     256        if (hid_dev == NULL || hid_dev->data == NULL) {
    256257                usb_log_debug("default_connection_handler: "
    257258                    "Missing parameter.\n");
     
    259260                return;
    260261        }
     262       
     263        assert(hid_dev != NULL);
     264        assert(hid_dev->data != NULL);
     265        usb_kbd_t *kbd_dev = (usb_kbd_t *)hid_dev->data;
    261266
    262267        if (method == IPC_M_CONNECT_TO_ME) {
     
    308313        usb_hid_report_field_t *field = usb_hid_report_get_sibling(
    309314            hid_dev->report, NULL, kbd_dev->led_path,
    310             USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY,
     315            USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY | USB_HID_PATH_COMPARE_END,
    311316            USB_HID_REPORT_TYPE_OUTPUT);
    312317       
    313         while (field != NULL) {         
    314                
     318        while (field != NULL) {
     319
    315320                if ((field->usage == USB_HID_LED_NUM_LOCK)
    316321                    && (kbd_dev->mods & KM_NUM_LOCK)){
     
    329334               
    330335                field = usb_hid_report_get_sibling(hid_dev->report, field,
    331                     kbd_dev->led_path, 
    332                 USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY,
    333                         USB_HID_REPORT_TYPE_OUTPUT);
     336                    kbd_dev->led_path, USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY
     337                    | USB_HID_PATH_COMPARE_END, USB_HID_REPORT_TYPE_OUTPUT);
    334338        }
    335339       
     
    658662 *     usb_hid_parse_report().
    659663 */
    660 static void usb_kbd_process_data(usb_hid_dev_t *hid_dev, usb_kbd_t *kbd_dev,
     664static void usb_kbd_process_data(usb_hid_dev_t *hid_dev,
    661665                                 uint8_t *buffer, size_t actual_size)
    662666{
    663667        assert(hid_dev->report != NULL);
    664668        assert(hid_dev != NULL);
    665         assert(kbd_dev != NULL);
     669        assert(hid_dev->data != NULL);
     670       
     671        usb_kbd_t *kbd_dev = (usb_kbd_t *)hid_dev->data;
    666672
    667673        usb_log_debug("Calling usb_hid_parse_report() with "
     
    768774/*----------------------------------------------------------------------------*/
    769775
    770 static int usb_kbd_create_function(usb_hid_dev_t *hid_dev, usb_kbd_t *kbd_dev)
     776static int usb_kbd_create_function(usb_hid_dev_t *hid_dev)
    771777{
    772778        assert(hid_dev != NULL);
    773779        assert(hid_dev->usb_dev != NULL);
    774         assert(kbd_dev != NULL);
    775780       
    776781        /* Create the function exposed under /dev/devices. */
     
    787792         * to the DDF function.
    788793         */
    789         fun->ops = &kbd_dev->ops;
    790         fun->driver_data = kbd_dev;
     794        fun->ops = &hid_dev->ops;
     795        fun->driver_data = hid_dev;   // TODO: maybe change to hid_dev->data
    791796
    792797        int rc = ddf_fun_bind(fun);
     
    797802                return rc;
    798803        }
    799        
    800         usb_log_debug("%s function created. Handle: %d\n", HID_KBD_FUN_NAME,
    801             fun->handle);
    802804       
    803805        usb_log_debug("Adding DDF function to class %s...\n",
     
    838840 * @return Other value inherited from function usbhid_dev_init().
    839841 */
    840 int usb_kbd_init(usb_hid_dev_t *hid_dev, void **data)
     842int usb_kbd_init(usb_hid_dev_t *hid_dev)
    841843{
    842844        usb_log_debug("Initializing HID/KBD structure...\n");
     
    863865        usb_hid_report_path_set_report_id(path, 0);
    864866       
    865         kbd_dev->key_count = usb_hid_report_size(
    866             hid_dev->report, 0, USB_HID_REPORT_TYPE_INPUT);
     867        kbd_dev->key_count = usb_hid_report_input_length(
     868            hid_dev->report, path,
     869            USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY);
    867870        usb_hid_report_path_free(path);
    868871       
     
    905908            kbd_dev->led_path, USB_HIDUT_PAGE_LED, 0);
    906909       
    907         kbd_dev->led_output_size = usb_hid_report_size(hid_dev->report,
    908             0, USB_HID_REPORT_TYPE_OUTPUT);
     910        kbd_dev->led_output_size = usb_hid_report_output_size(hid_dev->report,
     911            kbd_dev->led_path,
     912            USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY);
    909913       
    910914        usb_log_debug("Output report size (in items): %zu\n",
     
    951955       
    952956        // save the KBD device structure into the HID device structure
    953         //hid_dev->data = kbd_dev;
    954         *data = kbd_dev;
     957        hid_dev->data = kbd_dev;
    955958       
    956959        // set handler for incoming calls
    957         kbd_dev->ops.default_handler = default_connection_handler;
     960        hid_dev->ops.default_handler = default_connection_handler;
    958961       
    959962        /*
     
    980983       
    981984        usb_log_debug("Creating KBD function...\n");
    982         int rc = usb_kbd_create_function(hid_dev, kbd_dev);
     985        int rc = usb_kbd_create_function(hid_dev);
    983986        if (rc != EOK) {
    984987                usb_kbd_free(&kbd_dev);
     
    991994/*----------------------------------------------------------------------------*/
    992995
    993 bool usb_kbd_polling_callback(usb_hid_dev_t *hid_dev, void *data,
    994      uint8_t *buffer, size_t buffer_size)
    995 {
    996         if (hid_dev == NULL || buffer == NULL || data == NULL) {
     996bool usb_kbd_polling_callback(usb_hid_dev_t *hid_dev, uint8_t *buffer,
     997     size_t buffer_size)
     998{
     999        if (hid_dev == NULL || buffer == NULL) {
    9971000                // do not continue polling (???)
    9981001                return false;
    9991002        }
    10001003       
    1001         usb_kbd_t *kbd_dev = (usb_kbd_t *)data;
    1002         assert(kbd_dev != NULL);
    1003        
    10041004        // TODO: add return value from this function
    1005         usb_kbd_process_data(hid_dev, kbd_dev, buffer, buffer_size);
     1005        usb_kbd_process_data(hid_dev, buffer, buffer_size);
    10061006       
    10071007        return true;
     
    10661066/*----------------------------------------------------------------------------*/
    10671067
    1068 void usb_kbd_deinit(usb_hid_dev_t *hid_dev, void *data)
     1068void usb_kbd_deinit(usb_hid_dev_t *hid_dev)
    10691069{
    10701070        if (hid_dev == NULL) {
     
    10721072        }
    10731073       
    1074         if (data != NULL) {
    1075                 usb_kbd_t *kbd_dev = (usb_kbd_t *)data;
     1074        if (hid_dev->data != NULL) {
     1075                usb_kbd_t *kbd_dev = (usb_kbd_t *)hid_dev->data;
    10761076                if (usb_kbd_is_initialized(kbd_dev)) {
    10771077                        usb_kbd_mark_unusable(kbd_dev);
    10781078                } else {
    10791079                        usb_kbd_free(&kbd_dev);
     1080                        hid_dev->data = NULL;
    10801081                }
    10811082        }
  • uspace/drv/usbhid/kbd/kbddev.h

    r6bfaab5 r88be3a0b  
    8383        int console_phone;
    8484       
    85         /** @todo What is this actually? */
    86         ddf_dev_ops_t ops;
    87        
    8885        /** Information for auto-repeat of keys. */
    8986        usb_kbd_repeat_t repeat;
     
    120117/*----------------------------------------------------------------------------*/
    121118
    122 int usb_kbd_init(struct usb_hid_dev *hid_dev, void **data);
     119int usb_kbd_init(struct usb_hid_dev *hid_dev);
    123120
    124 bool usb_kbd_polling_callback(struct usb_hid_dev *hid_dev, void *data,
    125                               uint8_t *buffer, size_t buffer_size);
     121bool usb_kbd_polling_callback(struct usb_hid_dev *hid_dev, uint8_t *buffer,
     122    size_t buffer_size);
    126123
    127124int usb_kbd_is_initialized(const usb_kbd_t *kbd_dev);
     
    134131    int type, unsigned int key);
    135132
    136 void usb_kbd_deinit(struct usb_hid_dev *hid_dev, void *data);
     133void usb_kbd_deinit(struct usb_hid_dev *hid_dev);
    137134
    138135int usb_kbd_set_boot_protocol(struct usb_hid_dev *hid_dev);
  • uspace/drv/usbhid/mouse/mousedev.c

    r6bfaab5 r88be3a0b  
    122122        sysarg_t method = IPC_GET_IMETHOD(*icall);
    123123       
    124         usb_mouse_t *mouse_dev = (usb_mouse_t *)fun->driver_data;
    125        
    126         if (mouse_dev == NULL) {
     124        usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)fun->driver_data;
     125       
     126        if (hid_dev == NULL || hid_dev->data == NULL) {
    127127                usb_log_debug("default_connection_handler: Missing "
    128128                    "parameters.\n");
     
    131131        }
    132132       
    133         usb_log_debug("default_connection_handler: fun->name: %s\n",
    134                       fun->name);
    135         usb_log_debug("default_connection_handler: mouse_phone: %d, wheel "
    136             "phone: %d\n", mouse_dev->mouse_phone, mouse_dev->wheel_phone);
     133        assert(hid_dev != NULL);
     134        assert(hid_dev->data != NULL);
     135        usb_mouse_t *mouse_dev = (usb_mouse_t *)hid_dev->data;
    137136       
    138137        int *phone = (str_cmp(fun->name, HID_MOUSE_FUN_NAME) == 0)
     
    146145                            "phone to mouse already set.\n");
    147146                        async_answer_0(icallid, ELIMIT);
     147                        //async_answer_0(icallid, EOK);
    148148                        return;
    149149                }
    150150
    151151                *phone = callback;
    152                 usb_log_debug("Console phone to mouse set ok (%d).\n", *phone);
     152                usb_log_debug("Console phone to mouse set ok (%d).\n", callback);
    153153                async_answer_0(icallid, EOK);
    154154                return;
     
    224224/*----------------------------------------------------------------------------*/
    225225
    226 static bool usb_mouse_process_report(usb_hid_dev_t *hid_dev,
    227                                      usb_mouse_t *mouse_dev, uint8_t *buffer,
    228                                      size_t buffer_size)
    229 {
    230         assert(mouse_dev != NULL);
     226static bool usb_mouse_process_report(usb_hid_dev_t *hid_dev, uint8_t *buffer,
     227    size_t buffer_size)
     228{
     229        usb_mouse_t *mouse_dev = (usb_mouse_t *)hid_dev->data;
    231230       
    232231        usb_log_debug2("got buffer: %s.\n",
     
    234233       
    235234        if (mouse_dev->mouse_phone < 0) {
    236                 usb_log_warning(NAME " No console phone.\n");
    237                 return true;
     235                usb_log_error(NAME " No console phone.\n");
     236                return false;   // ??
    238237        }
    239238
     
    379378/*----------------------------------------------------------------------------*/
    380379
    381 static int usb_mouse_create_function(usb_hid_dev_t *hid_dev, usb_mouse_t *mouse)
    382 {
    383         assert(hid_dev != NULL);
    384         assert(mouse != NULL);
    385        
     380static int usb_mouse_create_function(usb_hid_dev_t *hid_dev)
     381{
    386382        /* Create the function exposed under /dev/devices. */
    387383        usb_log_debug("Creating DDF function %s...\n", HID_MOUSE_FUN_NAME);
     
    393389        }
    394390       
    395         fun->ops = &mouse->ops;
    396         fun->driver_data = mouse;   // TODO: maybe change to hid_dev->data
     391        /*
     392         * Store the initialized HID device and HID ops
     393         * to the DDF function.
     394         */
     395        fun->ops = &hid_dev->ops;
     396        fun->driver_data = hid_dev;   // TODO: maybe change to hid_dev->data
    397397
    398398        int rc = ddf_fun_bind(fun);
     
    431431         * to the DDF function.
    432432         */
    433         fun->ops = &mouse->ops;
    434         fun->driver_data = mouse;   // TODO: maybe change to hid_dev->data
     433        fun->ops = &hid_dev->ops;
     434        fun->driver_data = hid_dev;   // TODO: maybe change to hid_dev->data
    435435
    436436        rc = ddf_fun_bind(fun);
     
    458458/*----------------------------------------------------------------------------*/
    459459
    460 int usb_mouse_init(usb_hid_dev_t *hid_dev, void **data)
     460int usb_mouse_init(usb_hid_dev_t *hid_dev)
    461461{
    462462        usb_log_debug("Initializing HID/Mouse structure...\n");
     
    485485       
    486486        // save the Mouse device structure into the HID device structure
    487         *data = mouse_dev;
     487        hid_dev->data = mouse_dev;
    488488       
    489489        // set handler for incoming calls
    490         // TODO: must be one for each subdriver!!
    491         mouse_dev->ops.default_handler = default_connection_handler;
     490        hid_dev->ops.default_handler = default_connection_handler;
    492491       
    493492        // TODO: how to know if the device supports the request???
     
    495494//          hid_dev->usb_dev->interface_no, IDLE_RATE);
    496495       
    497         int rc = usb_mouse_create_function(hid_dev, mouse_dev);
     496        int rc = usb_mouse_create_function(hid_dev);
    498497        if (rc != EOK) {
    499498                usb_mouse_free(&mouse_dev);
     
    506505/*----------------------------------------------------------------------------*/
    507506
    508 bool usb_mouse_polling_callback(usb_hid_dev_t *hid_dev, void *data,
    509      uint8_t *buffer, size_t buffer_size)
     507bool usb_mouse_polling_callback(usb_hid_dev_t *hid_dev, uint8_t *buffer,
     508     size_t buffer_size)
    510509{
    511510        usb_log_debug("usb_mouse_polling_callback()\n");
    512511        usb_debug_str_buffer(buffer, buffer_size, 0);
    513512       
    514         if (hid_dev == NULL || data == NULL) {
     513        if (hid_dev == NULL) {
    515514                usb_log_error("Missing argument to the mouse polling callback."
    516515                    "\n");
     
    518517        }
    519518       
    520         usb_mouse_t *mouse_dev = (usb_mouse_t *)data;
    521                
    522         return usb_mouse_process_report(hid_dev, mouse_dev, buffer,
    523                                         buffer_size);
    524 }
    525 
    526 /*----------------------------------------------------------------------------*/
    527 
    528 void usb_mouse_deinit(usb_hid_dev_t *hid_dev, void *data)
    529 {
    530         if (data != NULL) {
    531                 usb_mouse_free((usb_mouse_t **)&data);
    532         }
     519        if (hid_dev->data == NULL) {
     520                usb_log_error("Wrong argument to the mouse polling callback."
     521                    "\n");
     522                return false;
     523        }
     524       
     525        return usb_mouse_process_report(hid_dev, buffer, buffer_size);
     526}
     527
     528/*----------------------------------------------------------------------------*/
     529
     530void usb_mouse_deinit(usb_hid_dev_t *hid_dev)
     531{
     532        usb_mouse_free((usb_mouse_t **)&hid_dev->data);
    533533}
    534534
  • uspace/drv/usbhid/mouse/mousedev.h

    r6bfaab5 r88be3a0b  
    5252       
    5353        int32_t *buttons;
    54        
    55         ddf_dev_ops_t ops;
    5654} usb_mouse_t;
    5755
     
    6563/*----------------------------------------------------------------------------*/
    6664
    67 int usb_mouse_init(struct usb_hid_dev *hid_dev, void **data);
     65int usb_mouse_init(struct usb_hid_dev *hid_dev);
    6866
    69 bool usb_mouse_polling_callback(struct usb_hid_dev *hid_dev, void *data,
    70     uint8_t *buffer, size_t buffer_size);
     67bool usb_mouse_polling_callback(struct usb_hid_dev *hid_dev, uint8_t *buffer,
     68    size_t buffer_size);
    7169
    72 void usb_mouse_deinit(struct usb_hid_dev *hid_dev, void *data);
     70void usb_mouse_deinit(struct usb_hid_dev *hid_dev);
    7371
    7472int usb_mouse_set_boot_protocol(struct usb_hid_dev *hid_dev);
  • uspace/drv/usbhid/subdrivers.c

    r6bfaab5 r88be3a0b  
    3838#include <usb/hid/hidpath.h>
    3939
    40 #include "multimedia/multimedia.h"
     40#include "lgtch-ultrax/lgtch-ultrax.h"
    4141#include "mouse/mousedev.h"
    42 #include "generic/hiddev.h"
    4342
    4443static usb_hid_subdriver_usage_t path_kbd[] = {
    45         {USB_HIDUT_PAGE_GENERIC_DESKTOP,
    46          USB_HIDUT_USAGE_GENERIC_DESKTOP_KEYBOARD},
     44        {USB_HIDUT_PAGE_KEYBOARD, 0},
    4745        {0, 0}
    4846};
    4947
    50 static usb_hid_subdriver_usage_t path_mouse[] = {
    51         {USB_HIDUT_PAGE_GENERIC_DESKTOP, USB_HIDUT_USAGE_GENERIC_DESKTOP_MOUSE},
     48static usb_hid_subdriver_usage_t path_mouse2[] = {
     49        {USB_HIDUT_PAGE_GENERIC_DESKTOP, USB_HIDUT_USAGE_GENERIC_DESKTOP_X},
    5250        {0, 0}
    5351};
    5452
    55 static usb_hid_subdriver_usage_t multim_key_path[] = {
    56         {USB_HIDUT_PAGE_CONSUMER, USB_HIDUT_USAGE_CONSUMER_CONSUMER_CONTROL},
     53static usb_hid_subdriver_usage_t lgtch_path[] = {
     54        {0xc, 0},
    5755        {0, 0}
    5856};
    59 
    60 //static usb_hid_subdriver_usage_t generic_hid_key_path[] = {
    61 //      {0, 0}
    62 //};
    6357
    6458const usb_hid_subdriver_mapping_t usb_hid_subdrivers[] = {
    6559        {
    6660                path_kbd,
    67                 0,
    68                 USB_HID_PATH_COMPARE_BEGIN,
     61                -1,
     62                USB_HID_PATH_COMPARE_END
     63                | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY,
    6964                -1,
    7065                -1,
     
    7873        },
    7974        {
    80                 multim_key_path,
     75                lgtch_path,
    8176                1,
    82                 USB_HID_PATH_COMPARE_BEGIN,
    83                 -1,
    84                 -1,
     77                USB_HID_PATH_COMPARE_END
     78                | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY,
     79                0x046d,
     80                0xc30e,
    8581                {
    86                         .init = usb_multimedia_init,
    87                         .deinit = usb_multimedia_deinit,
    88                         .poll = usb_multimedia_polling_callback,
     82                        .init = usb_lgtch_init,
     83                        .deinit = usb_lgtch_deinit,
     84                        .poll = usb_lgtch_polling_callback,
    8985                        .poll_end = NULL
    9086                }
    9187        },
    9288        {
    93                 path_mouse,
    94                 0,
    95                 USB_HID_PATH_COMPARE_BEGIN,
     89                path_mouse2,
     90                -1,
     91                USB_HID_PATH_COMPARE_END
     92                | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY,
    9693                -1,
    9794                -1,
     
    103100                }
    104101        },
    105 //      {
    106 //              generic_hid_key_path,
    107 //              0,
    108 //              USB_HID_PATH_COMPARE_ANYWHERE,
    109 //              -1,
    110 //              -1,
    111 //              {
    112 //                      .init = usb_generic_hid_init,
    113 //                      .deinit = NULL,
    114 //                      .poll = usb_generic_hid_polling_callback,
    115 //                      .poll_end = NULL
    116 //              }
    117 //      },
    118         {NULL, -1, 0, -1, -1, {NULL, NULL, NULL, NULL, NULL}}
     102        {NULL, -1, 0, -1, -1, {NULL, NULL, NULL, NULL}}
    119103};
    120104
  • uspace/drv/usbhid/usbhid.c

    r6bfaab5 r88be3a0b  
    6363static const int USB_HID_MAX_SUBDRIVERS = 10;
    6464
    65 /** @todo What happens if this is not fibril local? */
    66 //static fibril_local bool report_number;
     65static fibril_local bool report_received;
    6766
    6867/*----------------------------------------------------------------------------*/
     
    204203       
    205204        usb_log_debug("Compare flags: %d\n", mapping->compare);
    206 //      size_t size = usb_hid_report_size(hid_dev->report, 0,
    207 //          USB_HID_REPORT_TYPE_INPUT);
    208         size_t size = 0;
    209         usb_hid_report_field_t *field = usb_hid_report_get_sibling (hid_dev->report,
    210                 NULL, usage_path, mapping->compare, USB_HID_REPORT_TYPE_INPUT);
    211         while(field != NULL) {
    212                 size++;
    213                 field = usb_hid_report_get_sibling (hid_dev->report,
    214                                         field, usage_path, mapping->compare,
    215                             USB_HID_REPORT_TYPE_INPUT);
    216         }
    217        
     205        size_t size = usb_hid_report_input_length(hid_dev->report, usage_path,
     206            mapping->compare);
    218207        usb_log_debug("Size of the input report: %zuB\n", size);
     208       
    219209        usb_hid_report_path_free(usage_path);
    220210       
     
    235225        }
    236226       
    237         // add one generic HID subdriver per device
    238        
    239         hid_dev->subdrivers = (usb_hid_subdriver_t *)malloc((count + 1) *
     227        hid_dev->subdrivers = (usb_hid_subdriver_t *)malloc(count *
    240228            sizeof(usb_hid_subdriver_t));
    241229        if (hid_dev->subdrivers == NULL) {
     
    250238        }
    251239       
    252         hid_dev->subdrivers[count].init = usb_generic_hid_init;
    253         hid_dev->subdrivers[count].poll = usb_generic_hid_polling_callback;
    254         hid_dev->subdrivers[count].deinit = NULL;
    255         hid_dev->subdrivers[count].poll_end = NULL;
    256        
    257         hid_dev->subdriver_count = count + 1;
     240        hid_dev->subdriver_count = count;
    258241       
    259242        return EOK;
     
    315298               
    316299                if (matched) {
    317                         usb_log_debug("Subdriver matched.\n");
    318300                        subdrivers[count++] = &mapping->subdriver;
    319301                }
     
    357339/*----------------------------------------------------------------------------*/
    358340
    359 static int usb_hid_init_report(usb_hid_dev_t *hid_dev)
    360 {
    361         assert(hid_dev != NULL && hid_dev->report != NULL);
    362        
    363         uint8_t report_id = 0;
    364         size_t size;/* = usb_hid_report_byte_size(hid_dev->report, report_id,
    365             USB_HID_REPORT_TYPE_INPUT);*/
    366        
    367         size_t max_size = 0;
    368        
    369         do {
    370                 size = usb_hid_report_byte_size(hid_dev->report, report_id,
    371                     USB_HID_REPORT_TYPE_INPUT);
    372                 usb_log_debug("Report ID: %u, size: %zu\n", report_id, size);
    373                 max_size = (size > max_size) ? size : max_size;
    374                 report_id = usb_hid_get_next_report_id(hid_dev->report,
    375                     report_id, USB_HID_REPORT_TYPE_INPUT);
    376         } while (report_id != 0);
    377        
    378         usb_log_debug("Max size of input report: %zu\n", max_size);
    379        
    380         hid_dev->max_input_report_size = max_size;
    381         assert(hid_dev->input_report == NULL);
    382        
    383         hid_dev->input_report = malloc(max_size);
    384         if (hid_dev->input_report == NULL) {
    385                 return ENOMEM;
    386         }
    387         memset(hid_dev->input_report, 0, max_size);
    388        
    389         return EOK;
    390 }
    391 
    392 /*----------------------------------------------------------------------------*/
    393 
    394341usb_hid_dev_t *usb_hid_new(void)
    395342{
     
    446393        /* Get the report descriptor and parse it. */
    447394        rc = usb_hid_process_report_descriptor(hid_dev->usb_dev,
    448             hid_dev->report, &hid_dev->report_desc, &hid_dev->report_desc_size);
     395            hid_dev->report);
    449396       
    450397        bool fallback = false;
     
    510457                        if (hid_dev->subdrivers[i].init != NULL) {
    511458                                usb_log_debug("Initializing subdriver %d.\n",i);
    512                                 rc = hid_dev->subdrivers[i].init(hid_dev,
    513                                     &hid_dev->subdrivers[i].data);
     459                                rc = hid_dev->subdrivers[i].init(hid_dev);
    514460                                if (rc != EOK) {
    515461                                        usb_log_warning("Failed to initialize"
     
    527473        }
    528474       
    529         // save max input report size and allocate space for the report
    530         rc = usb_hid_init_report(hid_dev);
    531         if (rc != EOK) {
    532                 usb_log_error("Failed to initialize input report buffer.\n");
    533         }
    534        
    535475        return rc;
    536476}
     
    550490        usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)arg;
    551491       
    552 //      int allocated = (hid_dev->input_report != NULL);
    553         assert(hid_dev->input_report != NULL);
    554         usb_log_debug("Max input report size: %zu, buffer size: %zu\n",
    555             hid_dev->max_input_report_size, buffer_size);
    556         assert(hid_dev->max_input_report_size >= buffer_size);
    557        
    558 //      if (/*!allocated*/
    559 //          /*|| *//*hid_dev->input_report_size < buffer_size*/) {
    560 //              uint8_t *input_old = hid_dev->input_report;
    561 //              uint8_t *input_new = (uint8_t *)malloc(buffer_size);
    562                
    563 //              if (input_new == NULL) {
    564 //                      usb_log_error("Failed to allocate space for input "
    565 //                          "buffer. This event may not be reported\n");
    566 //                      memset(hid_dev->input_report, 0,
    567 //                          hid_dev->input_report_size);
    568 //              } else {
    569 //                      memcpy(input_new, input_old,
    570 //                          hid_dev->input_report_size);
    571 //                      hid_dev->input_report = input_new;
    572 //                      if (allocated) {
    573 //                              free(input_old);
    574 //                      }
    575 //                      usb_hid_new_report();
    576 //              }
    577 //      }
     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                        usb_hid_new_report();
     512                }
     513        }
    578514       
    579515        /*! @todo This should probably be atomic. */
    580516        memcpy(hid_dev->input_report, buffer, buffer_size);
    581517        hid_dev->input_report_size = buffer_size;
    582         usb_hid_new_report(hid_dev);
    583518       
    584519        bool cont = false;
     
    587522        for (i = 0; i < hid_dev->subdriver_count; ++i) {
    588523                if (hid_dev->subdrivers[i].poll != NULL
    589                     && hid_dev->subdrivers[i].poll(hid_dev,
    590                         hid_dev->subdrivers[i].data, buffer, buffer_size)) {
     524                    && hid_dev->subdrivers[i].poll(hid_dev, buffer,
     525                    buffer_size)) {
    591526                        cont = true;
    592527                }
     
    611546        for (i = 0; i < hid_dev->subdriver_count; ++i) {
    612547                if (hid_dev->subdrivers[i].poll_end != NULL) {
    613                         hid_dev->subdrivers[i].poll_end(hid_dev,
    614                             hid_dev->subdrivers[i].data, reason);
     548                        hid_dev->subdrivers[i].poll_end(hid_dev, reason);
    615549                }
    616550        }
     
    656590/*----------------------------------------------------------------------------*/
    657591
    658 void usb_hid_new_report(usb_hid_dev_t *hid_dev)
    659 {
    660         ++hid_dev->report_nr;
    661 }
    662 
    663 /*----------------------------------------------------------------------------*/
    664 
    665 int usb_hid_report_number(usb_hid_dev_t *hid_dev)
    666 {
    667         return hid_dev->report_nr;
    668 }
    669 
    670 /*----------------------------------------------------------------------------*/
    671 
    672 //void usb_hid_report_received(void)
    673 //{
    674 //      ++report_number;
    675 //}
    676 
    677 /*----------------------------------------------------------------------------*/
    678 
    679 //bool usb_hid_report_ready(void)
    680 //{
    681 //      return !report_received;
    682 //}
     592void usb_hid_new_report(void)
     593{
     594        report_received = false;
     595}
     596
     597/*----------------------------------------------------------------------------*/
     598
     599void usb_hid_report_received(void)
     600{
     601        report_received = true;
     602}
     603
     604/*----------------------------------------------------------------------------*/
     605
     606bool usb_hid_report_ready(void)
     607{
     608        return !report_received;
     609}
    683610
    684611/*----------------------------------------------------------------------------*/
     
    700627        for (i = 0; i < (*hid_dev)->subdriver_count; ++i) {
    701628                if ((*hid_dev)->subdrivers[i].deinit != NULL) {
    702                         (*hid_dev)->subdrivers[i].deinit(*hid_dev,
    703                             (*hid_dev)->subdrivers[i].data);
     629                        (*hid_dev)->subdrivers[i].deinit(*hid_dev);
    704630                }
    705631        }
  • uspace/drv/usbhid/usbhid.h

    r6bfaab5 r88be3a0b  
    4848struct usb_hid_dev;
    4949
    50 typedef int (*usb_hid_driver_init_t)(struct usb_hid_dev *, void **data);
    51 typedef void (*usb_hid_driver_deinit_t)(struct usb_hid_dev *, void *data);
    52 typedef bool (*usb_hid_driver_poll)(struct usb_hid_dev *, void *data, uint8_t *,
    53                                     size_t);
    54 typedef int (*usb_hid_driver_poll_ended)(struct usb_hid_dev *, void *data,
    55                                          bool reason);
     50typedef int (*usb_hid_driver_init_t)(struct usb_hid_dev *);
     51typedef void (*usb_hid_driver_deinit_t)(struct usb_hid_dev *);
     52typedef bool (*usb_hid_driver_poll)(struct usb_hid_dev *, uint8_t *, size_t);
     53typedef int (*usb_hid_driver_poll_ended)(struct usb_hid_dev *, bool reason);
    5654
    5755// TODO: add function and class name??
     
    6563        /** Function to be called when polling ends. */
    6664        usb_hid_driver_poll_ended poll_end;
    67         /** Arbitrary data needed by the subdriver. */
    68         void *data;
    6965} usb_hid_subdriver_t;
    7066
     
    7672        /** Structure holding generic USB device information. */
    7773        usb_device_t *usb_dev;
     74       
     75        /** @todo What is this actually? */
     76        ddf_dev_ops_t ops;
    7877       
    7978        /** Index of the polling pipe in usb_hid_endpoints array. */
     
    9897       
    9998        size_t input_report_size;
    100         size_t max_input_report_size;
    10199       
    102         int report_nr;
     100        /** Arbitrary data (e.g. a special structure for handling keyboard). */
     101        void *data;
    103102} usb_hid_dev_t;
    104103
     
    130129//const char *usb_hid_get_class_name(const usb_hid_dev_t *hid_dev);
    131130
    132 void usb_hid_new_report(usb_hid_dev_t *hid_dev);
     131void usb_hid_new_report(void);
    133132
    134 int usb_hid_report_number(usb_hid_dev_t *hid_dev);
     133void usb_hid_report_received(void);
    135134
    136 //void usb_hid_report_received(void);
    137 
    138 //bool usb_hid_report_ready(void);
     135bool usb_hid_report_ready(void);
    139136
    140137void usb_hid_free(usb_hid_dev_t **hid_dev);
  • uspace/lib/drv/Makefile

    r6bfaab5 r88be3a0b  
    4040        generic/remote_usb.c \
    4141        generic/remote_pci.c \
    42         generic/remote_usbhc.c \
    43         generic/remote_usbhid.c
     42        generic/remote_usbhc.c
    4443
    4544include $(USPACE_PREFIX)/Makefile.common
  • uspace/lib/drv/generic/dev_iface.c

    r6bfaab5 r88be3a0b  
    4646#include "remote_pci.h"
    4747
    48 #include <stdio.h>
    49 
    5048static iface_dipatch_table_t remote_ifaces = {
    5149        .ifaces = {
     
    6260{
    6361        assert(is_valid_iface_idx(idx));
    64        
    6562        return remote_ifaces.ifaces[idx];
    6663}
  • uspace/lib/drv/generic/driver.c

    r6bfaab5 r88be3a0b  
    405405                                /* The interface has not such method */
    406406                                printf("%s: driver_connection_gen error - "
    407                                     "invalid interface method (%d).\n",
    408                                     driver->name, iface_method_idx);
     407                                    "invalid interface method.", driver->name);
    409408                                async_answer_0(callid, ENOTSUP);
    410409                                break;
  • uspace/lib/drv/generic/remote_usbhid.c

    r6bfaab5 r88be3a0b  
    3636#include <errno.h>
    3737#include <assert.h>
    38 #include <stdio.h>
    3938
    4039#include "usbhid_iface.h"
     
    4342static void remote_usbhid_get_event_length(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
    4443static void remote_usbhid_get_event(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
    45 static void remote_usbhid_get_report_descriptor_length(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
    46 static void remote_usbhid_get_report_descriptor(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
    4744// static void remote_usbhid_(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
    4845
     
    5047static remote_iface_func_ptr_t remote_usbhid_iface_ops [] = {
    5148        remote_usbhid_get_event_length,
    52         remote_usbhid_get_event,
    53         remote_usbhid_get_report_descriptor_length,
    54         remote_usbhid_get_report_descriptor
     49        remote_usbhid_get_event
    5550};
    5651
     
    6358};
    6459
    65 //usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     60usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
    6661
    6762
     
    6964    ipc_callid_t callid, ipc_call_t *call)
    7065{
    71         printf("remote_usbhid_get_event_length()\n");
    72        
    7366        usbhid_iface_t *hid_iface = (usbhid_iface_t *) iface;
    7467
    7568        if (!hid_iface->get_event_length) {
    76                 printf("Get event length not set!\n");
    7769                async_answer_0(callid, ENOTSUP);
    7870                return;
    7971        }
    8072
    81         size_t len = hid_iface->get_event_length(fun);
    82 //      if (len == 0) {
    83 //              len = EEMPTY;
    84 //      }
    85         async_answer_1(callid, EOK, len);
    86        
    87 //      if (len < 0) {
    88 //              async_answer_0(callid, len);
    89 //      } else {
    90 //              async_answer_1(callid, EOK, len);
    91 //      }
     73        int len = hid_iface->get_event_length(fun);
     74        if (len == 0) {
     75                len = EEMPTY;
     76        }
     77        if (len < 0) {
     78                async_answer_0(callid, len);
     79        } else {
     80                async_answer_1(callid, EOK, len);
     81        }
    9282}
    9383
     
    110100                return;
    111101        }
    112 //      /* Check that length is even number. Truncate otherwise. */
    113 //      if ((len % 2) == 1) {
    114 //              len--;
    115 //      }
     102        /* Check that length is even number. Truncate otherwise. */
     103        if ((len % 2) == 1) {
     104                len--;
     105        }
    116106        if (len == 0) {
    117107                async_answer_0(data_callid, EINVAL);
    118108                async_answer_0(callid, EINVAL);
    119                 return;
    120109        }
    121110
    122111        int rc;
    123112
    124         uint8_t *data = malloc(len);
    125         if (data == NULL) {
     113        size_t items = len / 2;
     114        uint16_t *usage_pages_and_usages = malloc(sizeof(uint16_t) * len);
     115        if (usage_pages_and_usages == NULL) {
    126116                async_answer_0(data_callid, ENOMEM);
    127117                async_answer_0(callid, ENOMEM);
    128                 return;
    129118        }
    130119
    131         size_t act_length;
    132         int event_nr;
    133         rc = hid_iface->get_event(fun, data, len, &act_length, &event_nr, flags);
     120        size_t act_items;
     121        int rc = hid_iface->get_event(fun, usage_pages_and_usages,
     122            usage_pages_and_usages + items, items, &act_items, flags);
    134123        if (rc != EOK) {
    135                 free(data);
     124                free(usage_pages_and_usages);
    136125                async_answer_0(data_callid, rc);
    137126                async_answer_0(callid, rc);
    138                 return;
    139127        }
    140         if (act_length >= len) {
     128        if (act_items >= items) {
    141129                /* This shall not happen. */
    142130                // FIXME: how about an assert here?
    143                 act_length = len;
     131                act_items = items;
    144132        }
    145133
    146         async_data_read_finalize(data_callid, data, act_length);
     134        async_data_read_finalize(data_callid, usage_pages_and_usages,
     135            act_items * 2 * sizeof(uint16_t));
    147136
    148         free(data);
     137        free(usage_pages_and_usages);
    149138
    150         async_answer_1(callid, EOK, event_nr);
     139        async_answer_0(callid, EOK);
    151140}
    152 
    153 void remote_usbhid_get_report_descriptor_length(ddf_fun_t *fun, void *iface,
    154     ipc_callid_t callid, ipc_call_t *call)
    155 {
    156         usbhid_iface_t *hid_iface = (usbhid_iface_t *) iface;
    157 
    158         if (!hid_iface->get_report_descriptor_length) {
    159                 async_answer_0(callid, ENOTSUP);
    160                 return;
    161         }
    162 
    163         size_t len = hid_iface->get_report_descriptor_length(fun);
    164         async_answer_1(callid, EOK, (sysarg_t) len);
    165 }
    166 
    167 void remote_usbhid_get_report_descriptor(ddf_fun_t *fun, void *iface,
    168     ipc_callid_t callid, ipc_call_t *call)
    169 {
    170         usbhid_iface_t *hid_iface = (usbhid_iface_t *) iface;
    171 
    172         if (!hid_iface->get_report_descriptor) {
    173                 async_answer_0(callid, ENOTSUP);
    174                 return;
    175         }
    176 
    177         size_t len;
    178         ipc_callid_t data_callid;
    179         if (!async_data_read_receive(&data_callid, &len)) {
    180                 async_answer_0(callid, EINVAL);
    181                 return;
    182         }
    183 
    184         if (len == 0) {
    185                 async_answer_0(data_callid, EINVAL);
    186                 async_answer_0(callid, EINVAL);
    187                 return;
    188         }
    189 
    190         uint8_t *descriptor = malloc(len);
    191         if (descriptor == NULL) {
    192                 async_answer_0(data_callid, ENOMEM);
    193                 async_answer_0(callid, ENOMEM);
    194                 return;
    195         }
    196 
    197         size_t act_len = 0;
    198         int rc = hid_iface->get_report_descriptor(fun, descriptor, len,
    199             &act_len);
    200         if (act_len > len) {
    201                 rc = ELIMIT;
    202         }
    203         if (rc != EOK) {
    204                 free(descriptor);
    205                 async_answer_0(data_callid, rc);
    206                 async_answer_0(callid, rc);
    207                 return;
    208         }
    209 
    210         async_data_read_finalize(data_callid, descriptor, act_len);
    211         async_answer_0(callid, EOK);
    212 
    213         free(descriptor);
    214 }
    215 
    216 
    217141
    218142/**
  • uspace/lib/drv/include/remote_usbhid.h

    r6bfaab5 r88be3a0b  
    3636#define LIBDRV_REMOTE_USBHID_H_
    3737
    38 extern remote_iface_t remote_usbhid_iface;
     38remote_iface_t remote_usbhid_iface;
    3939
    4040#endif
  • uspace/lib/drv/include/usbhid_iface.h

    r6bfaab5 r88be3a0b  
    4545         * Parameters: none
    4646         * Answer:
    47          * - Size of one report in bytes.
     47         * - EOK (expected always as long as device support USB HID interface)
     48         * Parameters of the answer:
     49         * - number of items
    4850         */
    4951        IPC_M_USBHID_GET_EVENT_LENGTH,
     
    6163         * It is okay if the client requests less data. Extra data must
    6264         * be truncated by the driver.
    63          *
    64          * @todo Change this comment.
    6565         */
    66         IPC_M_USBHID_GET_EVENT,
    67        
    68         /** Get the size of the report descriptor from the HID device.
    69          *
    70          * Parameters:
    71          * - none
    72          * Answer:
    73          * - EOK - method is implemented (expected always)
    74          * Parameters of the answer:
    75          * - Size of the report in bytes.
    76          */
    77         IPC_M_USBHID_GET_REPORT_DESCRIPTOR_LENGTH,
    78        
    79         /** Get the report descriptor from the HID device.
    80          *
    81          * Parameters:
    82          * - none
    83          * The call is followed by data read expecting the descriptor itself.
    84          * Answer:
    85          * - EOK - report descriptor returned.
    86          */
    87         IPC_M_USBHID_GET_REPORT_DESCRIPTOR
     66        IPC_M_USBHID_GET_EVENT
    8867} usbhid_iface_funcs_t;
    8968
     
    9675         *
    9776         * @param[in] fun DDF function answering the request.
    98          * @return Size of the event in bytes.
     77         * @return Number of events or error code.
    9978         */
    10079        size_t (*get_event_length)(ddf_fun_t *fun);
     
    10887         * @return Error code.
    10988         */
    110         int (*get_event)(ddf_fun_t *fun, uint8_t *buffer, size_t size,
    111             size_t *act_size, int *event_nr, unsigned int flags);
    112        
    113         /** Get size of the report descriptor in bytes.
    114          *
    115          * @param[in] fun DDF function answering the request.
    116          * @return Size of the report descriptor in bytes.
    117          */
    118         size_t (*get_report_descriptor_length)(ddf_fun_t *fun);
    119        
    120         /** Get the report descriptor from the HID device.
    121          *
    122          * @param[in] fun DDF function answering the request.
    123          * @param[out] desc Buffer with the report descriptor.
    124          * @param[in] size Size of the allocated @p desc buffer.
    125          * @param[out] act_size Actual size of the report descriptor returned.
    126          * @return Error code.
    127          */
    128         int (*get_report_descriptor)(ddf_fun_t *fun, uint8_t *desc,
    129             size_t size, size_t *act_size);
     89        int (*get_event)(ddf_fun_t *fun, int32_t *buffer, size_t size,
     90            size_t *act_size, unsigned int flags);
    13091} usbhid_iface_t;
    13192
  • uspace/lib/usb/Makefile

    r6bfaab5 r88be3a0b  
    3737        src/ddfiface.c \
    3838        src/debug.c \
     39        src/driver.c \
    3940        src/dump.c \
    40         src/hc.c \
    41         src/resolve.c \
     41        src/host.c \
    4242        src/usb.c
    4343
  • uspace/lib/usb/src/ddfiface.c

    r6bfaab5 r88be3a0b  
    3737#include <async.h>
    3838#include <usb/ddfiface.h>
    39 #include <usb/hc.h>
     39#include <usb/driver.h>
    4040#include <usb/debug.h>
    4141#include <errno.h>
  • uspace/lib/usbdev/Makefile

    r6bfaab5 r88be3a0b  
    4646        src/pipesio.c \
    4747        src/recognise.c \
    48         src/request.c
     48        src/request.c \
     49        src/usbdevice.c
    4950
    5051include $(USPACE_PREFIX)/Makefile.common
  • uspace/lib/usbdev/include/usb/dev/hub.h

    r6bfaab5 r88be3a0b  
    3939
    4040#include <sys/types.h>
    41 #include <usb/hc.h>
     41#include <usb/dev/hc.h>
    4242
    4343int usb_hc_new_device_wrapper(ddf_dev_t *, usb_hc_connection_t *, usb_speed_t,
     
    6363    const usb_hc_attached_device_t *);
    6464int usb_hc_unregister_device(usb_hc_connection_t *, usb_address_t);
     65int usb_hc_get_handle_by_address(usb_hc_connection_t *, usb_address_t,
     66    devman_handle_t *);
    6567
    6668#endif
  • uspace/lib/usbdev/include/usb/dev/pipes.h

    r6bfaab5 r88be3a0b  
    3838#include <sys/types.h>
    3939#include <usb/usb.h>
    40 #include <usb/hc.h>
     40#include <usb/dev/hc.h>
    4141#include <usb/descriptor.h>
    4242#include <ipc/devman.h>
     
    163163
    164164int usb_device_get_assigned_interface(ddf_dev_t *);
     165usb_address_t usb_device_get_assigned_address(devman_handle_t);
    165166
    166167int usb_pipe_initialize(usb_pipe_t *, usb_device_connection_t *,
  • uspace/lib/usbdev/src/hub.c

    r6bfaab5 r88be3a0b  
    4141#include <assert.h>
    4242#include <usb/debug.h>
    43 #include <time.h>
    4443
    4544/** How much time to wait between attempts to register endpoint 0:0.
     
    120119}
    121120
     121/** Get handle of USB device with given address.
     122 *
     123 * @param[in] connection Opened connection to host controller.
     124 * @param[in] address Address of device in question.
     125 * @param[out] handle Where to write the device handle.
     126 * @return Error code.
     127 */
     128int usb_hc_get_handle_by_address(usb_hc_connection_t *connection,
     129    usb_address_t address, devman_handle_t *handle)
     130{
     131        CHECK_CONNECTION(connection);
     132
     133        sysarg_t tmp;
     134        int rc = async_req_2_1(connection->hc_phone,
     135            DEV_IFACE_ID(USBHC_DEV_IFACE),
     136            IPC_M_USBHC_GET_HANDLE_BY_ADDRESS,
     137            address, &tmp);
     138        if ((rc == EOK) && (handle != NULL)) {
     139                *handle = tmp;
     140        }
     141
     142        return rc;
     143}
    122144
    123145static void unregister_control_endpoint_on_default_address(
     
    196218
    197219        int rc;
    198         struct timeval start_time;
    199 
    200         rc = gettimeofday(&start_time, NULL);
    201         if (rc != EOK) {
    202                 return rc;
    203         }
    204220
    205221        rc = usb_hc_connection_open(&hc_conn);
     
    248264                }
    249265        } while (rc != EOK);
    250         struct timeval end_time;
    251 
    252         rc = gettimeofday(&end_time, NULL);
    253         if (rc != EOK) {
    254                 goto leave_release_default_address;
    255         }
    256 
    257         /* According to the USB spec part 9.1.2 host allows 100ms time for
    258          * the insertion process to complete. According to 7.1.7.1 this is the
    259          * time between attach detected and port reset. However, the setup done
    260          * above might use much of this time so we should only wait to fill
    261          * up the 100ms quota*/
    262         suseconds_t elapsed = tv_sub(&end_time, &start_time);
    263         if (elapsed < 100000) {
    264                 async_usleep(100000 - elapsed);
    265         }
    266266
    267267        /*
     
    273273                goto leave_release_default_address;
    274274        }
    275         /* USB spec 7.1.7.1: The USB System Software guarantees a minimum of
    276          * 10ms for reset recovery. Device response to any bus transactions
    277          * addressed to the default device address during the reset recovery
    278          * time is undefined.
    279          */
    280         async_usleep(10000);
    281275
    282276        rc = usb_pipe_probe_default_control(&ctrl_pipe);
  • uspace/lib/usbdev/src/pipes.c

    r6bfaab5 r88be3a0b  
    3636#include <usb/dev/pipes.h>
    3737#include <usb/debug.h>
    38 #include <usb/hc.h>
     38#include <usb/driver.h>
    3939#include <usbhc_iface.h>
    4040#include <usb_iface.h>
     
    9797
    9898        return (int) iface_no;
     99}
     100
     101/** Tell USB address assigned to given device.
     102 *
     103 * @param dev_handle Devman handle of the USB device in question.
     104 * @return USB address or negative error code.
     105 */
     106usb_address_t usb_device_get_assigned_address(devman_handle_t dev_handle)
     107{
     108        int parent_phone = devman_parent_device_connect(dev_handle,
     109            IPC_FLAG_BLOCKING);
     110        if (parent_phone < 0) {
     111                return parent_phone;
     112        }
     113
     114        sysarg_t address;
     115
     116        int rc = async_req_2_1(parent_phone, DEV_IFACE_ID(USB_DEV_IFACE),
     117            IPC_M_USB_GET_ADDRESS,
     118            dev_handle, &address);
     119
     120        if (rc != EOK) {
     121                return rc;
     122        }
     123
     124        async_hangup(parent_phone);
     125
     126        return (usb_address_t) address;
    99127}
    100128
  • uspace/lib/usbhid/Makefile

    r6bfaab5 r88be3a0b  
    4141        src/hidpath.c \
    4242        src/hidreport.c \
    43         src/consumer.c \
    4443        src/hidreq.c
    4544
  • uspace/lib/usbhid/include/usb/hid/hid_report_items.h

    r6bfaab5 r88be3a0b  
    2727 */
    2828
    29 /** @addtogroup libusb
     29/** @addtogroup libusbhid
    3030 * @{
    3131 */
    3232/** @file
    33  * @brief USB HID Report descriptor item tags.
     33 * @brief USB HID parser.
    3434 */
    35 #ifndef LIBUSB_HID_REPORT_ITEMS_H_
    36 #define LIBUSB_HID_REPORT_ITEMS_H_
     35#ifndef LIBUSBHID_HID_REPORT_ITEMS_H_
     36#define LIBUSBHID_HID_REPORT_ITEMS_H_
    3737
    3838#include <stdint.h>
    3939
    40 /*---------------------------------------------------------------------------*/
    41 /*
     40/**
    4241 * Item prefix
    4342 */
    44 
    45 /** Returns size of item data in bytes */
    4643#define USB_HID_ITEM_SIZE(data)         ((uint8_t)(data & 0x3))
    47 
    48 /** Returns item tag */
    4944#define USB_HID_ITEM_TAG(data)          ((uint8_t)((data & 0xF0) >> 4))
    50 
    51 /** Returns class of item tag */
    5245#define USB_HID_ITEM_TAG_CLASS(data)    ((uint8_t)((data & 0xC) >> 2))
    53 
    54 /** Returns if the item is the short item or long item. Long items are not
    55  * supported. */
    5646#define USB_HID_ITEM_IS_LONG(data)      (data == 0xFE)
    5747
    58 /*---------------------------------------------------------------------------*/
    59 /*
    60  * Extended usage macros
    61  */
    6248
    63 /** Recognizes if the given usage is extended (contains also usage page).  */
    64 #define USB_HID_IS_EXTENDED_USAGE(usage)        ((usage & 0xFFFF0000) != 0)
    65 
    66 /** Cuts usage page of the extended usage. */
    67 #define USB_HID_EXTENDED_USAGE_PAGE(usage)      ((usage & 0xFFFF0000) >> 16)
    68 
    69 /** Cuts usage of the extended usage */
    70 #define USB_HID_EXTENDED_USAGE(usage)           (usage & 0xFFFF)
    71 
    72 /*---------------------------------------------------------------------------*/
    73 /*
     49/**
    7450 * Input/Output/Feature Item flags
    7551 */
    76 /**
    77  * Indicates whether the item is data (0) or a constant (1) value. Data
    78  * indicates the item is defining report fields that contain modifiable device
    79  * data. Constant indicates the item is a static read-only field in a report
    80  * and cannot be modified (written) by the host.
    81  */
     52/** Constant (1) / Variable (0) */
    8253#define USB_HID_ITEM_FLAG_CONSTANT(flags)       ((flags & 0x1) == 0x1)
    83 
    84 /**
    85  * Indicates whether the item creates variable (1) or array (0) data fields in
    86  * reports.
    87  */
     54/** Variable (1) / Array (0) */
    8855#define USB_HID_ITEM_FLAG_VARIABLE(flags)       ((flags & 0x2) == 0x2)
    89 
    90 /**
    91  * Indicates whether the data is absolute (0) (based on a fixed origin) or
    92  * relative (1) (indicating the change in value from the last report). Mouse
    93  * devices usually provide relative data, while tablets usually provide
    94  * absolute data.
    95  */
     56/** Absolute / Relative*/
    9657#define USB_HID_ITEM_FLAG_RELATIVE(flags)       ((flags & 0x4) == 0x4)
    97 
    98 /** Indicates whether the data “rolls over” when reaching either the extreme
    99  * high or low value. For example, a dial that can spin freely 360 degrees
    100  * might output values from 0 to 10. If Wrap is indicated, the next value
    101  * reported after passing the 10 position in the increasing direction would be
    102  * 0.
    103  */
     58/** Wrap / No Wrap */
    10459#define USB_HID_ITEM_FLAG_WRAP(flags)           ((flags & 0x8) == 0x8)
    105 
    106 /**
    107  * Indicates whether the raw data from the device has been processed in some
    108  * way, and no longer represents a linear relationship between what is
    109  * measured and the data that is reported.
    110  */
    11160#define USB_HID_ITEM_FLAG_LINEAR(flags)         ((flags & 0x10) == 0x10)
    112 
    113 /**
    114  * Indicates whether the control has a preferred state to which it will return
    115  * when the user is not physically interacting with the control. Push buttons
    116  * (as opposed to toggle buttons) and self- centering joysticks are examples.
    117  */
    11861#define USB_HID_ITEM_FLAG_PREFERRED(flags)      ((flags & 0x20) == 0x20)
    119 
    120 /**
    121  * Indicates whether the control has a state in which it is not sending
    122  * meaningful data. One possible use of the null state is for controls that
    123  * require the user to physically interact with the control in order for it to
    124  * report useful data.
    125  */
    12662#define USB_HID_ITEM_FLAG_POSITION(flags)       ((flags & 0x40) == 0x40)
    127 
    128 /**
    129  * Indicates whether the Feature or Output control's value should be changed
    130  * by the host or not.  Volatile output can change with or without host
    131  * interaction. To avoid synchronization problems, volatile controls should be
    132  * relative whenever possible.
    133  */
    13463#define USB_HID_ITEM_FLAG_VOLATILE(flags)       ((flags & 0x80) == 0x80)
    135 
    136 /**
    137  * Indicates that the control emits a fixed-size stream of bytes. The contents
    138  * of the data field are determined by the application. The contents of the
    139  * buffer are not interpreted as a single numeric quantity. Report data
    140  * defined by a Buffered Bytes item must be aligned on an 8-bit boundary.
    141  */
    14264#define USB_HID_ITEM_FLAG_BUFFERED(flags)       ((flags & 0x100) == 0x100)
    14365
    144 /*---------------------------------------------------------------------------*/
    145 
    14666/* MAIN ITEMS */
    147 
    148 /**
    149  * Main items are used to either define or group certain types of data fields
    150  * within a Report descriptor.
    151  */
    152 #define USB_HID_TAG_CLASS_MAIN                  0x0
    153 
    154 /**
    155  * An Input item describes information about the data provided by one or more
    156  * physical controls. An application can use this information to interpret the
    157  * data provided by the device. All data fields defined in a single item share
    158  * an identical data format.
    159  */
    160 #define USB_HID_REPORT_TAG_INPUT                0x8
    161 
    162 /**
    163  * The Output item is used to define an output data field in a report. This
    164  * item is similar to an Input item except it describes data sent to the
    165  * device—for example, LED states.
    166  */
    167 #define USB_HID_REPORT_TAG_OUTPUT               0x9
    168 
    169 /**
    170  * Feature items describe device configuration information that can be sent to
    171  * the device.
    172  */
    173 #define USB_HID_REPORT_TAG_FEATURE              0xB
    174 
    175 /**
    176  * A Collection item identifies a relationship between two or more data
    177  * (Input, Output, or Feature.)
    178  */
     67#define USB_HID_TAG_CLASS_MAIN                          0x0
     68#define USB_HID_REPORT_TAG_INPUT                        0x8
     69#define USB_HID_REPORT_TAG_OUTPUT                       0x9
     70#define USB_HID_REPORT_TAG_FEATURE                      0xB
    17971#define USB_HID_REPORT_TAG_COLLECTION           0xA
    180 
    181 /**
    182  * While the Collection item opens a collection of data, the End Collection
    183  * item closes a collection.
    184  */
    18572#define USB_HID_REPORT_TAG_END_COLLECTION       0xC
    18673
    187 /*---------------------------------------------------------------------------*/
     74/* GLOBAL ITEMS */
     75#define USB_HID_TAG_CLASS_GLOBAL                        0x1
     76#define USB_HID_REPORT_TAG_USAGE_PAGE           0x0
     77#define USB_HID_REPORT_TAG_LOGICAL_MINIMUM      0x1
     78#define USB_HID_REPORT_TAG_LOGICAL_MAXIMUM      0x2
     79#define USB_HID_REPORT_TAG_PHYSICAL_MINIMUM 0x3
     80#define USB_HID_REPORT_TAG_PHYSICAL_MAXIMUM 0x4
     81#define USB_HID_REPORT_TAG_UNIT_EXPONENT        0x5
     82#define USB_HID_REPORT_TAG_UNIT                         0x6
     83#define USB_HID_REPORT_TAG_REPORT_SIZE          0x7
     84#define USB_HID_REPORT_TAG_REPORT_ID            0x8
     85#define USB_HID_REPORT_TAG_REPORT_COUNT         0x9
     86#define USB_HID_REPORT_TAG_PUSH                         0xA
     87#define USB_HID_REPORT_TAG_POP                          0xB
    18888
    189 /* GLOBAL ITEMS */
    190 
    191 /**
    192  * Global items describe rather than define data from a control.
    193  */
    194 #define USB_HID_TAG_CLASS_GLOBAL                0x1
    195 
    196 /**
    197  * Unsigned integer specifying the current Usage Page. Since a usage are 32
    198  * bit values, Usage Page items can be used to conserve space in a report
    199  * descriptor by setting the high order 16 bits of a subsequent usages. Any
    200  * usage that follows which is defines 16 bits or less is interpreted as a
    201  * Usage ID and concatenated with the Usage Page to form a 32 bit Usage.
    202  */
    203 #define USB_HID_REPORT_TAG_USAGE_PAGE           0x0
    204 
    205 /**
    206  * Extent value in logical units. This is the minimum value that a variable
    207  * or array item will report. For example, a mouse reporting x position values
    208  * from 0 to 128 would have a Logical Minimum of 0 and a Logical Maximum of
    209  * 128.
    210  */
    211 #define USB_HID_REPORT_TAG_LOGICAL_MINIMUM      0x1
    212 
    213 /**
    214  * Extent value in logical units. This is the maximum value that a variable
    215  * or array item will report.
    216  */
    217 #define USB_HID_REPORT_TAG_LOGICAL_MAXIMUM      0x2
    218 
    219 /**
    220  * Minimum value for the physical extent of a variable item. This represents
    221  * the Logical Minimum with units applied to it.
    222  */
    223 #define USB_HID_REPORT_TAG_PHYSICAL_MINIMUM     0x3
    224 
    225 /**
    226  * Maximum value for the physical extent of a variable item.
    227  */
    228 #define USB_HID_REPORT_TAG_PHYSICAL_MAXIMUM     0x4
    229 
    230 /**
    231  * Value of the unit exponent in base 10. See the table later in this section
    232  * for more information.
    233  */
    234 #define USB_HID_REPORT_TAG_UNIT_EXPONENT        0x5
    235 
    236 /**
    237  * Unit values.
    238  */
    239 #define USB_HID_REPORT_TAG_UNIT                 0x6
    240 
    241 /**
    242  * Unsigned integer specifying the size of the report fields in bits. This
    243  * allows the parser to build an item map for the report handler to use.
    244  */
    245 #define USB_HID_REPORT_TAG_REPORT_SIZE          0x7
    246 
    247 /**
    248  * Unsigned value that specifies the Report ID. If a Report ID tag is used
    249  * anywhere in Report descriptor, all data reports for the device are preceded
    250  * by a single byte ID field. All items succeeding the first Report ID tag but
    251  * preceding a second Report ID tag are included in a report prefixed by a
    252  * 1-byte ID. All items succeeding the second but preceding a third Report ID
    253  * tag are included in a second report prefixed by a second ID, and so on.
    254  */
    255 #define USB_HID_REPORT_TAG_REPORT_ID            0x8
    256 
    257 /**
    258  * Unsigned integer specifying the number of data fields for the item;
    259  * determines how many fields are included in the report for this particular
    260  * item (and consequently how many bits are added to the report).
    261  */
    262 #define USB_HID_REPORT_TAG_REPORT_COUNT         0x9
    263 
    264 /**
    265  * Places a copy of the global item state table on the stack.
    266  */
    267 #define USB_HID_REPORT_TAG_PUSH                 0xA
    268 
    269 /**
    270  * Replaces the item state table with the top structure from the stack.
    271  */
    272 #define USB_HID_REPORT_TAG_POP                  0xB
    273 
    274 /*---------------------------------------------------------------------------*/
    27589
    27690/* LOCAL ITEMS */
    277 
    278 /**
    279  * Local item tags define characteristics of controls. These items do not
    280  * carry over to the next Main item. If a Main item defines more than one
    281  * control, it may be preceded by several similar Local item tags. For
    282  * example, an Input item may have several Usage tags associated with it, one
    283  * for each control.
    284  */
    285 #define USB_HID_TAG_CLASS_LOCAL                 0x2
    286 
    287 /**
    288  * Usage index for an item usage; represents a suggested usage for the item or
    289  * collection. In the case where an item represents multiple controls, a Usage
    290  * tag may suggest a usage for every variable or element in an array.
    291  */
    292 #define USB_HID_REPORT_TAG_USAGE                0x0
    293 
    294 /**
    295  * Defines the starting usage associated with an array or bitmap.
    296  */
    297 #define USB_HID_REPORT_TAG_USAGE_MINIMUM        0x1
    298 
    299 /**
    300  * Defines the ending usage associated with an array or bitmap.
    301  */
    302 #define USB_HID_REPORT_TAG_USAGE_MAXIMUM        0x2
    303 
    304 /**
    305  * Determines the body part used for a control. Index points to a designator
    306  * in the Physical descriptor.
    307  */
    308 #define USB_HID_REPORT_TAG_DESIGNATOR_INDEX     0x3
    309 
    310 /**
    311  * Defines the index of the starting designator associated with an array or
    312  * bitmap.
    313  */
     91#define USB_HID_TAG_CLASS_LOCAL                                 0x2
     92#define USB_HID_REPORT_TAG_USAGE                                0x0
     93#define USB_HID_REPORT_TAG_USAGE_MINIMUM                0x1
     94#define USB_HID_REPORT_TAG_USAGE_MAXIMUM                0x2
     95#define USB_HID_REPORT_TAG_DESIGNATOR_INDEX             0x3
    31496#define USB_HID_REPORT_TAG_DESIGNATOR_MINIMUM   0x4
    315 
    316 /**
    317  * Defines the index of the ending designator associated with an array or
    318  * bitmap.
    319  */
    32097#define USB_HID_REPORT_TAG_DESIGNATOR_MAXIMUM   0x5
    321 
    322 /**
    323  * String index for a String descriptor; allows a string to be associated with
    324  * a particular item or control.
    325  */
    326 #define USB_HID_REPORT_TAG_STRING_INDEX         0x7
    327 
    328 /**
    329  * Specifies the first string index when assigning a group of sequential
    330  * strings to controls in an array or bitmap.
    331  */
    332 #define USB_HID_REPORT_TAG_STRING_MINIMUM       0x8
    333 
    334 /**
    335  * Specifies the last string index when assigning a group of sequential
    336  * strings to controls in an array or bitmap.
    337  */
    338 #define USB_HID_REPORT_TAG_STRING_MAXIMUM       0x9
    339 
    340 /**
    341  * Defines the beginning or end of a set of local items (1 = open set, 0 =
    342  * close set).
    343  *
    344  * Usages other than the first (most preferred) usage defined are not
    345  * accessible by system software.
    346  */
    347 #define USB_HID_REPORT_TAG_DELIMITER            0xA
    348 
    349 /*---------------------------------------------------------------------------*/
     98#define USB_HID_REPORT_TAG_STRING_INDEX                 0x7
     99#define USB_HID_REPORT_TAG_STRING_MINIMUM               0x8
     100#define USB_HID_REPORT_TAG_STRING_MAXIMUM               0x9
     101#define USB_HID_REPORT_TAG_DELIMITER                    0xA
    350102
    351103#endif
  • uspace/lib/usbhid/include/usb/hid/hiddescriptor.h

    r6bfaab5 r88be3a0b  
    2727 */
    2828
    29 /** @addtogroup libusb
     29/** @addtogroup libusbhid
    3030 * @{
    3131 */
     
    3333 * USB HID report descriptor and report data parser
    3434 */
    35 #ifndef LIBUSB_HIDDESCRIPTOR_H_
    36 #define LIBUSB_HIDDESCRIPTOR_H_
     35#ifndef LIBUSBHID_HIDDESCRIPTOR_H_
     36#define LIBUSBHID_HIDDESCRIPTOR_H_
    3737
    3838#include <stdint.h>
     
    4242#include <usb/hid/hidtypes.h>
    4343
     44
     45/*
     46 * Descriptor parser functions
     47 */
     48
     49/** */
    4450int usb_hid_parse_report_descriptor(usb_hid_report_t *report,
    45                 const uint8_t *data, size_t size);
     51                                    const uint8_t *data, size_t size);
    4652
     53/** */
    4754void usb_hid_free_report(usb_hid_report_t *report);
    4855
     56/** */
    4957void usb_hid_descriptor_print(usb_hid_report_t *report);
    5058
     59
    5160int usb_hid_report_init(usb_hid_report_t *report);
     61int usb_hid_report_append_fields(usb_hid_report_t *report,
     62                                 usb_hid_report_item_t *report_item);
    5263
    53 int usb_hid_report_append_fields(usb_hid_report_t *report,
    54                 usb_hid_report_item_t *report_item);
    55 
    56 usb_hid_report_description_t * usb_hid_report_find_description(
    57                 const usb_hid_report_t *report, uint8_t report_id,
    58                 usb_hid_report_type_t type);
    59 
    60 int usb_hid_report_parse_tag(uint8_t tag, uint8_t class, const uint8_t *data,
    61                 size_t item_size, usb_hid_report_item_t *report_item,
    62                 usb_hid_report_path_t *usage_path);
    63 
    64 int usb_hid_report_parse_main_tag(uint8_t tag, const uint8_t *data,
    65                 size_t item_size, usb_hid_report_item_t *report_item,
    66                 usb_hid_report_path_t *usage_path);
    67 
    68 int usb_hid_report_parse_global_tag(uint8_t tag, const uint8_t *data,
    69                 size_t item_size, usb_hid_report_item_t *report_item,
    70                 usb_hid_report_path_t *usage_path);
    71 
    72 int usb_hid_report_parse_local_tag(uint8_t tag, const uint8_t *data,
    73                 size_t item_size, usb_hid_report_item_t *report_item,
    74                 usb_hid_report_path_t *usage_path);
     64usb_hid_report_description_t * usb_hid_report_find_description(const usb_hid_report_t *report, uint8_t report_id, usb_hid_report_type_t type);
     65int usb_hid_report_parse_tag(uint8_t tag, uint8_t class, const uint8_t *data, size_t item_size,
     66                             usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path);
     67int usb_hid_report_parse_main_tag(uint8_t tag, const uint8_t *data, size_t item_size,
     68                             usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path);
     69int usb_hid_report_parse_global_tag(uint8_t tag, const uint8_t *data, size_t item_size,
     70                             usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path);
     71int usb_hid_report_parse_local_tag(uint8_t tag, const uint8_t *data, size_t item_size,
     72                             usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path);
    7573
    7674void usb_hid_descriptor_print_list(link_t *head);
    77 
    7875void usb_hid_report_reset_local_items(usb_hid_report_item_t *report_item);
    79 
    8076void usb_hid_free_report_list(link_t *head);
    81 
    82 usb_hid_report_item_t *usb_hid_report_item_clone(
    83                 const usb_hid_report_item_t *item);
    84 
     77usb_hid_report_item_t *usb_hid_report_item_clone(const usb_hid_report_item_t *item);
    8578uint32_t usb_hid_report_tag_data_uint32(const uint8_t *data, size_t size);
    8679
    87 usb_hid_report_path_t *usb_hid_report_path_try_insert(usb_hid_report_t*report,
    88                 usb_hid_report_path_t *cmp_path);
    89 
    90 
     80usb_hid_report_path_t *usb_hid_report_path_try_insert(usb_hid_report_t *report, usb_hid_report_path_t *cmp_path);
    9181#endif
    9282/**
  • uspace/lib/usbhid/include/usb/hid/hidparser.h

    r6bfaab5 r88be3a0b  
    4747 * Input report parser functions
    4848 */
    49 int usb_hid_parse_report(const usb_hid_report_t *report, const uint8_t *data,
    50                 size_t size, uint8_t *report_id);
     49/** */
     50int usb_hid_parse_report(const usb_hid_report_t *report, const uint8_t *data,
     51                         size_t size, uint8_t *report_id);
     52
     53/** */
     54size_t usb_hid_report_input_length(const usb_hid_report_t *report,
     55        usb_hid_report_path_t *path, int flags);
    5156
    5257/*
    5358 * Output report parser functions
    5459 */
     60/** Allocates output report buffer*/
    5561uint8_t *usb_hid_report_output(usb_hid_report_t *report, size_t *size,
    56                 uint8_t report_id);
     62                               uint8_t report_id);
    5763
     64/** Frees output report buffer*/
    5865void usb_hid_report_output_free(uint8_t *output);
    5966
    60 size_t usb_hid_report_size(usb_hid_report_t *report, uint8_t report_id,
    61                 usb_hid_report_type_t type);
     67/** Returns size of output for given usage path */
     68size_t usb_hid_report_output_size(usb_hid_report_t *report,
     69                                  usb_hid_report_path_t *path, int flags);
    6270
    63 size_t usb_hid_report_byte_size(usb_hid_report_t *report, uint8_t report_id,
    64                 usb_hid_report_type_t type);
     71/** Makes the output report buffer by translated given data */
     72int usb_hid_report_output_translate(usb_hid_report_t *report, uint8_t report_id,
     73                                    uint8_t *buffer, size_t size);
    6574
     75/** */
     76usb_hid_report_field_t *usb_hid_report_get_sibling(usb_hid_report_t *report,
     77                                                   usb_hid_report_field_t *field,
     78                                                   usb_hid_report_path_t *path,
     79                                                   int flags,
     80                                                   usb_hid_report_type_t type);
    6681
    67 int usb_hid_report_output_translate(usb_hid_report_t *report,
    68                 uint8_t report_id, uint8_t *buffer, size_t size);
    69 
    70 
    71 /*
    72  * Report descriptor structure observing functions
    73  */
    74 usb_hid_report_field_t *usb_hid_report_get_sibling(usb_hid_report_t *report,
    75                 usb_hid_report_field_t *field, usb_hid_report_path_t *path,
    76                 int flags, usb_hid_report_type_t type);
    77 
    78 uint8_t usb_hid_get_next_report_id(usb_hid_report_t *report,
    79                 uint8_t report_id, usb_hid_report_type_t type);
     82/** */
     83uint8_t usb_hid_report_get_report_id(usb_hid_report_t *report,
     84                                     uint8_t report_id,
     85                                     usb_hid_report_type_t type);
    8086
    8187#endif
  • uspace/lib/usbhid/include/usb/hid/hidpath.h

    r6bfaab5 r88be3a0b  
    2727 */
    2828
    29 /** @addtogroup libusb
     29/** @addtogroup libusbhid
    3030 * @{
    3131 */
     
    3333 * USB HID report descriptor and report data parser
    3434 */
    35 #ifndef LIBUSB_HIDPATH_H_
    36 #define LIBUSB_HIDPATH_H_
     35#ifndef LIBUSBHID_HIDPATH_H_
     36#define LIBUSBHID_HIDPATH_H_
    3737
    3838#include <usb/hid/hidparser.h>
     
    4040#include <adt/list.h>
    4141
    42 
    43 /*---------------------------------------------------------------------------*/
    44 /*
    45  * Flags of usage paths comparison modes.
    46  *
     42/**
     43 * Description of path of usage pages and usages in report descriptor
    4744 */
    48 /** Wanted usage path must be exactly the same as the searched one.  This
    49  * option cannot be combined with the others.
    50  */
     45/** Wanted usage path must be exactly the same as the searched one */
    5146#define USB_HID_PATH_COMPARE_STRICT             0
    52 
    53 /**
    54  * Wanted usage path must be the suffix in the searched one.
    55  */
     47/** Wanted usage path must be the suffix in the searched one */
    5648#define USB_HID_PATH_COMPARE_END                1
    57 
    58 /**
    59  * Only usage page are compared along the usage path.  This option can be
    60  * combined with others.
    61  */
     49/** */
    6250#define USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY    2
    63 
    64 /**
    65  * Searched usage page must be prefix of the other one.
    66  */
     51/** Searched usage page must be prefix of the other one */
    6752#define USB_HID_PATH_COMPARE_BEGIN              4
    68 
    69 /**
    70  * Searched couple of usage page and usage can be anywhere in usage path.
    71  * This option is deprecated.
    72  */
     53/** Searched couple of usage page and usage can be anywhere in usage path */
    7354#define USB_HID_PATH_COMPARE_ANYWHERE           8
    7455
    75 /*----------------------------------------------------------------------------*/
    76 /**
    77  * Item of usage path structure. Last item of linked list describes one item
    78  * in report, the others describe superior Collection tags. Usage and Usage
    79  * page of report item can be changed due to data in report.
    80  */
     56
     57/** Collection usage path structure */
    8158typedef struct {
    82         /** Usage page of report item. Zero when usage page can be changed. */
     59        /** */
    8360        uint32_t usage_page;
    84         /** Usage of report item. Zero when usage can be changed. */   
     61        /** */ 
    8562        uint32_t usage;
    8663
    87         /** Attribute of Collection tag in report descriptor*/
    8864        uint8_t flags;
    89 
    90         /** Linked list structure*/
     65        /** */
    9166        link_t link;
    9267} usb_hid_report_usage_path_t;
    9368
    94 
    95 /*---------------------------------------------------------------------------*/
    96 /**
    97  * USB HID usage path structure.
    98  * */
     69/** */
    9970typedef struct {
    100         /** Length of usage path */     
     71        /** */ 
    10172        int depth;     
    102 
    103         /** Report id. Zero is reserved and means that report id is not used.
    104          * */
    10573        uint8_t report_id;
    10674       
    107         /** Linked list structure. */   
     75        /** */ 
    10876        link_t link; /* list */
    10977
    110         /** Head of the list of usage path items. */
    111         link_t head;
     78        link_t head; /* head of list of usage paths */
    11279
    11380} usb_hid_report_path_t;
    11481
    115 /*---------------------------------------------------------------------------*/
     82/** */
    11683usb_hid_report_path_t *usb_hid_report_path(void);
    11784
     85/** */
    11886void usb_hid_report_path_free(usb_hid_report_path_t *path);
    11987
    120 int usb_hid_report_path_set_report_id(usb_hid_report_path_t *usage_path,
    121                 uint8_t report_id);
     88/** */
     89int usb_hid_report_path_set_report_id(usb_hid_report_path_t *usage_path,
     90                                      uint8_t report_id);
    12291
     92/** */
    12393int usb_hid_report_path_append_item(usb_hid_report_path_t *usage_path,
    124                 int32_t usage_page, int32_t usage);
     94                                    int32_t usage_page, int32_t usage);
    12595
     96/** */
    12697void usb_hid_report_remove_last_item(usb_hid_report_path_t *usage_path);
    12798
     99/** */
    128100void usb_hid_report_null_last_item(usb_hid_report_path_t *usage_path);
    129101
     102/** */
    130103void usb_hid_report_set_last_item(usb_hid_report_path_t *usage_path,
    131                 int32_t tag, int32_t data);
     104                                  int32_t tag, int32_t data);
    132105
    133 int usb_hid_report_compare_usage_path(usb_hid_report_path_t *report_path,
    134                 usb_hid_report_path_t *path, int flags);
     106/** */
     107int usb_hid_report_compare_usage_path(usb_hid_report_path_t *report_path,
     108                                      usb_hid_report_path_t *path, int flags);
    135109
    136 usb_hid_report_path_t *usb_hid_report_path_clone(
    137                 usb_hid_report_path_t *usage_path);
     110/** */
     111usb_hid_report_path_t *usb_hid_report_path_clone(usb_hid_report_path_t *usage_path);
    138112
    139113void usb_hid_print_usage_path(usb_hid_report_path_t *path);
  • uspace/lib/usbhid/include/usb/hid/hidreport.h

    r6bfaab5 r88be3a0b  
    4444 * report parser.
    4545 *
    46  * \param[in] dev USB device representing a HID device.
    47  * \param[in/out] parser HID Report parser.
    48  * \param[out] report_desc Place to save report descriptor into.
    49  * \param[out] report_size
     46 * \param dev USB device representing a HID device.
     47 * \param parser HID Report parser.
    5048 *
    5149 * \retval EOK if successful.
     
    5957 */
    6058int usb_hid_process_report_descriptor(usb_device_t *dev,
    61     usb_hid_report_t *report, uint8_t **report_desc, size_t *report_size);
     59    usb_hid_report_t *report);
    6260
    6361#endif /* LIBUSB_HIDREPORT_H_ */
  • uspace/lib/usbhid/include/usb/hid/hidtypes.h

    r6bfaab5 r88be3a0b  
    2727 */
    2828
    29 /** @addtogroup libusb
     29/** @addtogroup libusbhid
    3030 * @{
    3131 */
    3232/** @file
    33  * Basic data structures for USB HID Report descriptor and report parser.
    34  */
    35 #ifndef LIBUSB_HIDTYPES_H_
    36 #define LIBUSB_HIDTYPES_H_
     33 * USB HID report descriptor and report data parser
     34 */
     35#ifndef LIBUSBHID_HIDTYPES_H_
     36#define LIBUSBHID_HIDTYPES_H_
    3737
    3838#include <stdint.h>
    3939#include <adt/list.h>
    4040
    41 /*---------------------------------------------------------------------------*/
    42 
    43 /**
    44  * Maximum amount of specified usages for one report item
    45  */
    46 #define USB_HID_MAX_USAGES      0xffff
    47 
    48 /**
    49  * Converts integer from unsigned two's complement format format to signed
    50  * one.
    51  *
    52  * @param x Number to convert
    53  * @param size Length of the unsigned number in bites
    54  * @return signed int
    55  */
    56 #define USB_HID_UINT32_TO_INT32(x, size)        \
    57         ((((x) & (1 << ((size) - 1))) != 0) ?   \
    58          -(~((x) - 1) & ((1 << size) - 1)) : (x))
    59 
    60 /**
    61  * Convert integer from signed format to unsigned. If number is negative the
    62  * two's complement format is used.
    63  *
    64  * @param x Number to convert
    65  * @param size Length of result number in bites
    66  * @return unsigned int
    67  */
    68 #define USB_HID_INT32_TO_UINT32(x, size)        \
    69         (((x) < 0 ) ? ((1 << (size)) + (x)) : (x))
    70 
    71 /*---------------------------------------------------------------------------*/
    72 
    73 /**
    74  * Enum of report types
    75  */
     41#define USB_HID_MAX_USAGES      20
     42
     43#define USB_HID_UINT32_TO_INT32(x, size)        ((((x) & (1 << ((size) - 1))) != 0) ? -(~(x - 1) & ((1 << size) - 1)) : (x)) //(-(~((x) - 1)))
     44#define USB_HID_INT32_TO_UINT32(x, size)        (((x) < 0 ) ? ((1 << (size)) + (x)) : (x))
     45
     46
    7647typedef enum {
    77         /** Input report. Data are sent from device to system */
    7848        USB_HID_REPORT_TYPE_INPUT = 1,
    79 
    80         /** Output report. Data are sent from system to device */
    8149        USB_HID_REPORT_TYPE_OUTPUT = 2,
    82 
    83         /** Feature report. Describes device configuration information that
    84          * can be sent to the device */
    8550        USB_HID_REPORT_TYPE_FEATURE = 3
    8651} usb_hid_report_type_t;
    8752
    88 /*---------------------------------------------------------------------------*/
    89 
    90 /**
    91  * Description of all reports described in one report descriptor.
    92  */
    93 typedef struct {
    94         /** Count of available reports. */
     53
     54typedef struct {
     55        /** */
    9556        int report_count;
    96 
    97         /** Head of linked list of description of reports. */
    98         link_t reports;
    99 
    100         /** Head of linked list of all used usage/collection paths. */
     57        link_t reports;         /** list of usb_hid_report_description_t */
     58
    10159        link_t collection_paths;
    102 
    103         /** Length of list of usage paths. */
    10460        int collection_paths_count;
    10561
    106         /** Flag whether report ids are used. */
    10762        int use_report_ids;
    108 
    109         /** Report id of last parsed report. */
    11063        uint8_t last_report_id;
    11164       
    11265} usb_hid_report_t;
    113 /*---------------------------------------------------------------------------*/
    114 
    115 /**
    116  * Description of one concrete report
    117  */
    118 typedef struct {
    119         /** Report id. Zero when no report id is used. */
     66
     67typedef struct {
    12068        uint8_t report_id;
    121 
    122         /** Type of report */
    12369        usb_hid_report_type_t type;
    12470
    125         /** Bit length of the report */
    12671        size_t bit_length;
    127 
    128         /** Number of items in report */
    12972        size_t item_length;
    13073       
    131         /** Linked list of report items in report */
    132         link_t report_items;
    133 
    134         /** Linked list of descriptions. */
     74        link_t report_items;    /** list of report items (fields) */
     75
    13576        link_t link;
    13677} usb_hid_report_description_t;
    137 /*---------------------------------------------------------------------------*/
    138 
    139 /**
    140  * Description of one field/item in report
    141  */
    142 typedef struct {
    143         /** Bit offset of the field */
     78
     79typedef struct {
     80
    14481        int offset;
    145 
    146         /** Bit size of the field */
    14782        size_t size;
    14883
    149         /** Usage page. Zero when usage page can be changed. */
    15084        uint16_t usage_page;
    151 
    152         /** Usage. Zero when usage can be changed. */
    15385        uint16_t usage;
    15486
    155         /** Item's attributes */
    15687        uint8_t item_flags;
    157 
    158         /** Usage/Collection path of the field. */
    15988        usb_hid_report_path_t *collection_path;
    16089
    161         /**
    162          * The lowest valid logical value (value with the device operates)
    163          */
    16490        int32_t logical_minimum;
    165 
    166         /**
    167          * The greatest valid logical value
    168          */
    16991        int32_t logical_maximum;
    170 
    171         /**
    172          * The lowest valid physical value (value with the system operates)
    173          */
    17492        int32_t physical_minimum;
    175 
    176         /** The greatest valid physical value */
    17793        int32_t physical_maximum;
    178 
    179         /** The lowest valid usage index */
    180         int32_t usage_minimum;
    181 
    182         /** The greatest valid usage index */
    183         int32_t usage_maximum;
    184        
    185         /** Unit of the value */
     94        uint32_t usage_minimum;
     95        uint32_t usage_maximum;
    18696        uint32_t unit;
    187 
    188         /** Unit exponent */
    18997        uint32_t unit_exponent;
    190 
    191         /** Array of possible usages */
    192         uint32_t *usages;
    193 
    194         /** Size of the array of usages */
    195         size_t usages_count;
    196 
    197         /** Parsed value */
     98       
     99
    198100        int32_t value;
    199101
    200         /** List to another report items */
    201102        link_t link;
    202103} usb_hid_report_field_t;
    203104
    204 /*---------------------------------------------------------------------------*/
     105
    205106
    206107/**
    207  * State table for report descriptor parsing
     108 * state table
    208109 */
    209110typedef struct {
     
    211112        int32_t id;
    212113       
    213         /** Extended usage page */
     114        /** */
    214115        uint16_t extended_usage_page;
    215 
    216         /** Array of usages specified for this item */
    217116        uint32_t usages[USB_HID_MAX_USAGES];
    218        
    219         /** Length of usages array */
    220117        int usages_count;
    221118
    222         /** Usage page*/
     119        /** */
    223120        uint32_t usage_page;
    224121
    225         /** Minimum valid usage index */       
    226         int32_t usage_minimum;
    227        
    228         /** Maximum valid usage index */       
    229         int32_t usage_maximum;
    230        
    231         /** Minimum valid logical value */     
     122        /** */ 
     123        uint32_t usage_minimum;
     124        /** */ 
     125        uint32_t usage_maximum;
     126        /** */ 
    232127        int32_t logical_minimum;
    233        
    234         /** Maximum valid logical value */     
     128        /** */ 
    235129        int32_t logical_maximum;
    236 
    237         /** Length of the items in bits*/       
     130        /** */ 
    238131        int32_t size;
    239 
    240         /** COunt of items*/   
     132        /** */ 
    241133        int32_t count;
    242 
    243         /**  Bit offset of the item in report */       
     134        /** */ 
    244135        size_t offset;
    245 
    246         /** Unit exponent */   
     136        /** */ 
    247137        int32_t unit_exponent;
    248         /** Unit of the value */       
     138        /** */ 
    249139        int32_t unit;
    250140
    251         /** String index */
     141        /** */
    252142        uint32_t string_index;
    253 
    254         /** Minimum valid string index */       
     143        /** */ 
    255144        uint32_t string_minimum;
    256 
    257         /** Maximum valid string index */       
     145        /** */ 
    258146        uint32_t string_maximum;
    259 
    260         /** The designator index */     
     147        /** */ 
    261148        uint32_t designator_index;
    262 
    263         /** Minimum valid designator value*/   
     149        /** */ 
    264150        uint32_t designator_minimum;
    265 
    266         /** Maximum valid designator value*/   
     151        /** */ 
    267152        uint32_t designator_maximum;
    268 
    269         /** Minimal valid physical value*/     
     153        /** */ 
    270154        int32_t physical_minimum;
    271 
    272         /** Maximal valid physical value */     
     155        /** */ 
    273156        int32_t physical_maximum;
    274157
    275         /** Items attributes*/ 
     158        /** */ 
    276159        uint8_t item_flags;
    277160
    278         /** Report type */
    279161        usb_hid_report_type_t type;
    280162
    281163        /** current collection path*/   
    282164        usb_hid_report_path_t *usage_path;
    283 
    284         /** Unused*/   
     165        /** */ 
    285166        link_t link;
    286167
    287168        int in_delimiter;
    288169} usb_hid_report_item_t;
    289 /*---------------------------------------------------------------------------*/
    290 /**
    291  * Enum of the keyboard modifiers
    292  */
     170
     171/** HID parser callbacks for IN items. */
     172typedef struct {
     173        /** Callback for keyboard.
     174         *
     175         * @param key_codes Array of pressed key (including modifiers).
     176         * @param count Length of @p key_codes.
     177         * @param arg Custom argument.
     178         */
     179        void (*keyboard)(const uint8_t *key_codes, size_t count, const uint8_t report_id, void *arg);
     180} usb_hid_report_in_callbacks_t;
     181
     182
    293183typedef enum {
    294184        USB_HID_MOD_LCTRL = 0x01,
     
    314204        USB_HID_MOD_RGUI
    315205};
    316 /*---------------------------------------------------------------------------*/
    317 
    318206
    319207#endif
  • uspace/lib/usbhid/include/usb/hid/iface.h

    r6bfaab5 r88be3a0b  
    3838#include <sys/types.h>
    3939
    40 int usbhid_dev_get_event_length(int, size_t *);
    41 int usbhid_dev_get_event(int, uint8_t *, size_t, size_t *, int *,
     40int usbhid_dev_get_event_length(int);
     41int usbhid_dev_get_event(int, uint16_t *, uint16_t *, size_t, size_t *,
    4242    unsigned int);
    43 int usbhid_dev_get_report_descriptor_length(int, size_t *);
    44 int usbhid_dev_get_report_descriptor(int, uint8_t *, size_t, size_t *);
    4543
    4644#endif
  • uspace/lib/usbhid/include/usb/hid/usages/core.h

    r6bfaab5 r88be3a0b  
    6767} usb_hidut_usage_generic_desktop_t;
    6868
    69 typedef enum {
    70         USB_HIDUT_USAGE_CONSUMER_CONSUMER_CONTROL = 1
    71 } usb_hidut_usage_consumer_t;
    72 
    7369
    7470#endif
  • uspace/lib/usbhid/src/hiddescriptor.c

    r6bfaab5 r88be3a0b  
    4141#include <assert.h>
    4242
    43 /*---------------------------------------------------------------------------*/
    44 /*
    45  * Constants defining current parsing mode for correct parsing of the set of
    46  * local tags (usage) enclosed in delimter tags.
    47  */
    48 /**
    49  * Second delimiter tag was read. The set of local items (usage) ended.
    50  */
     43
    5144#define OUTSIDE_DELIMITER_SET   0
    52 
    53 /**
    54  * First delimiter tag was read. The set of local items (usage) started.
    55  */
    5645#define START_DELIMITER_SET     1
    57 
    58 /**
    59  * Parser is in the set of local items.
    60  */
    6146#define INSIDE_DELIMITER_SET    2
    62 
    63 /*---------------------------------------------------------------------------*/
    6447       
    6548/** The new report item flag. Used to determine when the item is completly
     
    7861#define USB_HID_UNKNOWN_TAG             -99
    7962
    80 /*---------------------------------------------------------------------------*/
    81 /**
    82  * Checks if given collection path is already present in report structure and
    83  * inserts it if not.
    84  *
    85  * @param report Report structure
    86  * @param cmp_path The collection path
    87  * @return Pointer to the result collection path in report structure.
    88  * @retval NULL If some error occurs
    89  */
    90 usb_hid_report_path_t *usb_hid_report_path_try_insert(
    91                 usb_hid_report_t *report, usb_hid_report_path_t *cmp_path) {
    92        
    93         link_t *path_it = report->collection_paths.prev->next;
     63usb_hid_report_path_t *usb_hid_report_path_try_insert(usb_hid_report_t *report, usb_hid_report_path_t *cmp_path)
     64{
     65        /* find or append current collection path to the list */
     66        link_t *path_it = report->collection_paths.next;
    9467        usb_hid_report_path_t *path = NULL;
    95        
    96         if((report == NULL) || (cmp_path == NULL)) {
    97                 return NULL;
    98         }
    99        
    10068        while(path_it != &report->collection_paths) {
    101                 path = list_get_instance(path_it, usb_hid_report_path_t,
    102                                 link);
    103                
    104                 if(usb_hid_report_compare_usage_path(path, cmp_path,
    105                                         USB_HID_PATH_COMPARE_STRICT) == EOK){
     69                path = list_get_instance(path_it, usb_hid_report_path_t, link);
     70               
     71                if(usb_hid_report_compare_usage_path(path, cmp_path, USB_HID_PATH_COMPARE_STRICT) == EOK){
    10672                        break;
    10773                }                       
     
    10975        }
    11076        if(path_it == &report->collection_paths) {
    111                 path = usb_hid_report_path_clone(cmp_path);
    112                 if(path == NULL) {
    113                         return NULL;
    114                 }
     77                path = usb_hid_report_path_clone(cmp_path);                     
    11578                list_append(&path->link, &report->collection_paths);                                   
    11679                report->collection_paths_count++;
     
    11982        }
    12083        else {
    121                 return list_get_instance(path_it, usb_hid_report_path_t,
    122                                 link);
    123         }
    124 }
    125 
    126 /*---------------------------------------------------------------------------*/
     84                return list_get_instance(path_it, usb_hid_report_path_t, link);
     85        }
     86}
     87
    12788/**
    12889 * Initialize the report descriptor parser structure
     
    13091 * @param parser Report descriptor parser structure
    13192 * @return Error code
    132  * @retval EINVAL If no report structure was given
    133  * @retval EOK If report structure was successfully initialized
    13493 */
    13594int usb_hid_report_init(usb_hid_report_t *report)
     
    147106}
    148107
    149 /*---------------------------------------------------------------------------*/
    150 
    151 /**
    152  *
    153  *
    154  * @param report Report structure in which the new report items should be
    155  *               stored
    156  * @param report_item Current report descriptor's parsing state table
    157  * @return Error code
    158  * @retval EOK If all fields were successfully append to report
    159  * @retval EINVAL If invalid parameters (NULL) was given
    160  * @retval ENOMEM If there is no memmory to store new report description
    161  *
    162  */
    163 int usb_hid_report_append_fields(usb_hid_report_t *report,
    164                 usb_hid_report_item_t *report_item) {
    165 
     108
     109/*
     110 *
     111 *
     112 */
     113int usb_hid_report_append_fields(usb_hid_report_t *report, usb_hid_report_item_t *report_item)
     114{
    166115        usb_hid_report_field_t *field;
    167116        int i;
    168117
    169         uint32_t *usages;
    170         int usages_used=0;
    171 
    172         if((report == NULL) || (report_item == NULL)) {
    173                 return EINVAL;
    174         }
    175 
    176         if(report_item->usages_count > 0){
    177                 usages = malloc(sizeof(int32_t) * report_item->usages_count);
    178                 memcpy(usages, report_item->usages, sizeof(int32_t) *
    179                                 report_item->usages_count);
    180         }
    181         else {
    182                 usages = NULL;
    183         }
    184        
     118        for(i=0; i<report_item->usages_count; i++){
     119                usb_log_debug("usages (%d) - %x\n", i, report_item->usages[i]);
     120        }
     121
    185122        usb_hid_report_path_t *path = report_item->usage_path; 
    186123        for(i=0; i<report_item->count; i++){
     
    196133                field->physical_maximum = report_item->physical_maximum;
    197134
    198                 if(USB_HID_ITEM_FLAG_VARIABLE(report_item->item_flags) == 0){
    199                         /*
    200                         Store usage array. The Correct Usage Page and Usage is
    201                         depending on data in report and will be filled later
    202                         */
    203                         field->usage = 0;
    204                         field->usage_page = 0; //report_item->usage_page;
    205 
    206                         field->usages_count = report_item->usages_count;
    207                         field->usages = usages;
    208                         usages_used = 1;
     135                field->usage_minimum = report_item->usage_minimum;
     136                field->usage_maximum = report_item->usage_maximum;
     137                if(report_item->extended_usage_page != 0){
     138                        field->usage_page = report_item->extended_usage_page;
    209139                }
    210140                else {
    211 
    212                         /* Fill the correct Usage and Usage Page */
    213                         int32_t usage;
    214                         if(i < report_item->usages_count) {
     141                        field->usage_page = report_item->usage_page;
     142                }
     143
     144                if(report_item->usages_count > 0 && ((report_item->usage_minimum == 0) && (report_item->usage_maximum == 0))) {
     145                        uint32_t usage;
     146                        if(i < report_item->usages_count){
    215147                                usage = report_item->usages[i];
    216148                        }
    217149                        else {
    218                                 usage = report_item->usages[
    219                                         report_item->usages_count- 1];
    220                         }
    221 
    222                         if(USB_HID_IS_EXTENDED_USAGE(usage)){
    223                                 field->usage = USB_HID_EXTENDED_USAGE(usage);
    224                                 field->usage_page =
    225                                         USB_HID_EXTENDED_USAGE_PAGE(usage);
     150                                usage = report_item->usages[report_item->usages_count - 1];
     151                        }
     152
     153                                               
     154                        if((usage & 0xFFFF0000) != 0){
     155                                field->usage_page = (usage >> 16);                                     
     156                                field->usage = (usage & 0xFFFF);
    226157                        }
    227158                        else {
    228                                 // should not occur
    229159                                field->usage = usage;
    230                                 field->usage_page = report_item->usage_page;
    231                         }
    232                 }
    233                
    234                 usb_hid_report_set_last_item(path, USB_HID_TAG_CLASS_GLOBAL,
    235                                 field->usage_page);
    236                 usb_hid_report_set_last_item(path, USB_HID_TAG_CLASS_LOCAL,
    237                                 field->usage);
    238 
    239                 field->collection_path =
    240                         usb_hid_report_path_try_insert(report, path);
     160                        }
     161
     162                       
     163                }       
     164
     165                if((USB_HID_ITEM_FLAG_VARIABLE(report_item->item_flags) != 0) && (!((report_item->usage_minimum == 0) && (report_item->usage_maximum == 0)))) {
     166                        field->usage = report_item->usage_minimum + i;                                 
     167                }
     168               
     169                usb_hid_report_set_last_item(path, USB_HID_TAG_CLASS_GLOBAL, field->usage_page);
     170                usb_hid_report_set_last_item(path, USB_HID_TAG_CLASS_LOCAL, field->usage);
     171
     172                field->collection_path = usb_hid_report_path_try_insert(report, path);
    241173
    242174                field->size = report_item->size;
    243175               
    244                 size_t offset_byte = (report_item->offset + (i *
    245                         report_item->size)) / 8;
    246 
    247                 size_t offset_bit = 8 - ((report_item->offset + (i *
    248                         report_item->size)) % 8) - report_item->size;
     176                size_t offset_byte = (report_item->offset + (i * report_item->size)) / 8;
     177                size_t offset_bit = 8 - ((report_item->offset + (i * report_item->size)) % 8) - report_item->size;
    249178
    250179                field->offset = 8 * offset_byte + offset_bit;
     
    257186                /* find the right report list*/
    258187                usb_hid_report_description_t *report_des;
    259                 report_des = usb_hid_report_find_description(report,
    260                         report_item->id, report_item->type);
    261                
     188                report_des = usb_hid_report_find_description(report, report_item->id, report_item->type);
    262189                if(report_des == NULL){
    263                         report_des = malloc(
    264                                 sizeof(usb_hid_report_description_t));
    265                         if(report_des == NULL) {
    266                                 return ENOMEM;
    267                         }
    268 
    269                         memset(report_des, 0,
    270                                 sizeof(usb_hid_report_description_t));
     190                        report_des = malloc(sizeof(usb_hid_report_description_t));
     191                        memset(report_des, 0, sizeof(usb_hid_report_description_t));
    271192
    272193                        report_des->type = report_item->type;
    273194                        report_des->report_id = report_item->id;
    274                         if(report_des->report_id != 0) {
    275                                 /* set up the bit length by report_id field */
    276                                 report_des->bit_length = 8;
    277                         }
    278 
    279195                        list_initialize (&report_des->link);
    280196                        list_initialize (&report_des->report_items);
     
    293209        }
    294210
    295         // free only when not used!!!
    296         if(usages && usages_used == 0) {
    297                 free(usages);
    298         }
    299211
    300212        return EOK;
    301213}
    302 /*---------------------------------------------------------------------------*/
    303 /**
    304  * Finds description of report with given report_id and of given type in
    305  * opaque report structure.
    306  *
    307  * @param report Opaque structure containing the parsed report descriptor
    308  * @param report_id ReportId of report we are searching
    309  * @param type Type of report we are searching
    310  * @return Pointer to the particular report description
    311  * @retval NULL If no description is founded
    312  */
    313 usb_hid_report_description_t * usb_hid_report_find_description(
    314                 const usb_hid_report_t *report, uint8_t report_id,
    315                 usb_hid_report_type_t type) {
    316 
     214
     215usb_hid_report_description_t * usb_hid_report_find_description(const usb_hid_report_t *report, uint8_t report_id, usb_hid_report_type_t type)
     216{
    317217        link_t *report_it = report->reports.next;
    318218        usb_hid_report_description_t *report_des = NULL;
    319219       
    320220        while(report_it != &report->reports) {
    321                 report_des = list_get_instance(report_it,
    322                                 usb_hid_report_description_t, link);
    323 
    324                 if((report_des->report_id == report_id) &&
    325                    (report_des->type == type)) {
     221                report_des = list_get_instance(report_it, usb_hid_report_description_t, link);
     222
     223                if((report_des->report_id == report_id) && (report_des->type == type)){
    326224                        return report_des;
    327225                }
     
    332230        return NULL;
    333231}
    334 /*---------------------------------------------------------------------------*/
    335232
    336233/** Parse HID report descriptor.
     
    339236 * @param data Data describing the report.
    340237 * @return Error code.
    341  * @retval ENOMEM If no more memmory is available
    342  * @retval EINVAL If invalid data are founded
    343  * @retval EOK If report descriptor is successfully parsed
    344238 */
    345239int usb_hid_parse_report_descriptor(usb_hid_report_t *report,
     
    392286                       
    393287                        ret = usb_hid_report_parse_tag(tag,class,data+i+1,
    394                                 item_size,report_item, usage_path);
    395 
     288                                                       item_size,report_item, usage_path);
    396289                        switch(ret){
    397                         case USB_HID_NEW_REPORT_ITEM:
    398                                 /* store report item to report and create the
    399                                  * new one store current collection path
    400                                  */
    401                                 report_item->usage_path = usage_path;
     290                                case USB_HID_NEW_REPORT_ITEM:
     291                                        // store report item to report and create the new one
     292                                        // store current collection path
     293                                        report_item->usage_path = usage_path;
    402294                                       
    403                                 usb_hid_report_path_set_report_id(
    404                                      report_item->usage_path, report_item->id);
    405                                
    406                                 if(report_item->id != 0){
    407                                         report->use_report_ids = 1;
    408                                 }
     295                                        usb_hid_report_path_set_report_id(report_item->usage_path, report_item->id);   
     296                                        if(report_item->id != 0){
     297                                                report->use_report_ids = 1;
     298                                        }
    409299                                       
    410                                 switch(tag) {
    411                                 case USB_HID_REPORT_TAG_INPUT:
    412                                         report_item->type =
    413                                             USB_HID_REPORT_TYPE_INPUT;
    414 
    415                                         report_item->offset = offset_input;
    416                                         offset_input += report_item->count *
    417                                             report_item->size;
     300                                        switch(tag) {
     301                                                case USB_HID_REPORT_TAG_INPUT:
     302                                                        report_item->type = USB_HID_REPORT_TYPE_INPUT;
     303                                                        report_item->offset = offset_input;
     304                                                        offset_input += report_item->count * report_item->size;
     305                                                        break;
     306                                                case USB_HID_REPORT_TAG_OUTPUT:
     307                                                        report_item->type = USB_HID_REPORT_TYPE_OUTPUT;
     308                                                        report_item->offset = offset_output;
     309                                                        offset_output += report_item->count * report_item->size;
     310
     311                                                        break;
     312                                                case USB_HID_REPORT_TAG_FEATURE:
     313                                                        report_item->type = USB_HID_REPORT_TYPE_FEATURE;
     314                                                        report_item->offset = offset_feature;
     315                                                        offset_feature += report_item->count * report_item->size;
     316                                                        break;
     317                                                default:
     318                                                    usb_log_debug("\tjump over - tag %X\n", tag);
     319                                                    break;
     320                                        }
     321                                       
     322                                        /*
     323                                         * append new fields to the report
     324                                         * structure                                     
     325                                         */
     326                                        usb_hid_report_append_fields(report, report_item);
     327
     328                                        /* reset local items */
     329                                        usb_hid_report_reset_local_items (report_item);
     330
    418331                                        break;
    419        
    420                                 case USB_HID_REPORT_TAG_OUTPUT:
    421                                         report_item->type =
    422                                             USB_HID_REPORT_TYPE_OUTPUT;
     332
     333                                case USB_HID_RESET_OFFSET:
     334                                        offset_input = 0;
     335                                        offset_output = 0;
     336                                        offset_feature = 0;
     337                                        usb_hid_report_path_set_report_id (usage_path, report_item->id);
     338                                        break;
     339
     340                                case USB_HID_REPORT_TAG_PUSH:
     341                                        // push current state to stack
     342                                        new_report_item = usb_hid_report_item_clone(report_item);
     343                                        usb_hid_report_path_t *tmp_path = usb_hid_report_path_clone(usage_path);
     344                                        new_report_item->usage_path = tmp_path;
     345
     346                                        list_prepend (&new_report_item->link, &stack);
     347                                        break;
     348                                case USB_HID_REPORT_TAG_POP:
     349                                        // restore current state from stack
     350                                        if(list_empty (&stack)) {
     351                                                return EINVAL;
     352                                        }
     353                                        free(report_item);
     354                                               
     355                                        report_item = list_get_instance(stack.next, usb_hid_report_item_t, link);
    423356                                       
    424                                         report_item->offset = offset_output;
    425                                         offset_output += report_item->count *
    426                                             report_item->size;
     357                                        usb_hid_report_usage_path_t *tmp_usage_path;
     358                                        tmp_usage_path = list_get_instance(report_item->usage_path->link.prev, usb_hid_report_usage_path_t, link);
     359                                       
     360                                        usb_hid_report_set_last_item(usage_path, USB_HID_TAG_CLASS_GLOBAL, tmp_usage_path->usage_page);
     361                                        usb_hid_report_set_last_item(usage_path, USB_HID_TAG_CLASS_LOCAL, tmp_usage_path->usage);
     362
     363                                        usb_hid_report_path_free(report_item->usage_path);
     364                                        list_initialize(&report_item->usage_path->link);
     365                                        list_remove (stack.next);
     366                                       
    427367                                        break;
    428        
    429                                 case USB_HID_REPORT_TAG_FEATURE:
    430                                         report_item->type =
    431                                             USB_HID_REPORT_TYPE_FEATURE;
    432 
    433                                         report_item->offset = offset_feature;
    434                                         offset_feature += report_item->count *
    435                                                 report_item->size;
     368                                       
     369                                default:
     370                                        // nothing special to do                                       
    436371                                        break;
    437        
    438                                 default:
    439                                         usb_log_debug2(
    440                                             "\tjump over - tag %X\n", tag);
    441                                         break;
    442                                 }
    443                                        
    444                                 /*
    445                                  * append new fields to the report structure                                     
    446                                  */
    447                                 usb_hid_report_append_fields(report,
    448                                     report_item);
    449 
    450                                 /* reset local items */
    451                                 usb_hid_report_reset_local_items (report_item);
    452                                 break;
    453 
    454                         case USB_HID_RESET_OFFSET:
    455                                 offset_input = 0;
    456                                 offset_output = 0;
    457                                 offset_feature = 0;
    458                                 usb_hid_report_path_set_report_id (usage_path,
    459                                     report_item->id);
    460                                 break;
    461 
    462                         case USB_HID_REPORT_TAG_PUSH:
    463                                 // push current state to stack
    464                                 new_report_item = usb_hid_report_item_clone(
    465                                     report_item);
    466                                
    467                                 usb_hid_report_path_t *tmp_path =
    468                                     usb_hid_report_path_clone(usage_path);
    469 
    470                                 new_report_item->usage_path = tmp_path;
    471 
    472                                 list_prepend (&new_report_item->link, &stack);
    473                                 break;
    474                         case USB_HID_REPORT_TAG_POP:
    475                                 // restore current state from stack
    476                                 if(list_empty (&stack)) {
    477                                         return EINVAL;
    478                                 }
    479                                 free(report_item);
    480                                                
    481                                 report_item = list_get_instance(stack.next,
    482                                     usb_hid_report_item_t, link);
    483                                        
    484                                 usb_hid_report_usage_path_t *tmp_usage_path;
    485                                 tmp_usage_path = list_get_instance(
    486                                     report_item->usage_path->link.prev,
    487                                     usb_hid_report_usage_path_t, link);
    488                                        
    489                                 usb_hid_report_set_last_item(usage_path,
    490                                     USB_HID_TAG_CLASS_GLOBAL, tmp_usage_path->usage_page);
    491                                
    492                                 usb_hid_report_set_last_item(usage_path,
    493                                     USB_HID_TAG_CLASS_LOCAL, tmp_usage_path->usage);
    494 
    495                                 usb_hid_report_path_free(report_item->usage_path);
    496                                 list_initialize(&report_item->usage_path->link);
    497                                 list_remove (stack.next);
    498                                        
    499                                 break;
    500                                        
    501                         default:
    502                                 // nothing special to do                                       
    503                                 break;
    504372                        }
    505373
     
    518386}
    519387
    520 /*---------------------------------------------------------------------------*/
    521388
    522389/**
     
    529396 * @return Code of action to be done next
    530397 */
    531 int usb_hid_report_parse_tag(uint8_t tag, uint8_t class, const uint8_t *data,
    532         size_t item_size, usb_hid_report_item_t *report_item,
    533         usb_hid_report_path_t *usage_path) {   
    534        
     398int usb_hid_report_parse_tag(uint8_t tag, uint8_t class, const uint8_t *data, size_t item_size,
     399                             usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path)
     400{       
    535401        int ret;
    536402       
    537403        switch(class){
    538         case USB_HID_TAG_CLASS_MAIN:
    539 
    540                 if((ret=usb_hid_report_parse_main_tag(tag, data, item_size,
    541                         report_item, usage_path)) == EOK) {
    542 
    543                         return USB_HID_NEW_REPORT_ITEM;
    544                 }
    545                 else {
    546                         return ret;
    547                 }
    548                 break;
    549 
    550         case USB_HID_TAG_CLASS_GLOBAL: 
    551                 return usb_hid_report_parse_global_tag(tag, data, item_size,
    552                         report_item, usage_path);
    553                 break;
    554 
    555         case USB_HID_TAG_CLASS_LOCAL:                   
    556                 return usb_hid_report_parse_local_tag(tag, data, item_size,
    557                         report_item, usage_path);
    558                 break;
    559        
    560         default:
    561                 return USB_HID_NO_ACTION;
     404                case USB_HID_TAG_CLASS_MAIN:
     405
     406                        if((ret=usb_hid_report_parse_main_tag(tag,data,item_size,report_item, usage_path)) == EOK) {
     407                                return USB_HID_NEW_REPORT_ITEM;
     408                        }
     409                        else {
     410                                /*TODO process the error */
     411                                return ret;
     412                           }
     413                        break;
     414
     415                case USB_HID_TAG_CLASS_GLOBAL: 
     416                        return usb_hid_report_parse_global_tag(tag,data,item_size,report_item, usage_path);
     417                        break;
     418
     419                case USB_HID_TAG_CLASS_LOCAL:                   
     420                        return usb_hid_report_parse_local_tag(tag,data,item_size,report_item, usage_path);
     421                        break;
     422                default:
     423                        return USB_HID_NO_ACTION;
    562424        }
    563425}
     
    573435 */
    574436
    575 int usb_hid_report_parse_main_tag(uint8_t tag, const uint8_t *data,
    576         size_t item_size, usb_hid_report_item_t *report_item,
    577         usb_hid_report_path_t *usage_path)
     437int usb_hid_report_parse_main_tag(uint8_t tag, const uint8_t *data, size_t item_size,
     438                             usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path)
    578439{
    579440        usb_hid_report_usage_path_t *path_item;
     
    581442        switch(tag)
    582443        {
    583         case USB_HID_REPORT_TAG_INPUT:
    584         case USB_HID_REPORT_TAG_OUTPUT:
    585         case USB_HID_REPORT_TAG_FEATURE:
    586                 report_item->item_flags = *data;                       
    587                 return EOK;                     
    588                 break;
     444                case USB_HID_REPORT_TAG_INPUT:
     445                case USB_HID_REPORT_TAG_OUTPUT:
     446                case USB_HID_REPORT_TAG_FEATURE:
     447                        report_item->item_flags = *data;                       
     448                        return EOK;                     
     449                        break;
    589450                       
    590         case USB_HID_REPORT_TAG_COLLECTION:
    591 
    592                 /* store collection atributes */
    593                 path_item = list_get_instance(usage_path->head.prev,
    594                         usb_hid_report_usage_path_t, link);
    595                 path_item->flags = *data;       
     451                case USB_HID_REPORT_TAG_COLLECTION:
     452                        // store collection atributes
     453                        path_item = list_get_instance(usage_path->head.prev, usb_hid_report_usage_path_t, link);
     454                        path_item->flags = *data;       
    596455                       
    597                 /* set last item */
    598                 usb_hid_report_set_last_item(usage_path,
    599                         USB_HID_TAG_CLASS_GLOBAL,
    600                         USB_HID_EXTENDED_USAGE_PAGE(report_item->usages[
    601                                 report_item->usages_count-1]));
    602 
    603                 usb_hid_report_set_last_item(usage_path,
    604                         USB_HID_TAG_CLASS_LOCAL,
    605                         USB_HID_EXTENDED_USAGE(report_item->usages[
    606                                 report_item->usages_count-1]));
     456                        // set last item
     457                        usb_hid_report_set_last_item(usage_path, USB_HID_TAG_CLASS_GLOBAL, report_item->usage_page);
     458                        usb_hid_report_set_last_item(usage_path, USB_HID_TAG_CLASS_LOCAL, report_item->usages[report_item->usages_count-1]);
    607459                       
    608                 /* append the new one which will be set by common usage/usage
    609                  * page */
    610                 usb_hid_report_path_append_item(usage_path,
    611                         report_item->usage_page,
    612                         report_item->usages[report_item->usages_count-1]);
    613 
    614                 usb_hid_report_reset_local_items (report_item);
    615                 return USB_HID_NO_ACTION;
    616                 break;
     460                        // append the new one which will be set by common
     461                        // usage/usage page
     462                        usb_hid_report_path_append_item(usage_path, report_item->usage_page, report_item->usages[report_item->usages_count-1]);
     463                        usb_hid_report_reset_local_items (report_item);
     464                        return USB_HID_NO_ACTION;
     465                        break;
    617466                       
    618         case USB_HID_REPORT_TAG_END_COLLECTION:
    619                 usb_hid_report_remove_last_item(usage_path);
    620                 return USB_HID_NO_ACTION;
    621                 break;
    622 
    623         default:
    624                 return USB_HID_NO_ACTION;
     467                case USB_HID_REPORT_TAG_END_COLLECTION:
     468                        usb_hid_report_remove_last_item(usage_path);
     469                        return USB_HID_NO_ACTION;
     470                        break;
     471                default:
     472                        return USB_HID_NO_ACTION;
    625473        }
    626474
     
    637485 * @return Error code
    638486 */
    639 int usb_hid_report_parse_global_tag(uint8_t tag, const uint8_t *data,
    640         size_t item_size, usb_hid_report_item_t *report_item,
    641         usb_hid_report_path_t *usage_path) {
    642        
     487int usb_hid_report_parse_global_tag(uint8_t tag, const uint8_t *data, size_t item_size,
     488                             usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path)
     489{
     490        // TODO take care about the bit length of data
    643491        switch(tag)
    644492        {
    645         case USB_HID_REPORT_TAG_USAGE_PAGE:
    646                 report_item->usage_page =
    647                         usb_hid_report_tag_data_uint32(data, item_size);
    648                 break;
    649 
    650         case USB_HID_REPORT_TAG_LOGICAL_MINIMUM:
    651                 report_item->logical_minimum = USB_HID_UINT32_TO_INT32(
    652                         usb_hid_report_tag_data_uint32(data,item_size),
    653                         item_size * 8);
    654                 break;
    655 
    656         case USB_HID_REPORT_TAG_LOGICAL_MAXIMUM:
    657                 report_item->logical_maximum = USB_HID_UINT32_TO_INT32(
    658                         usb_hid_report_tag_data_uint32(data,item_size),
    659                         item_size * 8);
    660                 break;
    661 
    662         case USB_HID_REPORT_TAG_PHYSICAL_MINIMUM:
    663                 report_item->physical_minimum = USB_HID_UINT32_TO_INT32(
    664                         usb_hid_report_tag_data_uint32(data,item_size),
    665                         item_size * 8);
    666                 break;                 
    667 
    668         case USB_HID_REPORT_TAG_PHYSICAL_MAXIMUM:
    669                 report_item->physical_maximum = USB_HID_UINT32_TO_INT32(
    670                         usb_hid_report_tag_data_uint32(data,item_size),
    671                         item_size * 8);
    672                 break;
    673 
    674         case USB_HID_REPORT_TAG_UNIT_EXPONENT:
    675                 report_item->unit_exponent = usb_hid_report_tag_data_uint32(
    676                         data,item_size);
    677                 break;
    678 
    679         case USB_HID_REPORT_TAG_UNIT:
    680                 report_item->unit = usb_hid_report_tag_data_uint32(
    681                         data,item_size);
    682                 break;
    683 
    684         case USB_HID_REPORT_TAG_REPORT_SIZE:
    685                 report_item->size = usb_hid_report_tag_data_uint32(
    686                         data,item_size);
    687                 break;
    688 
    689         case USB_HID_REPORT_TAG_REPORT_COUNT:
    690                 report_item->count = usb_hid_report_tag_data_uint32(
    691                         data,item_size);
    692                 break;
    693 
    694         case USB_HID_REPORT_TAG_REPORT_ID:
    695                 report_item->id = usb_hid_report_tag_data_uint32(data,
    696                         item_size);
    697                 return USB_HID_RESET_OFFSET;
    698                 break;
    699        
    700         case USB_HID_REPORT_TAG_PUSH:
    701         case USB_HID_REPORT_TAG_POP:
    702                 /*
    703                  * stack operations are done in top level parsing
    704                  * function
    705                  */
    706                 return tag;
    707                 break;
     493                case USB_HID_REPORT_TAG_USAGE_PAGE:
     494                        report_item->usage_page = usb_hid_report_tag_data_uint32(data, item_size);
     495                        break;
     496                case USB_HID_REPORT_TAG_LOGICAL_MINIMUM:
     497                        report_item->logical_minimum = USB_HID_UINT32_TO_INT32(usb_hid_report_tag_data_uint32(data,item_size), item_size * 8);
     498                        break;
     499                case USB_HID_REPORT_TAG_LOGICAL_MAXIMUM:
     500                        report_item->logical_maximum = USB_HID_UINT32_TO_INT32(usb_hid_report_tag_data_uint32(data,item_size), item_size * 8);
     501                        break;
     502                case USB_HID_REPORT_TAG_PHYSICAL_MINIMUM:
     503                        report_item->physical_minimum = USB_HID_UINT32_TO_INT32(usb_hid_report_tag_data_uint32(data,item_size), item_size * 8);
     504                        break;                 
     505                case USB_HID_REPORT_TAG_PHYSICAL_MAXIMUM:
     506                        report_item->physical_maximum = USB_HID_UINT32_TO_INT32(usb_hid_report_tag_data_uint32(data,item_size), item_size * 8);
     507
     508                        break;
     509                case USB_HID_REPORT_TAG_UNIT_EXPONENT:
     510                        report_item->unit_exponent = usb_hid_report_tag_data_uint32(data,item_size);
     511                        break;
     512                case USB_HID_REPORT_TAG_UNIT:
     513                        report_item->unit = usb_hid_report_tag_data_uint32(data,item_size);
     514                        break;
     515                case USB_HID_REPORT_TAG_REPORT_SIZE:
     516                        report_item->size = usb_hid_report_tag_data_uint32(data,item_size);
     517                        break;
     518                case USB_HID_REPORT_TAG_REPORT_COUNT:
     519                        report_item->count = usb_hid_report_tag_data_uint32(data,item_size);
     520                        break;
     521                case USB_HID_REPORT_TAG_REPORT_ID:
     522                        report_item->id = usb_hid_report_tag_data_uint32(data,item_size);
     523                        return USB_HID_RESET_OFFSET;
     524                        break;
     525                case USB_HID_REPORT_TAG_PUSH:
     526                case USB_HID_REPORT_TAG_POP:
     527                        /*
     528                         * stack operations are done in top level parsing
     529                         * function
     530                         */
     531                        return tag;
     532                        break;
    708533                       
    709         default:
    710                 return USB_HID_NO_ACTION;
     534                default:
     535                        return USB_HID_NO_ACTION;
    711536        }
    712537
     
    723548 * @return Error code
    724549 */
    725 int usb_hid_report_parse_local_tag(uint8_t tag, const uint8_t *data,
    726         size_t item_size, usb_hid_report_item_t *report_item,
    727         usb_hid_report_path_t *usage_path)
    728 {
    729         int32_t extended_usage;
    730        
     550int usb_hid_report_parse_local_tag(uint8_t tag, const uint8_t *data, size_t item_size,
     551                             usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path)
     552{
    731553        switch(tag) {
    732         case USB_HID_REPORT_TAG_USAGE:
    733                 switch(report_item->in_delimiter) {
    734                 case INSIDE_DELIMITER_SET:
    735                         /* nothing to do
    736                          * we catch only the first one
    737                          */
    738                         break;
    739        
    740                 case START_DELIMITER_SET:
    741                         report_item->in_delimiter = INSIDE_DELIMITER_SET;
    742                 case OUTSIDE_DELIMITER_SET:
    743                         extended_usage = ((report_item->usage_page) << 16);
    744                         extended_usage += usb_hid_report_tag_data_uint32(
    745                                 data,item_size);
    746 
    747                         report_item->usages[report_item->usages_count] =
    748                                 extended_usage;
    749 
    750                         report_item->usages_count++;
    751                         break;
    752                 }
    753                 break;
    754                
    755         case USB_HID_REPORT_TAG_USAGE_MINIMUM:                 
    756                 if (item_size == 3) {
    757                         // usage extended usages
    758                         report_item->extended_usage_page =
    759                             USB_HID_EXTENDED_USAGE_PAGE(
    760                             usb_hid_report_tag_data_uint32(data,item_size));
    761                            
    762 
    763                         report_item->usage_minimum =
    764                             USB_HID_EXTENDED_USAGE(
    765                             usb_hid_report_tag_data_uint32(data,item_size));
    766                 }
    767                 else {
    768                         report_item->usage_minimum =
    769                             usb_hid_report_tag_data_uint32(data,item_size);
    770                 }
    771                 break;
    772        
    773         case USB_HID_REPORT_TAG_USAGE_MAXIMUM:
    774                 if (item_size == 3) {
    775                         if(report_item->extended_usage_page !=
    776                             USB_HID_EXTENDED_USAGE_PAGE(       
    777                             usb_hid_report_tag_data_uint32(data,item_size))) {
    778                                
    779                                 return EINVAL;
    780                         }
    781                                
    782                         // usage extended usages
    783                         report_item->extended_usage_page =
    784                                 USB_HID_EXTENDED_USAGE_PAGE(
    785                                 usb_hid_report_tag_data_uint32(data,item_size));
    786 
    787                         report_item->usage_maximum =
    788                                 USB_HID_EXTENDED_USAGE(
    789                                 usb_hid_report_tag_data_uint32(data,item_size));
    790                 }
    791                 else {
    792                         report_item->usage_maximum =
    793                                 usb_hid_report_tag_data_uint32(data,item_size);
    794                 }
    795 
    796                 // vlozit zaznamy do pole usages
    797                 int32_t i;
    798                 for(i = report_item->usage_minimum;
    799                     i <= report_item->usage_maximum; i++) {
    800 
    801                         if(report_item->extended_usage_page) {
    802                             report_item->usages[report_item->usages_count++] =
    803                                 (report_item->extended_usage_page << 16) + i;
    804                         }
    805                         else {                 
    806                             report_item->usages[report_item->usages_count++] =
    807                                 (report_item->usage_page << 16) + i;
    808                         }
    809                 }
    810                 report_item->extended_usage_page = 0;
    811                        
    812                 break;
    813                
    814         case USB_HID_REPORT_TAG_DESIGNATOR_INDEX:
    815                 report_item->designator_index =
    816                         usb_hid_report_tag_data_uint32(data,item_size);
    817                 break;
    818        
    819         case USB_HID_REPORT_TAG_DESIGNATOR_MINIMUM:
    820                 report_item->designator_minimum =
    821                         usb_hid_report_tag_data_uint32(data,item_size);
    822                 break;
    823 
    824         case USB_HID_REPORT_TAG_DESIGNATOR_MAXIMUM:
    825                 report_item->designator_maximum =
    826                         usb_hid_report_tag_data_uint32(data,item_size);
    827                 break;
    828 
    829         case USB_HID_REPORT_TAG_STRING_INDEX:
    830                 report_item->string_index =
    831                         usb_hid_report_tag_data_uint32(data,item_size);
    832                 break;
    833 
    834         case USB_HID_REPORT_TAG_STRING_MINIMUM:
    835                 report_item->string_minimum =
    836                         usb_hid_report_tag_data_uint32(data,item_size);
    837                 break;
    838 
    839         case USB_HID_REPORT_TAG_STRING_MAXIMUM:
    840                 report_item->string_maximum =
    841                         usb_hid_report_tag_data_uint32(data,item_size);
    842                 break;                 
    843 
    844         case USB_HID_REPORT_TAG_DELIMITER:
    845                 report_item->in_delimiter =
    846                         usb_hid_report_tag_data_uint32(data,item_size);
    847                 break;
    848 
    849         default:
    850                 return USB_HID_NO_ACTION;
     554                case USB_HID_REPORT_TAG_USAGE:
     555                        switch(report_item->in_delimiter) {
     556                                case INSIDE_DELIMITER_SET:
     557                                        // nothing to do
     558                                        break;
     559                                case START_DELIMITER_SET:
     560                                        report_item->in_delimiter = INSIDE_DELIMITER_SET;
     561                                case OUTSIDE_DELIMITER_SET:
     562                                        report_item->usages[report_item->usages_count] = usb_hid_report_tag_data_uint32(data,item_size);
     563                                        report_item->usages_count++;
     564                                        break;
     565                        }
     566                        break;
     567                case USB_HID_REPORT_TAG_USAGE_MINIMUM:
     568                        if (item_size == 3) {
     569                                // usage extended usages
     570                                report_item->extended_usage_page = (usb_hid_report_tag_data_uint32(data,item_size) & 0xFF00) >> 16;
     571                                report_item->usage_minimum = usb_hid_report_tag_data_uint32(data,item_size) & 0xFF;
     572                        }
     573                        else {
     574                                report_item->usage_minimum = usb_hid_report_tag_data_uint32(data,item_size);
     575                        }
     576                        break;
     577                case USB_HID_REPORT_TAG_USAGE_MAXIMUM:
     578                        if (item_size == 3) {
     579                                // usage extended usages
     580                                report_item->extended_usage_page = (usb_hid_report_tag_data_uint32(data,item_size) & 0xFF00) >> 16;
     581                                report_item->usage_maximum = usb_hid_report_tag_data_uint32(data,item_size) & 0xFF;
     582                        }
     583                        else {
     584                                report_item->usage_maximum = usb_hid_report_tag_data_uint32(data,item_size);
     585                        }
     586                        break;
     587                case USB_HID_REPORT_TAG_DESIGNATOR_INDEX:
     588                        report_item->designator_index = usb_hid_report_tag_data_uint32(data,item_size);
     589                        break;
     590                case USB_HID_REPORT_TAG_DESIGNATOR_MINIMUM:
     591                        report_item->designator_minimum = usb_hid_report_tag_data_uint32(data,item_size);
     592                        break;
     593                case USB_HID_REPORT_TAG_DESIGNATOR_MAXIMUM:
     594                        report_item->designator_maximum = usb_hid_report_tag_data_uint32(data,item_size);
     595                        break;
     596                case USB_HID_REPORT_TAG_STRING_INDEX:
     597                        report_item->string_index = usb_hid_report_tag_data_uint32(data,item_size);
     598                        break;
     599                case USB_HID_REPORT_TAG_STRING_MINIMUM:
     600                        report_item->string_minimum = usb_hid_report_tag_data_uint32(data,item_size);
     601                        break;
     602                case USB_HID_REPORT_TAG_STRING_MAXIMUM:
     603                        report_item->string_maximum = usb_hid_report_tag_data_uint32(data,item_size);
     604                        break;                 
     605                case USB_HID_REPORT_TAG_DELIMITER:
     606                        report_item->in_delimiter = usb_hid_report_tag_data_uint32(data,item_size);
     607                        break;
     608
     609                default:
     610                        return USB_HID_NO_ACTION;
    851611        }
    852612
    853613        return EOK;
    854614}
    855 /*---------------------------------------------------------------------------*/
    856615
    857616/**
     
    874633        return result;
    875634}
    876 /*---------------------------------------------------------------------------*/
    877635
    878636/**
     
    895653        for(item = head->next; item != head; item = item->next) {
    896654               
    897                 report_item = list_get_instance(item, usb_hid_report_field_t,
    898                                 link);
     655                report_item = list_get_instance(item, usb_hid_report_field_t, link);
    899656
    900657                usb_log_debug("\t\tOFFSET: %X\n", report_item->offset);
    901                 usb_log_debug("\t\tSIZE: %zu\n", report_item->size);
    902                 usb_log_debug("\t\tLOGMIN: %d\n",
    903                         report_item->logical_minimum);
    904                 usb_log_debug("\t\tLOGMAX: %d\n",
    905                         report_item->logical_maximum);         
    906                 usb_log_debug("\t\tPHYMIN: %d\n",
    907                         report_item->physical_minimum);         
    908                 usb_log_debug("\t\tPHYMAX: %d\n",
    909                         report_item->physical_maximum);                         
    910                 usb_log_debug("\t\ttUSAGEMIN: %X\n",
    911                         report_item->usage_minimum);
    912                 usb_log_debug("\t\tUSAGEMAX: %X\n",
    913                                report_item->usage_maximum);
    914                 usb_log_debug("\t\tUSAGES COUNT: %zu\n",
    915                         report_item->usages_count);
     658                usb_log_debug("\t\tSIZE: %zu\n", report_item->size);                           
     659                usb_log_debug("\t\tLOGMIN: %d\n", report_item->logical_minimum);
     660                usb_log_debug("\t\tLOGMAX: %d\n", report_item->logical_maximum);               
     661                usb_log_debug("\t\tPHYMIN: %d\n", report_item->physical_minimum);               
     662                usb_log_debug("\t\tPHYMAX: %d\n", report_item->physical_maximum);                               
     663                usb_log_debug("\t\ttUSAGEMIN: %X\n", report_item->usage_minimum);
     664                usb_log_debug("\t\tUSAGEMAX: %X\n", report_item->usage_maximum);
    916665
    917666                usb_log_debug("\t\tVALUE: %X\n", report_item->value);
     
    919668                usb_log_debug("\t\tUSAGE PAGE: %X\n", report_item->usage_page);
    920669               
    921                 usb_hid_print_usage_path(report_item->collection_path);
     670                //usb_hid_print_usage_path(report_item->collection_path);
    922671
    923672                usb_log_debug("\n");           
     
    925674        }
    926675
    927 }
    928 /*---------------------------------------------------------------------------*/
    929 
     676
     677}
    930678/**
    931679 * Prints content of given report descriptor in human readable format.
     
    944692
    945693        while(report_it != &report->reports) {
    946                 report_des = list_get_instance(report_it,
    947                         usb_hid_report_description_t, link);
     694                report_des = list_get_instance(report_it, usb_hid_report_description_t, link);
    948695                usb_log_debug("Report ID: %d\n", report_des->report_id);
    949696                usb_log_debug("\tType: %d\n", report_des->type);
    950697                usb_log_debug("\tLength: %zu\n", report_des->bit_length);               
    951                 usb_log_debug("\tB Size: %zu\n",
    952                         usb_hid_report_byte_size(report,
    953                                 report_des->report_id,
    954                                 report_des->type));
    955698                usb_log_debug("\tItems: %zu\n", report_des->item_length);               
    956699
    957700                usb_hid_descriptor_print_list(&report_des->report_items);
    958701
     702
     703                link_t *path_it = report->collection_paths.next;
     704                while(path_it != &report->collection_paths) {
     705                        usb_hid_print_usage_path (list_get_instance(path_it, usb_hid_report_path_t, link));
     706                        path_it = path_it->next;
     707                }
     708               
    959709                report_it = report_it->next;
    960710        }
    961711}
    962 /*---------------------------------------------------------------------------*/
    963712
    964713/**
     
    985734
    986735                while(!list_empty(&report_item->usage_path->link)) {
    987                     usb_hid_report_remove_last_item(report_item->usage_path);
     736                        usb_hid_report_remove_last_item(report_item->usage_path);
    988737                }
    989738
     
    997746       
    998747}
    999 /*---------------------------------------------------------------------------*/
    1000748
    1001749/** Frees the HID report descriptor parser structure
     
    1013761        usb_hid_report_path_t *path;
    1014762        while(!list_empty(&report->collection_paths)) {
    1015                 path = list_get_instance(report->collection_paths.next,
    1016                                 usb_hid_report_path_t, link);
    1017 
     763                path = list_get_instance(report->collection_paths.next, usb_hid_report_path_t, link);
    1018764                usb_hid_report_path_free(path);         
    1019765        }
     
    1023769        usb_hid_report_field_t *field;
    1024770        while(!list_empty(&report->reports)) {
    1025                 report_des = list_get_instance(report->reports.next,
    1026                                 usb_hid_report_description_t, link);
    1027 
     771                report_des = list_get_instance(report->reports.next, usb_hid_report_description_t, link);
    1028772                list_remove(&report_des->link);
    1029773               
    1030774                while(!list_empty(&report_des->report_items)) {
    1031                         field = list_get_instance(
    1032                                 report_des->report_items.next,
    1033                                 usb_hid_report_field_t, link);
    1034 
     775                        field = list_get_instance(report_des->report_items.next, usb_hid_report_field_t, link);
    1035776                        list_remove(&field->link);
    1036777
     
    1043784        return;
    1044785}
    1045 /*---------------------------------------------------------------------------*/
    1046786
    1047787/**
  • uspace/lib/usbhid/src/hidiface.c

    r6bfaab5 r88be3a0b  
    4646 * @return Number of usages returned or negative error code.
    4747 */
    48 int usbhid_dev_get_event_length(int dev_phone, size_t *size)
     48int usbhid_dev_get_event_length(int dev_phone)
    4949{
    5050        if (dev_phone < 0) {
     
    5656            IPC_M_USBHID_GET_EVENT_LENGTH, &len);
    5757        if (rc == EOK) {
    58                 if (size != NULL) {
    59                         *size = (size_t) len;
    60                 }
     58                return (int) len;
     59        } else {
     60                return rc;
    6161        }
    62        
    63         return rc;
    6462}
    6563
     
    7674 * @return Error code.
    7775 */
    78 int usbhid_dev_get_event(int dev_phone, uint8_t *buf,
    79     size_t size, size_t *actual_size, int *event_nr, unsigned int flags)
     76int usbhid_dev_get_event(int dev_phone, uint16_t *usage_pages, uint16_t *usages,
     77    size_t usage_count, size_t *actual_usage_count, unsigned int flags)
    8078{
    8179        if (dev_phone < 0) {
    8280                return EINVAL;
    8381        }
    84         if ((buf == NULL)) {
     82        if ((usage_pages == NULL) || (usages == NULL)) {
    8583                return ENOMEM;
    8684        }
    87         if (size == 0) {
     85        if (usage_count == 0) {
    8886                return EINVAL;
    8987        }
    90        
    91 //      if (size == 0) {
    92 //              return EOK;
    93 //      }
    9488
    95         size_t buffer_size =  size;
    96         uint8_t *buffer = malloc(buffer_size);
     89        size_t buffer_size = sizeof(uint16_t) * usage_count * 2;
     90        uint16_t *buffer = malloc(buffer_size);
    9791        if (buffer == NULL) {
    9892                return ENOMEM;
    9993        }
    10094
    101         ipc_call_t opening_request_call;
    10295        aid_t opening_request = async_send_2(dev_phone,
    10396            DEV_IFACE_ID(USBHID_DEV_IFACE), IPC_M_USBHID_GET_EVENT,
    104             flags, &opening_request_call);
     97            flags, NULL);
    10598        if (opening_request == 0) {
    10699                free(buffer);
     
    135128        }
    136129
    137         size_t act_size = IPC_GET_ARG2(data_request_call);
     130        size_t actual_size = IPC_GET_ARG2(data_request_call);
     131        size_t items = actual_size / 2;
    138132
    139133        /* Copy the individual items. */
    140         memcpy(buf, buffer, act_size);
    141 //      memcpy(usages, buffer + items, items * sizeof(int32_t));
     134        memcpy(usage_pages, buffer, items * sizeof(uint16_t));
     135        memcpy(usages, buffer + items, items * sizeof(uint16_t));
    142136
    143         if (actual_size != NULL) {
    144                 *actual_size = act_size;
    145         }
    146        
    147         if (event_nr != NULL) {
    148                 *event_nr = IPC_GET_ARG1(opening_request_call);
    149         }
    150 
    151         return EOK;
    152 }
    153 
    154 
    155 int usbhid_dev_get_report_descriptor_length(int dev_phone, size_t *size)
    156 {
    157         if (dev_phone < 0) {
    158                 return EINVAL;
    159         }
    160 
    161         sysarg_t arg_size;
    162         int rc = async_req_1_1(dev_phone, DEV_IFACE_ID(USBHID_DEV_IFACE),
    163             IPC_M_USBHID_GET_REPORT_DESCRIPTOR_LENGTH, &arg_size);
    164         if (rc == EOK) {
    165                 if (size != NULL) {
    166                         *size = (size_t) arg_size;
    167                 }
    168         }
    169         return rc;
    170 }
    171 
    172 int usbhid_dev_get_report_descriptor(int dev_phone, uint8_t *buf, size_t size,
    173     size_t *actual_size)
    174 {
    175         if (dev_phone < 0) {
    176                 return EINVAL;
    177         }
    178         if ((buf == NULL)) {
    179                 return ENOMEM;
    180         }
    181         if (size == 0) {
    182                 return EINVAL;
    183         }
    184 
    185         aid_t opening_request = async_send_1(dev_phone,
    186             DEV_IFACE_ID(USBHID_DEV_IFACE), IPC_M_USBHID_GET_REPORT_DESCRIPTOR,
    187             NULL);
    188         if (opening_request == 0) {
    189                 return ENOMEM;
    190         }
    191 
    192         ipc_call_t data_request_call;
    193         aid_t data_request = async_data_read(dev_phone, buf, size,
    194             &data_request_call);
    195         if (data_request == 0) {
    196                 async_wait_for(opening_request, NULL);
    197                 return ENOMEM;
    198         }
    199 
    200         sysarg_t data_request_rc;
    201         sysarg_t opening_request_rc;
    202         async_wait_for(data_request, &data_request_rc);
    203         async_wait_for(opening_request, &opening_request_rc);
    204 
    205         if (data_request_rc != EOK) {
    206                 /* Prefer return code of the opening request. */
    207                 if (opening_request_rc != EOK) {
    208                         return (int) opening_request_rc;
    209                 } else {
    210                         return (int) data_request_rc;
    211                 }
    212         }
    213 
    214         if (opening_request_rc != EOK) {
    215                 return (int) opening_request_rc;
    216         }
    217 
    218         size_t act_size = IPC_GET_ARG2(data_request_call);
    219 
    220         if (actual_size != NULL) {
    221                 *actual_size = act_size;
     137        if (actual_usage_count != NULL) {
     138                *actual_usage_count = items;
    222139        }
    223140
  • uspace/lib/usbhid/src/hidparser.c

    r6bfaab5 r88be3a0b  
    3131 */
    3232/** @file
    33  * USB HID report data parser implementation.
     33 * HID report descriptor and report data parser implementation.
    3434 */
    3535#include <usb/hid/hidparser.h>
     
    4141#include <assert.h>
    4242
    43 /*---------------------------------------------------------------------------*/
     43
    4444/*
    4545 * Data translation private functions
    4646 */
    4747uint32_t usb_hid_report_tag_data_uint32(const uint8_t *data, size_t size);
    48 
     48//inline size_t usb_hid_count_item_offset(usb_hid_report_item_t * report_item, size_t offset);
    4949int usb_hid_translate_data(usb_hid_report_field_t *item, const uint8_t *data);
    50 
    51 uint32_t usb_hid_translate_data_reverse(usb_hid_report_field_t *item,
    52         int32_t value);
    53 
     50uint32_t usb_hid_translate_data_reverse(usb_hid_report_field_t *item, int32_t value);
    5451int usb_pow(int a, int b);
    5552
    56 /*---------------------------------------------------------------------------*/
    5753
    5854// TODO: tohle ma bejt asi jinde
     
    6056{
    6157        switch(b) {
    62         case 0:
    63                 return 1;
    64                 break;
    65         case 1:
    66                 return a;
    67                 break;
    68         default:
    69                 return a * usb_pow(a, b-1);
    70                 break;
    71         }
    72 }
    73 /*---------------------------------------------------------------------------*/
    74 
    75 /** Returns size of report of specified report id and type in items
    76  *
    77  * @param parser Opaque report parser structure
    78  * @param report_id
    79  * @param type
    80  * @return Number of items in specified report
    81  */
    82 size_t usb_hid_report_size(usb_hid_report_t *report, uint8_t report_id,
    83                            usb_hid_report_type_t type)
    84 {
    85         usb_hid_report_description_t *report_des;
    86 
    87         if(report == NULL) {
    88                 return 0;
    89         }
    90 
    91         report_des = usb_hid_report_find_description (report, report_id, type);
    92         if(report_des == NULL){
    93                 return 0;
    94         }
    95         else {
    96                 return report_des->item_length;
    97         }
    98 }
    99 
    100 /** Returns size of report of specified report id and type in bytes
    101  *
    102  * @param parser Opaque report parser structure
    103  * @param report_id
    104  * @param type
    105  * @return Number of items in specified report
    106  */
    107 size_t usb_hid_report_byte_size(usb_hid_report_t *report, uint8_t report_id,
    108                            usb_hid_report_type_t type)
    109 {
    110         usb_hid_report_description_t *report_des;
    111 
    112         if(report == NULL) {
    113                 return 0;
    114         }
    115 
    116         report_des = usb_hid_report_find_description (report, report_id, type);
    117         if(report_des == NULL){
    118                 return 0;
    119         }
    120         else {
    121                 return ((report_des->bit_length + 7) / 8) ;
    122         }
    123 }
    124 /*---------------------------------------------------------------------------*/
     58                case 0:
     59                        return 1;
     60                        break;
     61                case 1:
     62                        return a;
     63                        break;
     64                default:
     65                        return a * usb_pow(a, b-1);
     66                        break;
     67        }
     68}
     69
     70
     71
    12572
    12673/** Parse and act upon a HID report.
     
    13279 * @return Error code.
    13380 */
    134 int usb_hid_parse_report(const usb_hid_report_t *report, const uint8_t *data,
    135         size_t size, uint8_t *report_id)
     81int usb_hid_parse_report(const usb_hid_report_t *report,
     82    const uint8_t *data, size_t size, uint8_t *report_id)
    13683{
    13784        link_t *list_item;
     
    14087        usb_hid_report_description_t *report_des;
    14188        usb_hid_report_type_t type = USB_HID_REPORT_TYPE_INPUT;
    142        
     89
    14390        if(report == NULL) {
    14491                return EINVAL;
     
    154101
    155102        report_des = usb_hid_report_find_description(report, *report_id, type);
    156         if(report_des == NULL) {
    157                 return EINVAL;
    158         }
    159103
    160104        /* read data */
     
    162106        while(list_item != &(report_des->report_items)) {
    163107
    164                 item = list_get_instance(list_item, usb_hid_report_field_t,
    165                                 link);
     108                item = list_get_instance(list_item, usb_hid_report_field_t, link);
    166109
    167110                if(USB_HID_ITEM_FLAG_CONSTANT(item->item_flags) == 0) {
     
    170113
    171114                                // array
    172                                 item->value =
    173                                         usb_hid_translate_data(item, data);
    174                
    175                                 item->usage = USB_HID_EXTENDED_USAGE(
    176                                     item->usages[item->value - item->physical_minimum]);
    177 
    178                                 item->usage_page = USB_HID_EXTENDED_USAGE_PAGE(
    179                                     item->usages[item->value - item->physical_minimum]);
    180 
    181                                 usb_hid_report_set_last_item (item->collection_path,
    182                                     USB_HID_TAG_CLASS_GLOBAL, item->usage_page);
    183 
    184                                 usb_hid_report_set_last_item (item->collection_path,
    185                                     USB_HID_TAG_CLASS_LOCAL, item->usage);
    186                                
     115                                item->value = usb_hid_translate_data(item, data);
     116                            item->usage = (item->value - item->physical_minimum) + item->usage_minimum;
    187117                        }
    188118                        else {
     
    193123                list_item = list_item->next;
    194124        }
    195        
     125           
    196126        return EOK;
    197127       
    198128}
    199129
    200 /*---------------------------------------------------------------------------*/
    201130/**
    202131 * Translate data from the report as specified in report descriptor item
     
    204133 * @param item Report descriptor item with definition of translation
    205134 * @param data Data to translate
     135 * @param j Index of processed field in report descriptor item
    206136 * @return Translated data
    207137 */
     
    272202        }
    273203
    274         return (int)(((value - item->logical_minimum) / resolution) +
    275                 item->physical_minimum);
    276        
    277 }
    278 
    279 /*---------------------------------------------------------------------------*/
    280 /* OUTPUT API */
     204        return (int)(((value - item->logical_minimum) / resolution) + item->physical_minimum);
     205       
     206}
     207
     208/**
     209 * Returns number of items in input report which are accessible by given usage path
     210 *
     211 * @param parser Opaque report descriptor structure
     212 * @param path Usage path specification
     213 * @param flags Usage path comparison flags
     214 * @return Number of items in input report
     215 */
     216size_t usb_hid_report_input_length(const usb_hid_report_t *report,
     217        usb_hid_report_path_t *path, int flags)
     218{       
     219       
     220        size_t ret = 0;
     221
     222        if(report == NULL) {
     223                return 0;
     224        }
     225
     226        usb_hid_report_description_t *report_des;
     227        report_des = usb_hid_report_find_description (report, path->report_id, USB_HID_REPORT_TYPE_INPUT);
     228        if(report_des == NULL) {
     229                return 0;
     230        }
     231
     232        link_t *field_it = report_des->report_items.next;
     233        usb_hid_report_field_t *field;
     234        while(field_it != &report_des->report_items) {
     235
     236                field = list_get_instance(field_it, usb_hid_report_field_t, link);
     237                if(USB_HID_ITEM_FLAG_CONSTANT(field->item_flags) == 0) {
     238                       
     239                        usb_hid_report_path_append_item (field->collection_path, field->usage_page, field->usage);
     240                        if(usb_hid_report_compare_usage_path (field->collection_path, path, flags) == EOK) {
     241                                ret++;
     242                        }
     243                        usb_hid_report_remove_last_item (field->collection_path);
     244                }
     245               
     246                field_it = field_it->next;
     247        }
     248
     249        return ret;
     250        }
     251
     252/*** OUTPUT API **/
    281253
    282254/**
     
    288260 * @return Returns allocated output buffer for specified output
    289261 */
    290 uint8_t *usb_hid_report_output(usb_hid_report_t *report, size_t *size,
    291         uint8_t report_id)
     262uint8_t *usb_hid_report_output(usb_hid_report_t *report, size_t *size, uint8_t report_id)
    292263{
    293264        if(report == NULL) {
     
    299270        usb_hid_report_description_t *report_des = NULL;
    300271        while(report_it != &report->reports) {
    301                 report_des = list_get_instance(report_it,
    302                         usb_hid_report_description_t, link);
    303                
    304                 if((report_des->report_id == report_id) &&
    305                         (report_des->type == USB_HID_REPORT_TYPE_OUTPUT)){
     272                report_des = list_get_instance(report_it, usb_hid_report_description_t, link);
     273                if((report_des->report_id == report_id) && (report_des->type == USB_HID_REPORT_TYPE_OUTPUT)){
    306274                        break;
    307275                }
     
    334302                free (output);
    335303        }
     304}
     305
     306/** Returns size of output for given usage path
     307 *
     308 * @param parser Opaque report parser structure
     309 * @param path Usage path specified which items will be thought for the output
     310 * @param flags Flags of usage path structure comparison
     311 * @return Number of items matching the given usage path
     312 */
     313size_t usb_hid_report_output_size(usb_hid_report_t *report,
     314                                  usb_hid_report_path_t *path, int flags)
     315{
     316        size_t ret = 0;
     317        usb_hid_report_description_t *report_des;
     318
     319        if(report == NULL) {
     320                return 0;
     321        }
     322
     323        report_des = usb_hid_report_find_description (report, path->report_id, USB_HID_REPORT_TYPE_OUTPUT);
     324        if(report_des == NULL){
     325                return 0;
     326        }
     327       
     328        link_t *field_it = report_des->report_items.next;
     329        usb_hid_report_field_t *field;
     330        while(field_it != &report_des->report_items) {
     331
     332                field = list_get_instance(field_it, usb_hid_report_field_t, link);
     333                if(USB_HID_ITEM_FLAG_CONSTANT(field->item_flags) == 0){
     334                        usb_hid_report_path_append_item (field->collection_path, field->usage_page, field->usage);
     335                        if(usb_hid_report_compare_usage_path (field->collection_path, path, flags) == EOK) {
     336                                ret++;
     337                        }
     338                        usb_hid_report_remove_last_item (field->collection_path);
     339                }
     340               
     341                field_it = field_it->next;
     342        }
     343
     344        return ret;
     345       
    336346}
    337347
     
    345355 * @return Error code
    346356 */
    347 int usb_hid_report_output_translate(usb_hid_report_t *report,
    348         uint8_t report_id, uint8_t *buffer, size_t size)
     357int usb_hid_report_output_translate(usb_hid_report_t *report, uint8_t report_id,
     358                                    uint8_t *buffer, size_t size)
    349359{
    350360        link_t *item;   
     
    362372        }
    363373
     374        usb_log_debug("OUTPUT BUFFER: %s\n", usb_debug_str_buffer(buffer,size, 0));
     375       
    364376        usb_hid_report_description_t *report_des;
    365         report_des = usb_hid_report_find_description (report, report_id,
    366                 USB_HID_REPORT_TYPE_OUTPUT);
    367        
     377        report_des = usb_hid_report_find_description (report, report_id, USB_HID_REPORT_TYPE_OUTPUT);
    368378        if(report_des == NULL){
    369379                return EINVAL;
     
    375385                report_item = list_get_instance(item, usb_hid_report_field_t, link);
    376386
    377                 if(USB_HID_ITEM_FLAG_VARIABLE(report_item->item_flags) == 0) {
     387                        if(USB_HID_ITEM_FLAG_VARIABLE(report_item->item_flags) == 0) {
    378388                                       
    379                         // array
    380                         value = usb_hid_translate_data_reverse(report_item,
    381                                 report_item->value);
    382 
    383                         offset = report_item->offset;
    384                         length = report_item->size;
    385                 }
    386                 else {
    387                         // variable item
    388                         value  = usb_hid_translate_data_reverse(report_item,
    389                                 report_item->value);
    390 
    391                         offset = report_item->offset;
    392                         length = report_item->size;
    393                 }
    394 
    395                 usb_log_debug("\ttranslated value: %x\n", value);
    396 
    397                 if((offset/8) == ((offset+length-1)/8)) {
    398                         // je to v jednom bytu
    399                         if(((size_t)(offset/8) >= size) ||
    400                                 ((size_t)(offset+length-1)/8) >= size) {
    401                                 break; // TODO ErrorCode
    402                         }
    403                         size_t shift = 8 - offset%8 - length;
    404                         value = value << shift;                                                 
    405                         value = value & (((1 << length)-1) << shift);
     389                                // array
     390                                value = usb_hid_translate_data_reverse(report_item, report_item->value);
     391                                offset = report_item->offset;
     392                                length = report_item->size;
     393                        }
     394                        else {
     395                                // variable item
     396                                value  = usb_hid_translate_data_reverse(report_item, report_item->value);
     397                                offset = report_item->offset;
     398                                length = report_item->size;
     399                        }
     400
     401                        if((offset/8) == ((offset+length-1)/8)) {
     402                                // je to v jednom bytu
     403                                if(((size_t)(offset/8) >= size) || ((size_t)(offset+length-1)/8) >= size) {
     404                                        break; // TODO ErrorCode
     405                                }
     406
     407                                size_t shift = 8 - offset%8 - length;
     408
     409                                value = value << shift;                                                 
     410                                value = value & (((1 << length)-1) << shift);
    406411                               
    407                         uint8_t mask = 0;
    408                         mask = 0xff - (((1 << length) - 1) << shift);
    409                         buffer[offset/8] = (buffer[offset/8] & mask) | value;
    410                 }
    411                 else {
    412                         int i = 0;
    413                         uint8_t mask = 0;
    414                         for(i = (offset/8); i <= ((offset+length-1)/8); i++) {
    415                                 if(i == (offset/8)) {
    416                                         tmp_value = value;
    417                                         tmp_value = tmp_value &
    418                                                 ((1 << (8-(offset%8)))-1);
    419 
    420                                         tmp_value = tmp_value << (offset%8);
    421        
    422                                         mask = ~(((1 << (8-(offset%8)))-1) <<
    423                                                         (offset%8));
    424 
    425                                         buffer[i] = (buffer[i] & mask) |
    426                                                 tmp_value;
     412                                uint8_t mask = 0;
     413                                mask = 0xff - (((1 << length) - 1) << shift);
     414                                buffer[offset/8] = (buffer[offset/8] & mask) | value;
     415                        }
     416                        else {
     417                                int i = 0;
     418                                uint8_t mask = 0;
     419                                for(i = (offset/8); i <= ((offset+length-1)/8); i++) {
     420                                        if(i == (offset/8)) {
     421                                                tmp_value = value;
     422                                                tmp_value = tmp_value & ((1 << (8-(offset%8)))-1);                             
     423                                                tmp_value = tmp_value << (offset%8);
     424       
     425                                                mask = ~(((1 << (8-(offset%8)))-1) << (offset%8));
     426                                                buffer[i] = (buffer[i] & mask) | tmp_value;                     
     427                                        }
     428                                        else if (i == ((offset + length -1)/8)) {
     429                                               
     430                                                value = value >> (length - ((offset + length) % 8));
     431                                                value = value & ((1 << (length - ((offset + length) % 8))) - 1);
     432                               
     433                                                mask = (1 << (length - ((offset + length) % 8))) - 1;
     434                                                buffer[i] = (buffer[i] & mask) | value;
     435                                        }
     436                                        else {
     437                                                buffer[i] = value & (0xFF << i);
     438                                        }
    427439                                }
    428                                 else if (i == ((offset + length -1)/8)) {
    429                                        
    430                                         value = value >> (length -
    431                                                 ((offset + length) % 8));
    432 
    433                                         value = value & ((1 << (length -
    434                                                 ((offset + length) % 8))) - 1);
    435                                
    436                                         mask = (1 << (length -
    437                                                 ((offset + length) % 8))) - 1;
    438 
    439                                         buffer[i] = (buffer[i] & mask) | value;
    440                                 }
    441                                 else {
    442                                         buffer[i] = value & (0xFF << i);
    443                                 }
    444                         }
    445                 }
     440                        }
     441
    446442
    447443                // reset value
     
    451447        }
    452448       
     449        usb_log_debug("OUTPUT BUFFER: %s\n", usb_debug_str_buffer(buffer,size, 0));
     450
    453451        return EOK;
    454452}
    455453
    456 /*---------------------------------------------------------------------------*/
    457454/**
    458455 * Translate given data for putting them into the outoput report
     
    461458 * @return ranslated value
    462459 */
    463 uint32_t usb_hid_translate_data_reverse(usb_hid_report_field_t *item,
    464         int value)
     460uint32_t usb_hid_translate_data_reverse(usb_hid_report_field_t *item, int value)
    465461{
    466462        int ret=0;
     
    476472        }
    477473       
    478         // variable item
    479         if(item->physical_maximum == item->physical_minimum){
    480             resolution = 1;
     474
     475        if((USB_HID_ITEM_FLAG_VARIABLE(item->item_flags) == 0)) {
     476
     477                // variable item
     478                if(item->physical_maximum == item->physical_minimum){
     479                    resolution = 1;
     480                }
     481                else {
     482                    resolution = (item->logical_maximum - item->logical_minimum) /
     483                        ((item->physical_maximum - item->physical_minimum) *
     484                        (usb_pow(10,(item->unit_exponent))));
     485                }
     486
     487                ret = ((value - item->physical_minimum) * resolution) + item->logical_minimum;
    481488        }
    482489        else {
    483             resolution = (item->logical_maximum - item->logical_minimum) /
    484                 ((item->physical_maximum - item->physical_minimum) *
    485                 (usb_pow(10,(item->unit_exponent))));
    486         }
    487 
    488         ret = ((value - item->physical_minimum) * resolution) +
    489                 item->logical_minimum;
    490 
    491         usb_log_debug("\tvalue(%x), resolution(%x), phymin(%x) logmin(%x), \
    492                 ret(%x)\n", value, resolution, item->physical_minimum,
    493                 item->logical_minimum, ret);
    494        
     490                // bitmapa
     491                if(value == 0) {
     492                        ret = 0;
     493                }
     494                else {
     495                        size_t bitmap_idx = (value - item->usage_minimum);
     496                        ret = 1 << bitmap_idx;
     497                }
     498        }
     499
    495500        if((item->logical_minimum < 0) || (item->logical_maximum < 0)){
    496501                return USB_HID_INT32_TO_UINT32(ret, item->size);
    497502        }
    498         return (int32_t)0 + ret;
    499 }
    500 
    501 /*---------------------------------------------------------------------------*/
    502 /**
    503  * Clones given state table
    504  *
    505  * @param item State table to clone
    506  * @return Pointer to the cloned item
    507  */
    508 usb_hid_report_item_t *usb_hid_report_item_clone(
    509         const usb_hid_report_item_t *item)
     503        return (int32_t)ret;
     504}
     505
     506usb_hid_report_item_t *usb_hid_report_item_clone(const usb_hid_report_item_t *item)
    510507{
    511508        usb_hid_report_item_t *new_report_item;
     
    520517}
    521518
    522 /*---------------------------------------------------------------------------*/
    523 /**
    524  * Function for sequence walking through the report. Returns next field in the
    525  * report or the first one when no field is given.
    526  *
    527  * @param report Searched report structure
    528  * @param field Current field. If NULL is given, the first one in the report
    529  * is returned. Otherwise the next one i nthe list is returned.
    530  * @param path Usage path specifying which fields wa are interested in.
    531  * @param flags Flags defining mode of usage paths comparison
    532  * @param type Type of report we search.
    533  * @retval NULL if no field is founded
    534  * @retval Pointer to the founded report structure when founded
    535  */
     519
    536520usb_hid_report_field_t *usb_hid_report_get_sibling(usb_hid_report_t *report,
    537         usb_hid_report_field_t *field, usb_hid_report_path_t *path, int flags,
    538         usb_hid_report_type_t type)
    539 {
    540         usb_hid_report_description_t *report_des =
    541                 usb_hid_report_find_description(report, path->report_id, type);
    542 
     521                                                        usb_hid_report_field_t *field,
     522                            usb_hid_report_path_t *path, int flags,
     523                            usb_hid_report_type_t type)
     524{
     525        usb_hid_report_description_t *report_des = usb_hid_report_find_description (report, path->report_id, type);
    543526        link_t *field_it;
    544527       
     
    548531
    549532        if(field == NULL){
     533                // vezmu prvni co mathuje podle path!!
    550534                field_it = report_des->report_items.next;
    551535        }
     
    555539
    556540        while(field_it != &report_des->report_items) {
    557                 field = list_get_instance(field_it, usb_hid_report_field_t,
    558                         link);
     541                field = list_get_instance(field_it, usb_hid_report_field_t, link);
    559542
    560543                if(USB_HID_ITEM_FLAG_CONSTANT(field->item_flags) == 0) {
    561                         usb_hid_report_path_append_item (
    562                                 field->collection_path, field->usage_page,
    563                                 field->usage);
    564 
    565                         if(usb_hid_report_compare_usage_path(
    566                                 field->collection_path, path, flags) == EOK){
    567 
    568                                 usb_hid_report_remove_last_item(
    569                                         field->collection_path);
    570 
     544                        usb_hid_report_path_append_item (field->collection_path, field->usage_page, field->usage);
     545                        if(usb_hid_report_compare_usage_path (field->collection_path, path, flags) == EOK){
     546                                usb_hid_report_remove_last_item (field->collection_path);
    571547                                return field;
    572548                        }
    573                         usb_hid_report_remove_last_item (
    574                                 field->collection_path);
     549                        usb_hid_report_remove_last_item (field->collection_path);
    575550                }
    576551                field_it = field_it->next;
     
    580555}
    581556
    582 /*---------------------------------------------------------------------------*/
    583 /**
    584  * Returns next report_id of report of specified type. If zero is given than
    585  * first report_id of specified type is returned (0 is not legal value for
    586  * repotr_id)
    587  *
    588  * @param report_id Current report_id, 0 if there is no current report_id
    589  * @param type Type of searched report
    590  * @param report Report structure inwhich we search
    591  * @retval 0 if report structure is null or there is no specified report
    592  * @retval report_id otherwise
    593  */
    594 uint8_t usb_hid_get_next_report_id(usb_hid_report_t *report,
    595         uint8_t report_id, usb_hid_report_type_t type)
     557uint8_t usb_hid_report_get_report_id(usb_hid_report_t *report, uint8_t report_id, usb_hid_report_type_t type)
    596558{
    597559        if(report == NULL){
     
    602564        link_t *report_it;
    603565       
    604         if(report_id > 0) {
    605                 report_it = usb_hid_report_find_description(report, report_id,
    606                         type)->link.next;               
     566        if(report_id == 0) {
     567                report_it = usb_hid_report_find_description (report, report_id, type)->link.next;               
    607568        }
    608569        else {
     
    611572
    612573        while(report_it != &report->reports) {
    613                 report_des = list_get_instance(report_it,
    614                         usb_hid_report_description_t, link);
    615 
     574                report_des = list_get_instance(report_it, usb_hid_report_description_t, link);
    616575                if(report_des->type == type){
    617576                        return report_des->report_id;
     
    622581}
    623582
    624 /*---------------------------------------------------------------------------*/
    625 /**
    626  * Reset all local items in given state table
    627  *
    628  * @param report_item State table containing current state of report
    629  * descriptor parsing
    630  *
    631  * @return void
    632  */
    633583void usb_hid_report_reset_local_items(usb_hid_report_item_t *report_item)
    634584{
  • uspace/lib/usbhid/src/hidpath.c

    r6bfaab5 r88be3a0b  
    4141#include <assert.h>
    4242
    43 /*---------------------------------------------------------------------------*/
    44 /**
    45  * Compares two usages if they are same or not or one of the usages is not
    46  * set.
    47  *
    48  * @param usage1
    49  * @param usage2
    50  * @return boolean
    51  */
    52 #define USB_HID_SAME_USAGE(usage1, usage2)              \
    53         ((usage1 == usage2) || (usage1 == 0) || (usage2 == 0))
    54 
    55 /**
    56  * Compares two usage pages if they are same or not or one of them is not set.
    57  *
    58  * @param page1
    59  * @param page2
    60  * @return boolean
    61  */
    62 #define USB_HID_SAME_USAGE_PAGE(page1, page2)   \
    63         ((page1 == page2) || (page1 == 0) || (page2 == 0))
    64 
    65 /*---------------------------------------------------------------------------*/
     43
    6644/**
    6745 * Appends one item (couple of usage_path and usage) into the usage path
     
    9270}
    9371
    94 /*---------------------------------------------------------------------------*/
    9572/**
    9673 * Removes last item from the usage path structure
     
    11188}
    11289
    113 /*---------------------------------------------------------------------------*/
    11490/**
    11591 * Nulls last item of the usage path structure.
     
    12399       
    124100        if(!list_empty(&usage_path->head)){     
    125                 item = list_get_instance(usage_path->head.prev,
    126                         usb_hid_report_usage_path_t, link);
    127 
     101                item = list_get_instance(usage_path->head.prev, usb_hid_report_usage_path_t, link);
    128102                memset(item, 0, sizeof(usb_hid_report_usage_path_t));
    129103        }
    130104}
    131105
    132 /*---------------------------------------------------------------------------*/
    133106/**
    134107 * Modifies last item of usage path structure by given usage page or usage
     
    161134}
    162135
    163 /*---------------------------------------------------------------------------*/
    164 /**
    165  *
    166  *
    167  *
    168  *
    169  */
     136
    170137void usb_hid_print_usage_path(usb_hid_report_path_t *path)
    171138{
     
    177144        while(item != &path->head) {
    178145
    179                 path_item = list_get_instance(item, usb_hid_report_usage_path_t,
    180                         link);
    181 
     146                path_item = list_get_instance(item, usb_hid_report_usage_path_t, link);
    182147                usb_log_debug("\tUSAGE_PAGE: %X\n", path_item->usage_page);
    183148                usb_log_debug("\tUSAGE: %X\n", path_item->usage);
    184149                usb_log_debug("\tFLAGS: %d\n", path_item->flags);               
    185150               
    186         item = item->next;
    187         }
    188 }
    189 
    190 /*---------------------------------------------------------------------------*/
     151                item = item->next;
     152        }
     153}
     154
    191155/**
    192156 * Compares two usage paths structures
     
    225189       
    226190        switch(flags){
    227         /* path is somewhere in report_path */
    228         case USB_HID_PATH_COMPARE_ANYWHERE:
    229                 if(path->depth != 1){
    230                         return 1;
    231                 }
    232 
    233                 report_link = report_path->head.next;
    234                 path_link = path->head.next;
    235                 path_item = list_get_instance(path_link,
    236                         usb_hid_report_usage_path_t, link);
    237 
    238                 while(report_link != &report_path->head) {
    239                         report_item = list_get_instance(report_link,
    240                                 usb_hid_report_usage_path_t, link);
    241                                
    242                         if(USB_HID_SAME_USAGE_PAGE(report_item->usage_page,
    243                                 path_item->usage_page)){
    244                                        
    245                                 if(only_page == 0){
    246                                         if(USB_HID_SAME_USAGE(
    247                                                 report_item->usage,
    248                                                 path_item->usage)) {
    249                                                        
     191                /* path is somewhere in report_path */
     192                case USB_HID_PATH_COMPARE_ANYWHERE:
     193                        if(path->depth != 1){
     194                                return 1;
     195                        }
     196
     197                        // projit skrz cestu a kdyz nekde sedi tak vratim EOK
     198                        // dojduli az za konec tak nnesedi
     199                        report_link = report_path->head.next;
     200                        path_link = path->head.next;
     201                        path_item = list_get_instance(path_link, usb_hid_report_usage_path_t, link);
     202
     203                        while(report_link != &report_path->head) {
     204                                report_item = list_get_instance(report_link, usb_hid_report_usage_path_t, link);
     205                                if(report_item->usage_page == path_item->usage_page){
     206                                        if(only_page == 0){
     207                                                if(report_item->usage == path_item->usage) {
     208                                                        return EOK;
     209                                                }
     210                                        }
     211                                        else {
    250212                                                return EOK;
    251213                                        }
    252214                                }
     215
     216                                report_link = report_link->next;
     217                        }
     218
     219                        return 1;
     220                        break;
     221                /* the paths must be identical */
     222                case USB_HID_PATH_COMPARE_STRICT:
     223                                if(report_path->depth != path->depth){
     224                                        return 1;
     225                                }
     226               
     227                /* path is prefix of the report_path */
     228                case USB_HID_PATH_COMPARE_BEGIN:
     229       
     230                                report_link = report_path->head.next;
     231                                path_link = path->head.next;
     232                       
     233                                while((report_link != &report_path->head) &&
     234                                      (path_link != &path->head)) {
     235                                                 
     236                                        report_item = list_get_instance(report_link,
     237                                                                        usb_hid_report_usage_path_t,
     238                                                                        link);
     239                                                 
     240                                        path_item = list_get_instance(path_link,
     241                                                                      usb_hid_report_usage_path_t,
     242                                                                      link);           
     243
     244                                        if((report_item->usage_page != path_item->usage_page) ||
     245                                           ((only_page == 0) &&
     246                                            (report_item->usage != path_item->usage))) {
     247                                                       
     248                                                   return 1;
     249                                        } else {
     250                                                report_link = report_link->next;
     251                                                path_link = path_link->next;                   
     252                                        }
     253                       
     254                                }
     255
     256                                if((((flags & USB_HID_PATH_COMPARE_BEGIN) != 0) && (path_link == &path->head)) ||
     257                                   ((report_link == &report_path->head) && (path_link == &path->head))) {
     258                                        return EOK;
     259                                }
    253260                                else {
     261                                        return 1;
     262                                }                                               
     263                        break;
     264
     265                /* path is suffix of report_path */
     266                case USB_HID_PATH_COMPARE_END:
     267
     268                                report_link = report_path->head.prev;
     269                                path_link = path->head.prev;
     270
     271                                if(list_empty(&path->head)){
    254272                                        return EOK;
    255273                                }
    256                         }
    257 
    258                         report_link = report_link->next;
    259                 }
    260 
    261                 return 1;
    262                 break;
    263 
    264         /* the paths must be identical */
    265         case USB_HID_PATH_COMPARE_STRICT:
    266                 if(report_path->depth != path->depth){
    267                         return 1;
    268                 }
    269                
    270         /* path is prefix of the report_path */
    271         case USB_HID_PATH_COMPARE_BEGIN:
    272        
    273                 report_link = report_path->head.next;
    274                 path_link = path->head.next;
    275274                       
    276                 while((report_link != &report_path->head) &&
    277                       (path_link != &path->head)) {
    278                                          
    279                         report_item = list_get_instance(report_link,
    280                                 usb_hid_report_usage_path_t, link);
    281                                          
    282                         path_item = list_get_instance(path_link,
    283                                 usb_hid_report_usage_path_t, link);
    284 
    285                         if(!USB_HID_SAME_USAGE_PAGE(report_item->usage_page,
    286                                 path_item->usage_page) || ((only_page == 0) &&
    287                             !USB_HID_SAME_USAGE(report_item->usage,
    288                                 path_item->usage))) {
     275                                while((report_link != &report_path->head) &&
     276                                      (path_link != &path->head)) {
     277                                                 
     278                                        report_item = list_get_instance(report_link,
     279                                                                        usb_hid_report_usage_path_t,
     280                                                                        link);
     281                                        path_item = list_get_instance(path_link,
     282                                                                      usb_hid_report_usage_path_t,
     283                                                                      link);           
     284
     285                                        if((report_item->usage_page != path_item->usage_page) ||
     286                                           ((only_page == 0) &&
     287                                            (report_item->usage != path_item->usage))) {
     288                                                   return 1;
     289                                        } else {
     290                                                report_link = report_link->prev;
     291                                                path_link = path_link->prev;                   
     292                                        }
    289293                       
    290                                 return 1;
    291                         }
    292                         else {
    293                                 report_link = report_link->next;
    294                                 path_link = path_link->next;                   
    295                         }
     294                                }
     295
     296                                if(path_link == &path->head) {
     297                                        return EOK;
     298                                }
     299                                else {
     300                                        return 1;
     301                                }                                               
    296302                       
    297                                 }
    298 
    299                 if((((flags & USB_HID_PATH_COMPARE_BEGIN) != 0) &&
    300                         (path_link == &path->head)) ||
    301                    ((report_link == &report_path->head) &&
    302                         (path_link == &path->head))) {
    303                                
    304                         return EOK;
    305                 }
    306                 else {
    307                         return 1;
    308                 }                                               
    309                 break;
    310 
    311         /* path is suffix of report_path */
    312         case USB_HID_PATH_COMPARE_END:
    313 
    314                 report_link = report_path->head.prev;
    315                 path_link = path->head.prev;
    316 
    317                 if(list_empty(&path->head)){
    318                         return EOK;
    319                 }
    320                        
    321                 while((report_link != &report_path->head) &&
    322                       (path_link != &path->head)) {
    323                                                  
    324                         report_item = list_get_instance(report_link,
    325                                 usb_hid_report_usage_path_t, link);
    326 
    327                         path_item = list_get_instance(path_link,
    328                                 usb_hid_report_usage_path_t, link);             
    329                                                  
    330                         if(!USB_HID_SAME_USAGE_PAGE(report_item->usage_page,
    331                                 path_item->usage_page) || ((only_page == 0) &&
    332                             !USB_HID_SAME_USAGE(report_item->usage,
    333                                 path_item->usage))) {
    334                                                
    335                                         return 1;
    336                         } else {
    337                                 report_link = report_link->prev;
    338                                 path_link = path_link->prev;                   
    339                         }
    340 
    341                 }
    342 
    343                 if(path_link == &path->head) {
    344                         return EOK;
    345                 }
    346                 else {
    347                         return 1;
    348                 }                                               
    349                        
    350                 break;
    351 
    352         default:
    353                 return EINVAL;
    354         }
    355 }
    356 
    357 /*---------------------------------------------------------------------------*/
     303                        break;
     304
     305                default:
     306                        return EINVAL;
     307        }
     308}
     309
    358310/**
    359311 * Allocates and initializes new usage path structure.
     
    377329}
    378330
    379 /*---------------------------------------------------------------------------*/
    380331/**
    381332 * Releases given usage path structure.
     
    394345}
    395346
    396 /*---------------------------------------------------------------------------*/
     347
    397348/**
    398349 * Clone content of given usage path to the new one
     
    401352 * @return New copy of given usage path structure
    402353 */
    403 usb_hid_report_path_t *usb_hid_report_path_clone(
    404         usb_hid_report_path_t *usage_path)
     354usb_hid_report_path_t *usb_hid_report_path_clone(usb_hid_report_path_t *usage_path)
    405355{
    406356        link_t *path_link;
     
    421371        path_link = usage_path->head.next;
    422372        while(path_link != &usage_path->head) {
    423                 path_item = list_get_instance(path_link,
    424                         usb_hid_report_usage_path_t, link);
    425 
     373                path_item = list_get_instance(path_link, usb_hid_report_usage_path_t,
     374                                              link);
    426375                new_path_item = malloc(sizeof(usb_hid_report_usage_path_t));
    427376                if(new_path_item == NULL) {
     
    443392}
    444393
    445 /*---------------------------------------------------------------------------*/
     394
    446395/**
    447396 * Sets report id in usage path structure
     
    451400 * @return Error code
    452401 */
    453 int usb_hid_report_path_set_report_id(usb_hid_report_path_t *path,
    454         uint8_t report_id)
     402int usb_hid_report_path_set_report_id(usb_hid_report_path_t *path, uint8_t report_id)
    455403{
    456404        if(path == NULL){
  • uspace/lib/usbhid/src/hidreport.c

    r6bfaab5 r88be3a0b  
    164164
    165165int usb_hid_process_report_descriptor(usb_device_t *dev,
    166     usb_hid_report_t *report, uint8_t **report_desc, size_t *report_size)
     166    usb_hid_report_t *report)
    167167{
    168168        if (dev == NULL || report == NULL) {
     
    172172        }
    173173       
    174 //      uint8_t *report_desc = NULL;
    175 //      size_t report_size;
    176        
    177         int rc = usb_hid_get_report_descriptor(dev, report_desc, report_size);
     174        uint8_t *report_desc = NULL;
     175        size_t report_size;
     176       
     177        int rc = usb_hid_get_report_descriptor(dev, &report_desc,
     178            &report_size);
    178179       
    179180        if (rc != EOK) {
    180181                usb_log_error("Problem with getting Report descriptor: %s.\n",
    181182                    str_error(rc));
    182                 if (*report_desc != NULL) {
    183                         free(*report_desc);
    184                         *report_desc = NULL;
     183                if (report_desc != NULL) {
     184                        free(report_desc);
    185185                }
    186186                return rc;
    187187        }
    188188       
    189         assert(*report_desc != NULL);
    190        
    191         rc = usb_hid_parse_report_descriptor(report, *report_desc, *report_size);
     189        assert(report_desc != NULL);
     190       
     191        rc = usb_hid_parse_report_descriptor(report, report_desc, report_size);
    192192        if (rc != EOK) {
    193193                usb_log_error("Problem parsing Report descriptor: %s.\n",
    194194                    str_error(rc));
    195                 free(*report_desc);
    196                 *report_desc = NULL;
     195                free(report_desc);
    197196                return rc;
    198197        }
    199198       
    200199        usb_hid_descriptor_print(report);
     200        free(report_desc);
    201201       
    202202        return EOK;
  • uspace/lib/usbhost/src/device_keeper.c

    r6bfaab5 r88be3a0b  
    158158}
    159159
    160 /** Find devman handle assigned to USB address.
    161  * Intentionally refuse to find handle of default address.
     160/** Find devman handled assigned to USB address.
    162161 *
    163162 * @param[in] instance Device keeper structure to use.
     
    171170        assert(instance);
    172171        fibril_mutex_lock(&instance->guard);
    173         if ((address <= 0) || (address >= USB_ADDRESS_COUNT)) {
     172        if ((address < 0) || (address >= USB_ADDRESS_COUNT)) {
    174173                fibril_mutex_unlock(&instance->guard);
    175174                return false;
Note: See TracChangeset for help on using the changeset viewer.