Changes in / [293de44:160b75e] in mainline


Ignore:
Files:
15 added
6 deleted
43 edited

Legend:

Unmodified
Added
Removed
  • .bzrignore

    r293de44 r160b75e  
    5353./uspace/app/klog/klog
    5454./uspace/app/lsusb/lsusb
    55 ./uspace/app/mkbd/mkbd
    5655./uspace/app/mkfat/mkfat
    5756./uspace/app/netstart/netstart
  • boot/Makefile.common

    r293de44 r160b75e  
    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

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

    r293de44 r160b75e  
    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

    r293de44 r160b75e  
    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/drv/ohci/batch.c

    r293de44 r160b75e  
    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

    r293de44 r160b75e  
    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

    r293de44 r160b75e  
    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

    r293de44 r160b75e  
    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

    r293de44 r160b75e  
    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{
     
    585502        /* Init interrupt code */
    586503        instance->interrupt_code.cmds = instance->interrupt_commands;
    587         instance->interrupt_code.cmdcount = OHCI_NEEDED_IRQ_COMMANDS;
    588504        {
    589505                /* Read status register */
     
    605521                instance->interrupt_commands[2].srcarg = 2;
    606522
    607                 /* Write-clean status register */
     523                /* Write clean status register */
    608524                instance->interrupt_commands[3].cmd = CMD_MEM_WRITE_A_32;
    609525                instance->interrupt_commands[3].srcarg = 1;
     
    613529                /* Accept interrupt */
    614530                instance->interrupt_commands[4].cmd = CMD_ACCEPT;
     531
     532                instance->interrupt_code.cmdcount = OHCI_NEEDED_IRQ_COMMANDS;
    615533        }
    616534
  • uspace/drv/ohci/hc.h

    r293de44 r160b75e  
    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

    r293de44 r160b75e  
    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

    r293de44 r160b75e  
    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

    r293de44 r160b75e  
    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

    r293de44 r160b75e  
    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

    r293de44 r160b75e  
    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/batch.c

    r293de44 r160b75e  
    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

    r293de44 r160b75e  
    4545usb_transfer_batch_t * batch_get(
    4646    ddf_fun_t *fun, endpoint_t *ep, char *buffer, size_t size,
    47     const char *setup_buffer, size_t setup_size,
     47    char *setup_buffer, size_t setup_size,
    4848    usbhc_iface_transfer_in_callback_t func_in,
    4949    usbhc_iface_transfer_out_callback_t func_out,
     
    5555
    5656void batch_control_write(usb_transfer_batch_t *instance);
     57
    5758void batch_control_read(usb_transfer_batch_t *instance);
    5859
    5960void batch_interrupt_in(usb_transfer_batch_t *instance);
     61
    6062void batch_interrupt_out(usb_transfer_batch_t *instance);
    6163
    6264void batch_bulk_in(usb_transfer_batch_t *instance);
     65
    6366void batch_bulk_out(usb_transfer_batch_t *instance);
    6467
  • uspace/drv/uhci-hcd/hc.c

    r293de44 r160b75e  
    5757static int hc_debug_checker(void *arg);
    5858/*----------------------------------------------------------------------------*/
    59 /** Initialize UHCI hc driver structure
     59/** Initialize UHCI hcd driver structure
    6060 *
    6161 * @param[in] instance Memory place to initialize.
  • uspace/drv/uhci-hcd/hc.h

    r293de44 r160b75e  
    9595#define UHCI_NEEDED_IRQ_COMMANDS 5
    9696
    97 /** Main UHCI driver structure */
     97/* Main HC driver structure */
    9898typedef struct hc {
    9999        /** USB bus driver, devices and addresses */
  • uspace/drv/uhci-hcd/transfer_list.c

    r293de44 r160b75e  
    3434#include <errno.h>
    3535#include <usb/debug.h>
    36 #include <arch/barrier.h>
    3736
    3837#include "transfer_list.h"
     
    7271 * @param[in] instance Memory place to use.
    7372 *
    74  * Frees memory of the internal qh_t structure.
     73 * Frees memory for internal qh_t structure.
    7574 */
    7675void transfer_list_fini(transfer_list_t *instance)
     
    127126        assert((pa & LINK_POINTER_ADDRESS_MASK) == pa);
    128127
    129         /* Make sure all data in the batch are written */
    130         write_barrier();
    131 
    132128        /* keep link */
    133129        batch_qh(batch)->next = last_qh->next;
    134130        qh_set_next_qh(last_qh, batch_qh(batch));
    135131
    136         /* Make sure the pointer is updated */
    137         write_barrier();
     132        asm volatile ("": : :"memory");
    138133
    139134        /* Add to the driver list */
     
    227222            == addr_to_phys(batch_qh(batch)));
    228223        prev_qh->next = batch_qh(batch)->next;
    229 
    230         /* Make sure the pointer is updated */
    231         write_barrier();
    232 
     224        asm volatile ("": : :"memory");
    233225        /* Remove from the batch list */
    234226        list_remove(&batch->link);
  • uspace/drv/uhci-hcd/transfer_list.h

    r293de44 r160b75e  
    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/utils/malloc32.h

    r293de44 r160b75e  
    7474        if (size <= SLAB_ELEMENT_SIZE)
    7575                return slab_malloc_g();
    76         usb_log_warning("Requested %zu bytes, current allocator can't handle "
    77             "that amount, pray that the standard malloc will suffice.", size);
     76        assert(false);
    7877        return memalign(UHCI_STRCUTURES_ALIGNMENT, size);
    7978}
  • uspace/drv/uhci-rhd/port.c

    r293de44 r160b75e  
    227227                while (uhci_port_read_status(port) & STATUS_IN_RESET);
    228228        }
    229         /* PIO delay, should not be longer than 3ms as the device might
    230          * enter suspend state. */
    231229        udelay(10);
    232230        /* Enable the port. */
    233231        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);
    234237        return EOK;
    235238}
  • uspace/drv/usbhid/Makefile

    r293de44 r160b75e  
    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

    r293de44 r160b75e  
    162162/*----------------------------------------------------------------------------*/
    163163
    164 int usb_generic_hid_init(usb_hid_dev_t *hid_dev, void **data)
     164int usb_generic_hid_init(usb_hid_dev_t *hid_dev)
    165165{
    166166        if (hid_dev == NULL) {
     
    173173/*----------------------------------------------------------------------------*/
    174174
    175 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,
    176176    uint8_t *buffer, size_t buffer_size)
    177177{
  • uspace/drv/usbhid/generic/hiddev.h

    r293de44 r160b75e  
    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

    r293de44 r160b75e  
    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);
     
    835840 * @return Other value inherited from function usbhid_dev_init().
    836841 */
    837 int usb_kbd_init(usb_hid_dev_t *hid_dev, void **data)
     842int usb_kbd_init(usb_hid_dev_t *hid_dev)
    838843{
    839844        usb_log_debug("Initializing HID/KBD structure...\n");
     
    860865        usb_hid_report_path_set_report_id(path, 0);
    861866       
    862         kbd_dev->key_count = usb_hid_report_size(
    863             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);
    864870        usb_hid_report_path_free(path);
    865871       
     
    902908            kbd_dev->led_path, USB_HIDUT_PAGE_LED, 0);
    903909       
    904         kbd_dev->led_output_size = usb_hid_report_size(hid_dev->report,
    905             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);
    906913       
    907914        usb_log_debug("Output report size (in items): %zu\n",
     
    948955       
    949956        // save the KBD device structure into the HID device structure
    950         //hid_dev->data = kbd_dev;
    951         *data = kbd_dev;
     957        hid_dev->data = kbd_dev;
    952958       
    953959        // set handler for incoming calls
    954         kbd_dev->ops.default_handler = default_connection_handler;
     960        hid_dev->ops.default_handler = default_connection_handler;
    955961       
    956962        /*
     
    977983       
    978984        usb_log_debug("Creating KBD function...\n");
    979         int rc = usb_kbd_create_function(hid_dev, kbd_dev);
     985        int rc = usb_kbd_create_function(hid_dev);
    980986        if (rc != EOK) {
    981987                usb_kbd_free(&kbd_dev);
     
    988994/*----------------------------------------------------------------------------*/
    989995
    990 bool usb_kbd_polling_callback(usb_hid_dev_t *hid_dev, void *data,
    991      uint8_t *buffer, size_t buffer_size)
    992 {
    993         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) {
    9941000                // do not continue polling (???)
    9951001                return false;
    9961002        }
    9971003       
    998         usb_kbd_t *kbd_dev = (usb_kbd_t *)data;
    999         assert(kbd_dev != NULL);
    1000        
    10011004        // TODO: add return value from this function
    1002         usb_kbd_process_data(hid_dev, kbd_dev, buffer, buffer_size);
     1005        usb_kbd_process_data(hid_dev, buffer, buffer_size);
    10031006       
    10041007        return true;
     
    10631066/*----------------------------------------------------------------------------*/
    10641067
    1065 void usb_kbd_deinit(usb_hid_dev_t *hid_dev, void *data)
     1068void usb_kbd_deinit(usb_hid_dev_t *hid_dev)
    10661069{
    10671070        if (hid_dev == NULL) {
     
    10691072        }
    10701073       
    1071         if (data != NULL) {
    1072                 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;
    10731076                if (usb_kbd_is_initialized(kbd_dev)) {
    10741077                        usb_kbd_mark_unusable(kbd_dev);
    10751078                } else {
    10761079                        usb_kbd_free(&kbd_dev);
     1080                        hid_dev->data = NULL;
    10771081                }
    10781082        }
  • uspace/drv/usbhid/kbd/kbddev.h

    r293de44 r160b75e  
    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

    r293de44 r160b75e  
    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",
     
    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

    r293de44 r160b75e  
    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

    r293de44 r160b75e  
    3838#include <usb/hid/hidpath.h>
    3939
    40 //#include "lgtch-ultrax/lgtch-ultrax.h"
    41 #include "multimedia/multimedia.h"
     40#include "lgtch-ultrax/lgtch-ultrax.h"
    4241#include "mouse/mousedev.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};
     
    6260                path_kbd,
    6361                -1,
    64                 USB_HID_PATH_COMPARE_BEGIN,
     62                USB_HID_PATH_COMPARE_END
     63                | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY,
    6564                -1,
    6665                -1,
     
    7473        },
    7574        {
    76                 multim_key_path,
     75                lgtch_path,
    7776                1,
    78                 USB_HID_PATH_COMPARE_BEGIN,
    79                 -1,
    80                 -1,
     77                USB_HID_PATH_COMPARE_END
     78                | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY,
     79                0x046d,
     80                0xc30e,
    8181                {
    82                         .init = usb_multimedia_init,
    83                         .deinit = usb_multimedia_deinit,
    84                         .poll = usb_multimedia_polling_callback,
     82                        .init = usb_lgtch_init,
     83                        .deinit = usb_lgtch_deinit,
     84                        .poll = usb_lgtch_polling_callback,
    8585                        .poll_end = NULL
    8686                }
    8787        },
    8888        {
    89                 path_mouse,
     89                path_mouse2,
    9090                -1,
    91                 USB_HID_PATH_COMPARE_BEGIN,
     91                USB_HID_PATH_COMPARE_END
     92                | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY,
    9293                -1,
    9394                -1,
     
    99100                }
    100101        },
    101         {NULL, -1, 0, -1, -1, {NULL, NULL, NULL, NULL, NULL}}
     102        {NULL, -1, 0, -1, -1, {NULL, NULL, NULL, NULL}}
    102103};
    103104
  • uspace/drv/usbhid/usbhid.c

    r293de44 r160b75e  
    203203       
    204204        usb_log_debug("Compare flags: %d\n", mapping->compare);
    205 //      size_t size = usb_hid_report_size(hid_dev->report, 0,
    206 //          USB_HID_REPORT_TYPE_INPUT);
    207         size_t size = 0;
    208         usb_hid_report_field_t *field = usb_hid_report_get_sibling (hid_dev->report,
    209                 NULL, usage_path, mapping->compare, USB_HID_REPORT_TYPE_INPUT);
    210         while(field != NULL) {
    211                 size++;
    212                 field = usb_hid_report_get_sibling (hid_dev->report,
    213                                         field, usage_path, mapping->compare,
    214                             USB_HID_REPORT_TYPE_INPUT);
    215         }
    216        
     205        size_t size = usb_hid_report_input_length(hid_dev->report, usage_path,
     206            mapping->compare);
    217207        usb_log_debug("Size of the input report: %zuB\n", size);
     208       
    218209        usb_hid_report_path_free(usage_path);
    219210       
     
    466457                        if (hid_dev->subdrivers[i].init != NULL) {
    467458                                usb_log_debug("Initializing subdriver %d.\n",i);
    468                                 rc = hid_dev->subdrivers[i].init(hid_dev,
    469                                     &hid_dev->subdrivers[i].data);
     459                                rc = hid_dev->subdrivers[i].init(hid_dev);
    470460                                if (rc != EOK) {
    471461                                        usb_log_warning("Failed to initialize"
     
    532522        for (i = 0; i < hid_dev->subdriver_count; ++i) {
    533523                if (hid_dev->subdrivers[i].poll != NULL
    534                     && hid_dev->subdrivers[i].poll(hid_dev,
    535                         hid_dev->subdrivers[i].data, buffer, buffer_size)) {
     524                    && hid_dev->subdrivers[i].poll(hid_dev, buffer,
     525                    buffer_size)) {
    536526                        cont = true;
    537527                }
     
    556546        for (i = 0; i < hid_dev->subdriver_count; ++i) {
    557547                if (hid_dev->subdrivers[i].poll_end != NULL) {
    558                         hid_dev->subdrivers[i].poll_end(hid_dev,
    559                             hid_dev->subdrivers[i].data, reason);
     548                        hid_dev->subdrivers[i].poll_end(hid_dev, reason);
    560549                }
    561550        }
     
    638627        for (i = 0; i < (*hid_dev)->subdriver_count; ++i) {
    639628                if ((*hid_dev)->subdrivers[i].deinit != NULL) {
    640                         (*hid_dev)->subdrivers[i].deinit(*hid_dev,
    641                             (*hid_dev)->subdrivers[i].data);
     629                        (*hid_dev)->subdrivers[i].deinit(*hid_dev);
    642630                }
    643631        }
  • uspace/drv/usbhid/usbhid.h

    r293de44 r160b75e  
    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;
     99       
     100        /** Arbitrary data (e.g. a special structure for handling keyboard). */
     101        void *data;
    100102} usb_hid_dev_t;
    101103
  • uspace/lib/usbdev/src/hub.c

    r293de44 r160b75e  
    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.
     
    219218
    220219        int rc;
    221         struct timeval start_time;
    222 
    223         rc = gettimeofday(&start_time, NULL);
    224         if (rc != EOK) {
    225                 return rc;
    226         }
    227220
    228221        rc = usb_hc_connection_open(&hc_conn);
     
    271264                }
    272265        } while (rc != EOK);
    273         struct timeval end_time;
    274 
    275         rc = gettimeofday(&end_time, NULL);
    276         if (rc != EOK) {
    277                 goto leave_release_default_address;
    278         }
    279 
    280         /* According to the USB spec part 9.1.2 host allows 100ms time for
    281          * the insertion process to complete. According to 7.1.7.1 this is the
    282          * time between attach detected and port reset. However, the setup done
    283          * above might use much of this time so we should only wait to fill
    284          * up the 100ms quota*/
    285         suseconds_t elapsed = tv_sub(&end_time, &start_time);
    286         if (elapsed < 100000) {
    287                 async_usleep(100000 - elapsed);
    288         }
    289266
    290267        /*
     
    296273                goto leave_release_default_address;
    297274        }
    298         /* USB spec 7.1.7.1: The USB System Software guarantees a minimum of
    299          * 10ms for reset recovery. Device response to any bus transactions
    300          * addressed to the default device address during the reset recovery
    301          * time is undefined.
    302          */
    303         async_usleep(10000);
    304275
    305276        rc = usb_pipe_probe_default_control(&ctrl_pipe);
  • uspace/lib/usbhid/include/usb/hid/hid_report_items.h

    r293de44 r160b75e  
    4646#define USB_HID_ITEM_IS_LONG(data)      (data == 0xFE)
    4747
    48 
    49 /**
    50  * Extended usage macros
    51  */
    52 #define USB_HID_IS_EXTENDED_USAGE(usage)        ((usage & 0xFFFF0000) != 0)
    53 #define USB_HID_EXTENDED_USAGE_PAGE(usage)      ((usage & 0xFFFF0000) >> 16)
    54 #define USB_HID_EXTENDED_USAGE(usage)           (usage & 0xFFFF)
    5548
    5649/**
  • uspace/lib/usbhid/include/usb/hid/hidparser.h

    r293de44 r160b75e  
    5151                         size_t size, uint8_t *report_id);
    5252
     53/** */
     54size_t usb_hid_report_input_length(const usb_hid_report_t *report,
     55        usb_hid_report_path_t *path, int flags);
     56
    5357/*
    5458 * Output report parser functions
     
    6165void usb_hid_report_output_free(uint8_t *output);
    6266
    63 /** Returns size of report in items */
    64 size_t usb_hid_report_size(usb_hid_report_t *report, uint8_t report_id,
    65                            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);
    6670
    6771/** Makes the output report buffer by translated given data */
  • uspace/lib/usbhid/include/usb/hid/hidtypes.h

    r293de44 r160b75e  
    3939#include <adt/list.h>
    4040
    41 #define USB_HID_MAX_USAGES      0xffff
     41#define USB_HID_MAX_USAGES      20
    4242
    4343#define USB_HID_UINT32_TO_INT32(x, size)        ((((x) & (1 << ((size) - 1))) != 0) ? -(~(x - 1) & ((1 << size) - 1)) : (x)) //(-(~((x) - 1)))
     
    9292        int32_t physical_minimum;
    9393        int32_t physical_maximum;
    94         int32_t usage_minimum;
    95         int32_t usage_maximum;
     94        uint32_t usage_minimum;
     95        uint32_t usage_maximum;
    9696        uint32_t unit;
    9797        uint32_t unit_exponent;
    98 
    99         uint32_t *usages;
    100         size_t usages_count;
     98       
    10199
    102100        int32_t value;
     
    123121
    124122        /** */ 
    125         int32_t usage_minimum;
    126         /** */ 
    127         int32_t usage_maximum;
     123        uint32_t usage_minimum;
     124        /** */ 
     125        uint32_t usage_maximum;
    128126        /** */ 
    129127        int32_t logical_minimum;
  • uspace/lib/usbhid/include/usb/hid/usages/core.h

    r293de44 r160b75e  
    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

    r293de44 r160b75e  
    6464{
    6565        /* find or append current collection path to the list */
    66         //link_t *path_it = report->collection_paths.next;
    67         link_t *path_it = report->collection_paths.prev->next;
     66        link_t *path_it = report->collection_paths.next;
    6867        usb_hid_report_path_t *path = NULL;
    69        
    70        
    7168        while(path_it != &report->collection_paths) {
    7269                path = list_get_instance(path_it, usb_hid_report_path_t, link);
     
    119116        int i;
    120117
    121         uint32_t *usages;
    122         int usages_used=0;
    123         if(report_item->usages_count > 0){
    124                 usages = malloc(sizeof(int32_t) * report_item->usages_count);
    125                 memcpy(usages, report_item->usages, sizeof(int32_t) * report_item->usages_count);
    126         }
    127         else {
    128                 usages = NULL;
    129         }
    130        
     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
    131122        usb_hid_report_path_t *path = report_item->usage_path; 
    132123        for(i=0; i<report_item->count; i++){
     
    142133                field->physical_maximum = report_item->physical_maximum;
    143134
    144                 if(USB_HID_ITEM_FLAG_VARIABLE(report_item->item_flags) == 0){
    145                         /*
    146                                 Store usage array. The Correct Usage Page and Usage is depending
    147                                 on data in report and will be filled later
    148                         */
    149                         field->usage = 0;
    150                         field->usage_page = 0; //report_item->usage_page;
    151 
    152                         field->usages_count = report_item->usages_count;
    153                         field->usages = usages;
    154                         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;
    155139                }
    156140                else {
    157 
    158                         /* Fill the correct Usage and Usage Page */
    159                         int32_t usage;
    160                         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){
    161147                                usage = report_item->usages[i];
    162148                        }
     
    165151                        }
    166152
    167                         if(USB_HID_IS_EXTENDED_USAGE(usage)){
    168                                 field->usage = USB_HID_EXTENDED_USAGE(usage);
    169                                 field->usage_page = USB_HID_EXTENDED_USAGE_PAGE(usage);
     153                                               
     154                        if((usage & 0xFFFF0000) != 0){
     155                                field->usage_page = (usage >> 16);                                     
     156                                field->usage = (usage & 0xFFFF);
    170157                        }
    171158                        else {
    172                                 // should not occur
    173159                                field->usage = usage;
    174                                 field->usage_page = report_item->usage_page;
    175                         }
     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;                                 
    176167                }
    177168               
     
    218209        }
    219210
    220         // free only when not used!!!
    221         if(usages && usages_used == 0) {
    222                 free(usages);
    223         }
    224211
    225212        return EOK;
     
    463450                       
    464451                case USB_HID_REPORT_TAG_COLLECTION:
    465 
    466452                        // store collection atributes
    467453                        path_item = list_get_instance(usage_path->head.prev, usb_hid_report_usage_path_t, link);
     
    469455                       
    470456                        // set last item
    471                         usb_hid_report_set_last_item(usage_path,
    472                                                      USB_HID_TAG_CLASS_GLOBAL,
    473                                                      USB_HID_EXTENDED_USAGE_PAGE(report_item->usages[report_item->usages_count-1]));
    474                         usb_hid_report_set_last_item(usage_path,
    475                                                      USB_HID_TAG_CLASS_LOCAL,
    476                                                      USB_HID_EXTENDED_USAGE(report_item->usages[report_item->usages_count-1]));
     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]);
    477459                       
    478460                        // append the new one which will be set by common
     
    569551                             usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path)
    570552{
    571         int32_t extended_usage;
    572        
    573553        switch(tag) {
    574554                case USB_HID_REPORT_TAG_USAGE:
     
    580560                                        report_item->in_delimiter = INSIDE_DELIMITER_SET;
    581561                                case OUTSIDE_DELIMITER_SET:
    582                                         extended_usage = ((report_item->usage_page) << 16);
    583                                         extended_usage += usb_hid_report_tag_data_uint32(data,item_size);
    584                                         report_item->usages[report_item->usages_count] = extended_usage;
     562                                        report_item->usages[report_item->usages_count] = usb_hid_report_tag_data_uint32(data,item_size);
    585563                                        report_item->usages_count++;
    586564                                        break;
    587565                        }
    588566                        break;
    589                 case USB_HID_REPORT_TAG_USAGE_MINIMUM:                 
     567                case USB_HID_REPORT_TAG_USAGE_MINIMUM:
    590568                        if (item_size == 3) {
    591569                                // usage extended usages
     
    599577                case USB_HID_REPORT_TAG_USAGE_MAXIMUM:
    600578                        if (item_size == 3) {
    601 
    602                                 if(report_item->extended_usage_page != ((usb_hid_report_tag_data_uint32(data,item_size) & 0xFF00) >> 16)) {
    603                                         return EINVAL;
    604                                 }
    605                                
    606579                                // usage extended usages
    607580                                report_item->extended_usage_page = (usb_hid_report_tag_data_uint32(data,item_size) & 0xFF00) >> 16;
     
    611584                                report_item->usage_maximum = usb_hid_report_tag_data_uint32(data,item_size);
    612585                        }
    613 
    614                         // vlozit zaznamy do pole usages
    615                         int32_t i;
    616                         for(i=report_item->usage_minimum; i<=report_item->usage_maximum; i++) {
    617                                 if(report_item->extended_usage_page) {
    618                                         report_item->usages[report_item->usages_count++] = (report_item->extended_usage_page << 16) + i;
    619                                 }
    620                                 else {
    621                                        
    622                                         report_item->usages[report_item->usages_count++] = (report_item->usage_page << 16) + i;
    623                                 }
    624                         }
    625                         report_item->extended_usage_page = 0;
    626                        
    627586                        break;
    628587                case USB_HID_REPORT_TAG_DESIGNATOR_INDEX:
     
    704663                usb_log_debug("\t\ttUSAGEMIN: %X\n", report_item->usage_minimum);
    705664                usb_log_debug("\t\tUSAGEMAX: %X\n", report_item->usage_maximum);
    706                 usb_log_debug("\t\tUSAGES COUNT: %zu\n", report_item->usages_count);
    707665
    708666                usb_log_debug("\t\tVALUE: %X\n", report_item->value);
     
    710668                usb_log_debug("\t\tUSAGE PAGE: %X\n", report_item->usage_page);
    711669               
    712                 usb_hid_print_usage_path(report_item->collection_path);
     670                //usb_hid_print_usage_path(report_item->collection_path);
    713671
    714672                usb_log_debug("\n");           
     
    742700                usb_hid_descriptor_print_list(&report_des->report_items);
    743701
    744 /*
     702
    745703                link_t *path_it = report->collection_paths.next;
    746704                while(path_it != &report->collection_paths) {
     
    748706                        path_it = path_it->next;
    749707                }
    750 */             
     708               
    751709                report_it = report_it->next;
    752710        }
  • uspace/lib/usbhid/src/hidparser.c

    r293de44 r160b75e  
    6969
    7070
    71 /** Returns size of report of specified report id and type in items
    72  *
    73  * @param parser Opaque report parser structure
    74  * @param report_id
    75  * @param type
    76  * @return Number of items in specified report
    77  */
    78 size_t usb_hid_report_size(usb_hid_report_t *report, uint8_t report_id,
    79                            usb_hid_report_type_t type)
    80 {
    81         usb_hid_report_description_t *report_des;
    82 
    83         if(report == NULL) {
    84                 return 0;
    85         }
    86 
    87         report_des = usb_hid_report_find_description (report, report_id, type);
    88         if(report_des == NULL){
    89                 return 0;
    90         }
    91         else {
    92                 return report_des->item_length;
    93         }
    94 }
    9571
    9672
     
    11187        usb_hid_report_description_t *report_des;
    11288        usb_hid_report_type_t type = USB_HID_REPORT_TYPE_INPUT;
    113        
     89
    11490        if(report == NULL) {
    11591                return EINVAL;
     
    138114                                // array
    139115                                item->value = usb_hid_translate_data(item, data);
    140                
    141                                 item->usage = USB_HID_EXTENDED_USAGE(item->usages[item->value - item->physical_minimum]);
    142                                 item->usage_page = USB_HID_EXTENDED_USAGE_PAGE(item->usages[item->value - item->physical_minimum]);                             
    143 
    144                                 usb_hid_report_set_last_item (item->collection_path,
    145                                                               USB_HID_TAG_CLASS_GLOBAL,
    146                                                               item->usage_page);
    147                                 usb_hid_report_set_last_item (item->collection_path,
    148                                                               USB_HID_TAG_CLASS_LOCAL,
    149                                                               item->usage);
    150                                
     116                            item->usage = (item->value - item->physical_minimum) + item->usage_minimum;
    151117                        }
    152118                        else {
     
    157123                list_item = list_item->next;
    158124        }
    159        
     125           
    160126        return EOK;
    161127       
     
    240206}
    241207
     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
    242252/*** OUTPUT API **/
    243253
     
    294304}
    295305
     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       
     346}
     347
    296348/** Makes the output report buffer for data given in the report structure
    297349 *
     
    333385                report_item = list_get_instance(item, usb_hid_report_field_t, link);
    334386
    335                 usb_log_debug("OUTPUT ITEM usage(%x), value(%x)\n", report_item->usage, report_item->value);
    336                
    337                 if(USB_HID_ITEM_FLAG_VARIABLE(report_item->item_flags) == 0) {
     387                        if(USB_HID_ITEM_FLAG_VARIABLE(report_item->item_flags) == 0) {
    338388                                       
    339                         // array
    340                         value = usb_hid_translate_data_reverse(report_item, report_item->value);
    341                         offset = report_item->offset;
    342                         length = report_item->size;
    343                 }
    344                 else {
    345                         // variable item
    346                         value  = usb_hid_translate_data_reverse(report_item, report_item->value);
    347                         offset = report_item->offset;
    348                         length = report_item->size;
    349                 }
    350 
    351                 usb_log_debug("\ttranslated value: %x\n", value);
    352 
    353                 if((offset/8) == ((offset+length-1)/8)) {
    354                         // je to v jednom bytu
    355                         if(((size_t)(offset/8) >= size) || ((size_t)(offset+length-1)/8) >= size) {
    356                                 break; // TODO ErrorCode
    357                         }
    358                         size_t shift = 8 - offset%8 - length;
    359                         value = value << shift;                                                 
    360                         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);
    361411                               
    362                         uint8_t mask = 0;
    363                         mask = 0xff - (((1 << length) - 1) << shift);
    364                         buffer[offset/8] = (buffer[offset/8] & mask) | value;
    365                 }
    366                 else {
    367                         int i = 0;
    368                         uint8_t mask = 0;
    369                         for(i = (offset/8); i <= ((offset+length-1)/8); i++) {
    370                                 if(i == (offset/8)) {
    371                                         tmp_value = value;
    372                                         tmp_value = tmp_value & ((1 << (8-(offset%8)))-1);                             
    373                                         tmp_value = tmp_value << (offset%8);
    374        
    375                                         mask = ~(((1 << (8-(offset%8)))-1) << (offset%8));
    376                                         buffer[i] = (buffer[i] & mask) | 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                                        }
    377439                                }
    378                                 else if (i == ((offset + length -1)/8)) {
    379                                        
    380                                         value = value >> (length - ((offset + length) % 8));
    381                                         value = value & ((1 << (length - ((offset + length) % 8))) - 1);
    382                                
    383                                         mask = (1 << (length - ((offset + length) % 8))) - 1;
    384                                         buffer[i] = (buffer[i] & mask) | value;
    385                                 }
    386                                 else {
    387                                         buffer[i] = value & (0xFF << i);
    388                                 }
    389                         }
    390                 }
     440                        }
     441
    391442
    392443                // reset value
     
    421472        }
    422473       
    423         // variable item
    424         if(item->physical_maximum == item->physical_minimum){
    425             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;
    426488        }
    427489        else {
    428             resolution = (item->logical_maximum - item->logical_minimum) /
    429                 ((item->physical_maximum - item->physical_minimum) *
    430                 (usb_pow(10,(item->unit_exponent))));
    431         }
    432 
    433         ret = ((value - item->physical_minimum) * resolution) + item->logical_minimum;
    434         usb_log_debug("\tvalue(%x), resolution(%x), phymin(%x) logmin(%x), ret(%x)\n", value, resolution, item->physical_minimum, item->logical_minimum, ret);
    435        
     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
    436500        if((item->logical_minimum < 0) || (item->logical_maximum < 0)){
    437501                return USB_HID_INT32_TO_UINT32(ret, item->size);
    438502        }
    439         return (int32_t)0 + ret;
     503        return (int32_t)ret;
    440504}
    441505
  • uspace/lib/usbhid/src/hidpath.c

    r293de44 r160b75e  
    4242
    4343
    44 #define USB_HID_SAME_USAGE(usage1, usage2)      ((usage1 == usage2) || (usage1 == 0) || (usage2 == 0))
    45 #define USB_HID_SAME_USAGE_PAGE(page1, page2)   ((page1 == page2) || (page1 == 0) || (page2 == 0))
    46 
    4744/**
    4845 * Appends one item (couple of usage_path and usage) into the usage path
     
    206203                        while(report_link != &report_path->head) {
    207204                                report_item = list_get_instance(report_link, usb_hid_report_usage_path_t, link);
    208                                 if(USB_HID_SAME_USAGE_PAGE(report_item->usage_page, path_item->usage_page)){
     205                                if(report_item->usage_page == path_item->usage_page){
    209206                                        if(only_page == 0){
    210                                                 if(USB_HID_SAME_USAGE(report_item->usage, path_item->usage)) {
     207                                                if(report_item->usage == path_item->usage) {
    211208                                                        return EOK;
    212209                                                }
     
    245242                                                                      link);           
    246243
    247                                         if(!USB_HID_SAME_USAGE_PAGE(report_item->usage_page, path_item->usage_page) ||
     244                                        if((report_item->usage_page != path_item->usage_page) ||
    248245                                           ((only_page == 0) &&
    249                                             !USB_HID_SAME_USAGE(report_item->usage, path_item->usage))) {
     246                                            (report_item->usage != path_item->usage))) {
    250247                                                       
    251248                                                   return 1;
     
    285282                                                                      usb_hid_report_usage_path_t,
    286283                                                                      link);           
    287                                                  
    288                                         if(!USB_HID_SAME_USAGE_PAGE(report_item->usage_page, path_item->usage_page) ||
     284
     285                                        if((report_item->usage_page != path_item->usage_page) ||
    289286                                           ((only_page == 0) &&
    290                                             !USB_HID_SAME_USAGE(report_item->usage, path_item->usage))) {
    291                                                         return 1;
     287                                            (report_item->usage != path_item->usage))) {
     288                                                   return 1;
    292289                                        } else {
    293290                                                report_link = report_link->prev;
  • uspace/lib/usbhost/src/device_keeper.c

    r293de44 r160b75e  
    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.