Changeset 291b8bc in mainline


Ignore:
Timestamp:
2011-03-26T13:28:43Z (13 years ago)
Author:
Vojtech Horky <vojtechhorky@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
f62468c
Parents:
889e8e3 (diff), c9f5e238 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge development/ changes

Files:
5 added
3 deleted
28 edited
14 moved

Legend:

Unmodified
Added
Removed
  • boot/arch/amd64/Makefile.inc

    r889e8e3 r291b8bc  
    4949        usbflbk \
    5050        usbhub \
    51         usbhid \
     51        usbkbd \
    5252        usbmid \
    5353        usbmouse \
  • kernel/generic/src/console/console.c

    r889e8e3 r291b8bc  
    5353#include <str.h>
    5454
     55/*
     56 * devman produces a lot of output and by giving so many pages
     57 * we to allow /app/klog to catch-up.
     58 */
     59#ifdef CONFIG_DEVMAN_EARLY_LAUNCH
     60#define KLOG_PAGES    64
     61#else
    5562#define KLOG_PAGES    4
     63#endif
     64
    5665#define KLOG_LENGTH   (KLOG_PAGES * PAGE_SIZE / sizeof(wchar_t))
    5766#define KLOG_LATENCY  8
  • kernel/generic/src/mm/as.c

    r889e8e3 r291b8bc  
    19491949sysarg_t sys_as_area_create(uintptr_t address, size_t size, unsigned int flags)
    19501950{
    1951         if (as_area_create(AS, flags | AS_AREA_CACHEABLE, size, address,
     1951        if (as_area_create(AS, flags, size, address,
    19521952            AS_AREA_ATTR_NONE, &anon_backend, NULL))
    19531953                return (sysarg_t) address;
  • uspace/Makefile

    r889e8e3 r291b8bc  
    122122                drv/uhci-rhd \
    123123                drv/usbflbk \
    124                 drv/usbhid \
     124                drv/usbkbd \
    125125                drv/usbhub \
    126126                drv/usbmid \
     
    142142                drv/uhci-rhd \
    143143                drv/usbflbk \
    144                 drv/usbhid \
     144                drv/usbkbd \
    145145                drv/usbhub \
    146146                drv/usbmid \
  • uspace/app/init/init.c

    r889e8e3 r291b8bc  
    288288       
    289289        spawn("/srv/clip");
    290 
    291 #ifdef CONFIG_DEVMAN_EARLY_LAUNCH
    292         spawn("/srv/devman");
    293 #endif
    294290       
    295291        /*
     
    318314        getterm("term/vc6", "/app/klog", false);
    319315
    320 #ifndef CONFIG_DEVMAN_EARLY_LAUNCH
     316#ifdef CONFIG_DEVMAN_EARLY_LAUNCH
     317        spawn("/srv/devman");
     318#else
    321319        getterm("term/vc7", "/srv/devman", false);
    322320#endif
  • uspace/drv/ohci/Makefile

    r889e8e3 r291b8bc  
    3737        main.c \
    3838        hc.c \
     39        ohci.c \
    3940        root_hub.c \
    4041        pci.c
  • uspace/drv/ohci/batch.c

    r889e8e3 r291b8bc  
    118118        instance->next_step = batch_call_in_and_dispose;
    119119        /* TODO: implement */
    120         usb_log_debug("Batch(%p) CONTROL WRITE initialized.\n", instance);
     120        usb_log_debug("Batch(%p) CONTROL READ initialized.\n", instance);
    121121}
    122122/*----------------------------------------------------------------------------*/
  • uspace/drv/ohci/hc.c

    r889e8e3 r291b8bc  
    3939#include <usb/debug.h>
    4040#include <usb/usb.h>
    41 #include <usb/hub.h>
    4241#include <usb/ddfiface.h>
    4342#include <usb/usbdevice.h>
     
    4544#include "hc.h"
    4645
    47 static int dummy_reset(int foo, void *arg);
    4846static int interrupt_emulator(hc_t *instance);
     47/*----------------------------------------------------------------------------*/
     48int hc_register_hub(hc_t *instance, ddf_fun_t *hub_fun)
     49{
     50        assert(instance);
     51        assert(hub_fun);
     52
     53        usb_address_t hub_address =
     54            device_keeper_get_free_address(&instance->manager, USB_SPEED_FULL);
     55        instance->rh.address = hub_address;
     56        usb_device_keeper_bind(
     57            &instance->manager, hub_address, hub_fun->handle);
     58
     59        char *match_str = NULL;
     60        int ret = asprintf(&match_str, "usb&mid");
     61        ret = (match_str == NULL) ? ret : EOK;
     62        if (ret < 0) {
     63                usb_log_error("Failed to create root hub match-id string.\n");
     64                return ret;
     65        }
     66
     67        ret = ddf_fun_add_match_id(hub_fun, match_str, 100);
     68        if (ret != EOK) {
     69                usb_log_error("Failed add create root hub match-id.\n");
     70        }
     71        return ret;
     72}
    4973/*----------------------------------------------------------------------------*/
    5074int hc_init(hc_t *instance, ddf_fun_t *fun, ddf_dev_t *dev,
     
    6892        }
    6993
     94        rh_init(&instance->rh, dev, instance->registers);
    7095
    71         rh_init(&instance->rh, dev, instance->registers);
    7296        /* TODO: implement */
    73         return EOK;
    74 }
    75 /*----------------------------------------------------------------------------*/
    76 int hc_register_hub(hc_t *instance)
    77 {
    78         async_usleep(1000000);
    79 #define CHECK_RET_RETURN(ret, msg...) \
    80         if (ret != EOK) { \
    81                 usb_log_error(msg); \
    82                 return ret; \
    83         } else (void)0
    84         assert(instance);
    85         assert(instance->ddf_instance);
    86         assert(instance->ddf_instance->handle);
    87         ddf_dev_t *dev = instance->rh.device;
    88         int ret = EOK;
    89 
    90         usb_hc_connection_t conn;
    91         ret =
    92             usb_hc_connection_initialize(&conn, instance->ddf_instance->handle);
    93         CHECK_RET_RETURN(ret, "Failed to initialize hc connection.\n");
    94 
    95         ret = usb_hc_connection_open(&conn);
    96         CHECK_RET_RETURN(ret, "Failed to open hc connection.\n");
    97 
    98         usb_address_t address;
    99         devman_handle_t handle;
    100         ret = usb_hc_new_device_wrapper(dev, &conn, USB_SPEED_FULL, dummy_reset,
    101             0, instance, &address, &handle, NULL, NULL, NULL);
    102         if (ret != EOK) {
    103                 usb_log_error("Failed to add rh device.\n");
    104                 instance->rh.address = -1;
    105                 return ret;
    106         }
    107 
    108         ret = usb_hc_connection_close(&conn);
    109         CHECK_RET_RETURN(ret, "Failed to close hc connection.\n");
    11097        return EOK;
    11198}
     
    134121}
    135122/*----------------------------------------------------------------------------*/
    136 static int dummy_reset(int foo, void *arg)
    137 {
    138         hc_t *hc = (hc_t*)arg;
    139         assert(hc);
    140         hc->rh.address = 0;
    141         return EOK;
    142 }
    143 /*----------------------------------------------------------------------------*/
    144 static int interrupt_emulator(hc_t *instance)
     123int interrupt_emulator(hc_t *instance)
    145124{
    146125        assert(instance);
  • uspace/drv/ohci/hc.h

    r889e8e3 r291b8bc  
    5757} hc_t;
    5858
     59int hc_register_hub(hc_t *instance, ddf_fun_t *hub_fun);
     60
    5961int hc_init(hc_t *instance, ddf_fun_t *fun, ddf_dev_t *dev,
    6062     uintptr_t regs, size_t reg_size, bool interrupts);
    61 
    62 int hc_register_hub(hc_t *instance);
    6363
    6464int hc_schedule(hc_t *instance, usb_transfer_batch_t *batch);
  • uspace/drv/ohci/iface.h

    r889e8e3 r291b8bc  
    3333 * Common OHCI definitions.
    3434 */
    35 #ifndef DRV_OHCI_OHCI_H
    36 #define DRV_OHCI_OHCI_H
     35#ifndef DRV_OHCI_IFACE_H
     36#define DRV_OHCI_IFACE_H
    3737
    3838#include <usbhc_iface.h>
    39 
    40 #define NAME "ohci"
    4139
    4240extern usbhc_iface_t hc_iface;
  • uspace/drv/ohci/main.c

    r889e8e3 r291b8bc  
    3434 */
    3535#include <ddf/driver.h>
    36 #include <ddf/interrupt.h>
    37 #include <device/hw_res.h>
    3836#include <errno.h>
    3937#include <str_error.h>
    4038
    41 #include <usb_iface.h>
    42 #include <usb/ddfiface.h>
    4339#include <usb/debug.h>
    4440
    45 #include "pci.h"
    46 #include "iface.h"
    47 #include "hc.h"
     41#include "ohci.h"
     42
     43#define NAME "ohci"
    4844
    4945static int ohci_add_device(ddf_dev_t *device);
    50 static int get_hc_handle(ddf_fun_t *fun, devman_handle_t *handle)
    51 {
    52         assert(handle);
    53   assert(fun != NULL);
    54 
    55   *handle = fun->handle;
    56   return EOK;
    57 }
    58 /*----------------------------------------------------------------------------*/
    59 static int get_address(
    60     ddf_fun_t *fun, devman_handle_t handle, usb_address_t *address)
    61 {
    62         assert(fun);
    63         usb_device_keeper_t *manager = &fun_to_hc(fun)->manager;
    64   usb_address_t addr = usb_device_keeper_find(manager, handle);
    65   if (addr < 0) {
    66     return addr;
    67   }
    68 
    69   if (address != NULL) {
    70     *address = addr;
    71   }
    72 
    73   return EOK;
    74 }
    75 /*----------------------------------------------------------------------------*/
    76 /** IRQ handling callback, identifies device
    77  *
    78  * @param[in] dev DDF instance of the device to use.
    79  * @param[in] iid (Unused).
    80  * @param[in] call Pointer to the call that represents interrupt.
    81  */
    82 static void irq_handler(ddf_dev_t *dev, ipc_callid_t iid, ipc_call_t *call)
    83 {
    84         assert(dev);
    85         hc_t *hc = (hc_t*)dev->driver_data;
    86         assert(hc);
    87         hc_interrupt(hc, 0);
    88 }
    8946/*----------------------------------------------------------------------------*/
    9047static driver_ops_t ohci_driver_ops = {
     
    9754};
    9855/*----------------------------------------------------------------------------*/
    99 static usb_iface_t hc_usb_iface = {
    100         .get_address = get_address,
    101         .get_hc_handle = get_hc_handle,
    102 };
    103 /*----------------------------------------------------------------------------*/
    104 static ddf_dev_ops_t hc_ops = {
    105         .interfaces[USB_DEV_IFACE] = &hc_usb_iface,
    106         .interfaces[USBHC_DEV_IFACE] = &hc_iface,
    107 };
    108 /*----------------------------------------------------------------------------*/
    10956/** Initializes a new ddf driver instance of OHCI hcd.
    11057 *
     
    11259 * @return Error code.
    11360 */
    114 static int ohci_add_device(ddf_dev_t *device)
     61int ohci_add_device(ddf_dev_t *device)
    11562{
     63        usb_log_debug("ohci_add_device() called\n");
    11664        assert(device);
    117 #define CHECK_RET_RETURN(ret, message...) \
    118 if (ret != EOK) { \
    119         usb_log_error(message); \
    120         return ret; \
    121 }
    122 
    123         uintptr_t mem_reg_base = 0;
    124         size_t mem_reg_size = 0;
    125         int irq = 0;
    126 
    127         int ret =
    128             pci_get_my_registers(device, &mem_reg_base, &mem_reg_size, &irq);
    129         CHECK_RET_RETURN(ret,
    130             "Failed(%d) to get memory addresses:.\n", ret, device->handle);
    131         usb_log_info("Memory mapped regs at 0x%X (size %zu), IRQ %d.\n",
    132             mem_reg_base, mem_reg_size, irq);
    133 
    134         ret = pci_disable_legacy(device);
    135         CHECK_RET_RETURN(ret,
    136             "Failed(%d) disable legacy USB: %s.\n", ret, str_error(ret));
    137 
    138         hc_t *hcd = malloc(sizeof(hc_t));
    139         if (hcd == NULL) {
     65        ohci_t *ohci = malloc(sizeof(ohci_t));
     66        if (ohci == NULL) {
    14067                usb_log_error("Failed to allocate OHCI driver.\n");
    14168                return ENOMEM;
    14269        }
    14370
    144         ddf_fun_t *hc_fun = ddf_fun_create(device, fun_exposed, "ohci-hc");
    145         if (hc_fun == NULL) {
    146                 usb_log_error("Failed to create OHCI function.\n");
    147                 free(hcd);
    148                 return ENOMEM;
    149         }
    150 
    151 
    152         bool interrupts = false;
    153 #ifdef CONFIG_USBHC_NO_INTERRUPTS
    154         usb_log_warning("Interrupts disabled in OS config, " \
    155             "falling back to polling.\n");
    156 #else
    157         ret = pci_enable_interrupts(device);
     71        int ret = ohci_init(ohci, device);
    15872        if (ret != EOK) {
    159                 usb_log_warning("Failed to enable interrupts: %s.\n",
     73                usb_log_error("Failed to initialize OHCI driver: %s.\n",
    16074                    str_error(ret));
    161                 usb_log_info("HW interrupts not available, " \
    162                     "falling back to polling.\n");
    163         } else {
    164                 usb_log_debug("Hw interrupts enabled.\n");
    165                 interrupts = true;
    166         }
    167 #endif
    168 
    169         ret = hc_init(hcd, hc_fun, device, mem_reg_base, mem_reg_size, interrupts);
    170         if (ret != EOK) {
    171                 usb_log_error("Failed to initialize OHCI driver.\n");
    172                 free(hcd);
    17375                return ret;
    17476        }
     77        device->driver_data = ohci;
    17578
    176         ret = register_interrupt_handler(device, irq, irq_handler, NULL);
    177 
    178         hc_fun->ops = &hc_ops;
    179         ret = ddf_fun_bind(hc_fun);
    180         if (ret != EOK) {
    181                 usb_log_error("Failed to bind OHCI function.\n");
    182                 ddf_fun_destroy(hc_fun);
    183                 free(hcd);
    184                 return ret;
    185         }
    186         hc_fun->driver_data = hcd;
    187 
    188         fid_t later = fibril_create((int(*)(void*))hc_register_hub, hcd);
    189         fibril_add_ready(later);
    190 
    191         usb_log_info("Controlling new OHCI device `%s' (handle %llu).\n",
    192             device->name, device->handle);
     79        usb_log_info("Controlling new OHCI device `%s'.\n", device->name);
    19380
    19481        return EOK;
    195 #undef CHECK_RET_RETURN
    19682}
    19783/*----------------------------------------------------------------------------*/
  • uspace/drv/ohci/ohci.h

    r889e8e3 r291b8bc  
    11/*
    2  * Copyright (c) 2011 Lubos Slovak
     2 * Copyright (c) 2011 Jan Vesely
    33 * All rights reserved.
    44 *
     
    2727 */
    2828
    29 /** @addtogroup drvusbhid
     29/** @addtogroup drvusbohci
    3030 * @{
    3131 */
    3232/** @file
    33  * USB HID keyboard autorepeat facilities
     33 * @brief OHCI driver main structure for both host controller and root-hub.
    3434 */
     35#ifndef DRV_OHCI_OHCI_H
     36#define DRV_OHCI_OHCI_H
     37#include <ddi.h>
     38#include <ddf/driver.h>
    3539
    36 #ifndef USBHID_KBDREPEAT_H_
    37 #define USBHID_KBDREPEAT_H_
     40#include "hc.h"
     41#include "root_hub.h"
    3842
    39 #include "kbddev.h"
     43typedef struct ohci {
     44        ddf_fun_t *hc_fun;
     45        ddf_fun_t *rh_fun;
    4046
    41 /*----------------------------------------------------------------------------*/
     47        hc_t hc;
     48        rh_t rh;
     49} ohci_t;
    4250
    43 int usbhid_kbd_repeat_fibril(void *arg);
     51int ohci_init(ohci_t *instance, ddf_dev_t *device);
    4452
    45 void usbhid_kbd_repeat_start(usbhid_kbd_t *kbd, unsigned int key);
    46 
    47 void usbhid_kbd_repeat_stop(usbhid_kbd_t *kbd, unsigned int key);
    48 
    49 #endif /* USBHID_KBDREPEAT_H_ */
    50 
     53#endif
    5154/**
    5255 * @}
  • uspace/drv/ohci/root_hub.c

    r889e8e3 r291b8bc  
    3939
    4040#include "root_hub.h"
     41#include "usb/classes/classes.h"
     42#include <usb/request.h>
     43#include <usb/classes/hub.h>
     44
     45static const usb_standard_device_descriptor_t ohci_rh_device_descriptor =
     46{
     47                .configuration_count = 1,
     48                .descriptor_type = USB_DESCTYPE_DEVICE,
     49                .device_class = USB_CLASS_HUB,
     50                .device_protocol = 0,
     51                .device_subclass = 0,
     52                .device_version = 0,
     53                .length = sizeof(usb_standard_device_descriptor_t),
     54                /// \TODO this value is guessed
     55                .max_packet_size = 8,
     56                .vendor_id = 0x16db,
     57                .product_id = 0x0001,
     58                /// \TODO these values migt be different
     59                .str_serial_number = 0,
     60                .usb_spec_version = 0,
     61};
     62
     63static const usb_standard_configuration_descriptor_t ohci_rh_conf_descriptor =
     64{
     65        /// \TODO some values are default or guessed
     66        .attributes = 1<<7,
     67        .configuration_number = 1,
     68        .descriptor_type = USB_DESCTYPE_CONFIGURATION,
     69        .interface_count = 1,
     70        .length = sizeof(usb_standard_configuration_descriptor_t),
     71        .max_power = 100,
     72        .str_configuration = 0,
     73};
     74
     75static const usb_standard_interface_descriptor_t ohci_rh_iface_descriptor =
     76{
     77        .alternate_setting = 0,
     78        .descriptor_type = USB_DESCTYPE_INTERFACE,
     79        .endpoint_count = 1,
     80        .interface_class = USB_CLASS_HUB,
     81        /// \TODO is this correct?
     82        .interface_number = 1,
     83        .interface_protocol = 0,
     84        .interface_subclass = 0,
     85        .length = sizeof(usb_standard_interface_descriptor_t),
     86        .str_interface = 0,
     87};
     88
     89static const usb_standard_endpoint_descriptor_t ohci_rh_ep_descriptor =
     90{
     91        .attributes = USB_TRANSFER_INTERRUPT,
     92        .descriptor_type = USB_DESCTYPE_ENDPOINT,
     93        .endpoint_address = 1 + (1<<7),
     94        .length = sizeof(usb_standard_endpoint_descriptor_t),
     95        .max_packet_size = 8,
     96        .poll_interval = 255,
     97};
    4198
    4299/** Root hub initialization
     
    50107        instance->device = dev;
    51108
     109
    52110        usb_log_info("OHCI root hub with %d ports.\n", regs->rh_desc_a & 0xff);
    53111
     112        //start generic usb hub driver
     113       
    54114        /* TODO: implement */
    55115        return EOK;
    56116}
    57117/*----------------------------------------------------------------------------*/
     118
     119
     120static int process_get_port_status_request(rh_t *instance, uint16_t port,
     121                usb_transfer_batch_t * request){
     122        if(port<1 || port>instance->port_count)
     123                return EINVAL;
     124        uint32_t * uint32_buffer = (uint32_t*)request->buffer;
     125        request->transfered_size = 4;
     126        uint32_buffer[0] = instance->registers->rh_port_status[port -1];
     127        return EOK;
     128}
     129
     130static int process_get_hub_status_request(rh_t *instance,
     131                usb_transfer_batch_t * request){
     132        uint32_t * uint32_buffer = (uint32_t*)request->buffer;
     133        //bits, 0,1,16,17
     134        request->transfered_size = 4;
     135        uint32_t mask = 1 & (1<<1) & (1<<16) & (1<<17);
     136        uint32_buffer[0] = mask & instance->registers->rh_status;
     137        return EOK;
     138
     139}
     140
     141static void usb_create_serialized_hub_descriptor(rh_t *instance, uint8_t ** out_result,
     142                size_t * out_size) {
     143        //base size
     144        size_t size = 7;
     145        //variable size according to port count
     146        size_t var_size = instance->port_count / 8 +
     147                        ((instance->port_count % 8 > 0) ? 1 : 0);
     148        size += 2 * var_size;
     149        uint8_t * result = (uint8_t*) malloc(size);
     150        bzero(result,size);
     151        //size
     152        result[0] = size;
     153        //descriptor type
     154        result[1] = USB_DESCTYPE_HUB;
     155        result[2] = instance->port_count;
     156        uint32_t hub_desc_reg = instance->registers->rh_desc_a;
     157        result[3] =
     158                        ((hub_desc_reg >> 8) %2) +
     159                        (((hub_desc_reg >> 9) %2) << 1) +
     160                        (((hub_desc_reg >> 10) %2) << 2) +
     161                        (((hub_desc_reg >> 11) %2) << 3) +
     162                        (((hub_desc_reg >> 12) %2) << 4);
     163        result[4] = 0;
     164        result[5] = /*descriptor->pwr_on_2_good_time*/ 50;
     165        result[6] = 50;
     166
     167        int port;
     168        for (port = 1; port <= instance->port_count; ++port) {
     169                result[7 + port/8] +=
     170                                ((instance->registers->rh_desc_b >> port)%2) << (port%8);
     171        }
     172        size_t i;
     173        for (i = 0; i < var_size; ++i) {
     174                result[7 + var_size + i] = 255;
     175        }
     176        (*out_result) = result;
     177        (*out_size) = size;
     178}
     179
     180
     181static int process_get_status_request(rh_t *instance,
     182                usb_transfer_batch_t * request)
     183{
     184        size_t buffer_size = request->buffer_size;
     185        usb_device_request_setup_packet_t * request_packet =
     186                        (usb_device_request_setup_packet_t*)
     187                        request->setup_buffer;
     188
     189        usb_hub_bm_request_type_t request_type = request_packet->request_type;
     190        if(buffer_size<4/*request_packet->length*/){///\TODO
     191                usb_log_warning("requested more data than buffer size\n");
     192                return EINVAL;
     193        }
     194
     195        if(request_type == USB_HUB_REQ_TYPE_GET_HUB_STATUS)
     196                return process_get_hub_status_request(instance, request);
     197        if(request_type == USB_HUB_REQ_TYPE_GET_PORT_STATUS)
     198                return process_get_port_status_request(instance, request_packet->index,
     199                                request);
     200        return ENOTSUP;
     201}
     202
     203static void create_interrupt_mask(rh_t *instance, void ** buffer,
     204                size_t * buffer_size){
     205        int bit_count = instance->port_count + 1;
     206        (*buffer_size) = (bit_count / 8) + (bit_count%8==0)?0:1;
     207        (*buffer) = malloc(*buffer_size);
     208        uint8_t * bitmap = (uint8_t*)(*buffer);
     209        uint32_t mask = (1<<16) + (1<<17);
     210        bzero(bitmap,(*buffer_size));
     211        if(instance->registers->rh_status & mask){
     212                bitmap[0] = 1;
     213        }
     214        int port;
     215        mask = 0;
     216        int i;
     217        for(i=16;i<=20;++i)
     218                mask += 1<<i;
     219        for(port = 1; port<=instance->port_count;++port){
     220                if(mask & instance->registers->rh_port_status[port-1]){
     221                        bitmap[(port+1)/8] += 1<<(port%8);
     222                }
     223        }
     224}
     225
     226
     227static int process_get_descriptor_request(rh_t *instance,
     228                usb_transfer_batch_t *request){
     229        /// \TODO
     230        usb_device_request_setup_packet_t * setup_request =
     231                        (usb_device_request_setup_packet_t*)request->setup_buffer;
     232        size_t size;
     233        const void * result_descriptor;
     234        const uint16_t setup_request_value = setup_request->value_high;
     235                        //(setup_request->value_low << 8);
     236        bool del = false;
     237
     238        switch (setup_request_value)
     239        {
     240        case USB_DESCTYPE_HUB: {
     241                uint8_t * descriptor;
     242                usb_create_serialized_hub_descriptor(
     243                    instance, &descriptor, &size);
     244                result_descriptor = descriptor;
     245                break;
     246        }
     247        case USB_DESCTYPE_DEVICE: {
     248                usb_log_debug("USB_DESCTYPE_DEVICE\n");
     249                result_descriptor = &ohci_rh_device_descriptor;
     250                size = sizeof(ohci_rh_device_descriptor);
     251                break;
     252        }
     253        case USB_DESCTYPE_CONFIGURATION: {
     254                usb_log_debug("USB_DESCTYPE_CONFIGURATION\n");
     255                usb_standard_configuration_descriptor_t * descriptor =
     256                                malloc(sizeof(usb_standard_configuration_descriptor_t));
     257                memcpy(descriptor, &ohci_rh_conf_descriptor,
     258                    sizeof(usb_standard_configuration_descriptor_t));
     259                /// \TODO should this include device descriptor?
     260                const size_t hub_descriptor_size = 7 +
     261                                2* (instance->port_count / 8 +
     262                                ((instance->port_count % 8 > 0) ? 1 : 0));
     263                descriptor->total_length =
     264                                sizeof(usb_standard_configuration_descriptor_t)+
     265                                sizeof(usb_standard_endpoint_descriptor_t)+
     266                                sizeof(usb_standard_interface_descriptor_t)+
     267                                hub_descriptor_size;
     268                result_descriptor = descriptor;
     269                size = sizeof(usb_standard_configuration_descriptor_t);
     270                del = true;
     271                break;
     272        }
     273        case USB_DESCTYPE_INTERFACE: {
     274                usb_log_debug("USB_DESCTYPE_INTERFACE\n");
     275                result_descriptor = &ohci_rh_iface_descriptor;
     276                size = sizeof(ohci_rh_iface_descriptor);
     277                break;
     278        }
     279        case USB_DESCTYPE_ENDPOINT: {
     280                usb_log_debug("USB_DESCTYPE_ENDPOINT\n");
     281                result_descriptor = &ohci_rh_ep_descriptor;
     282                size = sizeof(ohci_rh_ep_descriptor);
     283                break;
     284        }
     285        default: {
     286                usb_log_debug("USB_DESCTYPE_EINVAL %d \n",setup_request->value);
     287                usb_log_debug("\ttype %d\n\trequest %d\n\tvalue %d\n\tindex %d\n\tlen %d\n ",
     288                                setup_request->request_type,
     289                                setup_request->request,
     290                                setup_request_value,
     291                                setup_request->index,
     292                                setup_request->length
     293                                );
     294                return EINVAL;
     295        }
     296        }
     297#if 0
     298        if(setup_request_value == USB_DESCTYPE_HUB){
     299                usb_log_debug("USB_DESCTYPE_HUB\n");
     300                //create hub descriptor
     301                uint8_t * descriptor;
     302                usb_create_serialized_hub_descriptor(instance,
     303                                &descriptor, &size);
     304                result_descriptor = descriptor;
     305        }else if(setup_request_value == USB_DESCTYPE_DEVICE){
     306                //create std device descriptor
     307                usb_log_debug("USB_DESCTYPE_DEVICE\n");
     308                usb_standard_device_descriptor_t * descriptor =
     309                                (usb_standard_device_descriptor_t*)
     310                                malloc(sizeof(usb_standard_device_descriptor_t));
     311                descriptor->configuration_count = 1;
     312                descriptor->descriptor_type = USB_DESCTYPE_DEVICE;
     313                descriptor->device_class = USB_CLASS_HUB;
     314                descriptor->device_protocol = 0;
     315                descriptor->device_subclass = 0;
     316                descriptor->device_version = 0;
     317                descriptor->length = sizeof(usb_standard_device_descriptor_t);
     318                /// \TODO this value is guessed
     319                descriptor->max_packet_size = 8;
     320                descriptor->product_id = 0x0001;
     321                /// \TODO these values migt be different
     322                descriptor->str_serial_number = 0;
     323                descriptor->str_serial_number = 0;
     324                descriptor->usb_spec_version = 0;
     325                descriptor->vendor_id = 0x16db;
     326                result_descriptor = descriptor;
     327                size = sizeof(usb_standard_device_descriptor_t);
     328        }else if(setup_request_value == USB_DESCTYPE_CONFIGURATION){
     329                usb_log_debug("USB_DESCTYPE_CONFIGURATION\n");
     330                usb_standard_configuration_descriptor_t * descriptor =
     331                                (usb_standard_configuration_descriptor_t*)
     332                                malloc(sizeof(usb_standard_configuration_descriptor_t));
     333                /// \TODO some values are default or guessed
     334                descriptor->attributes = 1<<7;
     335                descriptor->configuration_number = 1;
     336                descriptor->descriptor_type = USB_DESCTYPE_CONFIGURATION;
     337                descriptor->interface_count = 1;
     338                descriptor->length = sizeof(usb_standard_configuration_descriptor_t);
     339                descriptor->max_power = 100;
     340                descriptor->str_configuration = 0;
     341                /// \TODO should this include device descriptor?
     342                size_t hub_descriptor_size = 7 +
     343                                2* (instance->port_count / 8 +
     344                                ((instance->port_count % 8 > 0) ? 1 : 0));
     345                descriptor->total_length =
     346                                sizeof(usb_standard_configuration_descriptor_t)+
     347                                sizeof(usb_standard_endpoint_descriptor_t)+
     348                                sizeof(usb_standard_interface_descriptor_t)+
     349                                hub_descriptor_size;
     350                result_descriptor = descriptor;
     351                size = sizeof(usb_standard_configuration_descriptor_t);
     352
     353        }else if(setup_request_value == USB_DESCTYPE_INTERFACE){
     354                usb_log_debug("USB_DESCTYPE_INTERFACE\n");
     355                usb_standard_interface_descriptor_t * descriptor =
     356                                (usb_standard_interface_descriptor_t*)
     357                                malloc(sizeof(usb_standard_interface_descriptor_t));
     358                descriptor->alternate_setting = 0;
     359                descriptor->descriptor_type = USB_DESCTYPE_INTERFACE;
     360                descriptor->endpoint_count = 1;
     361                descriptor->interface_class = USB_CLASS_HUB;
     362                /// \TODO is this correct?
     363                descriptor->interface_number = 1;
     364                descriptor->interface_protocol = 0;
     365                descriptor->interface_subclass = 0;
     366                descriptor->length = sizeof(usb_standard_interface_descriptor_t);
     367                descriptor->str_interface = 0;
     368                result_descriptor = descriptor;
     369                size = sizeof(usb_standard_interface_descriptor_t);
     370        }else if(setup_request_value == USB_DESCTYPE_ENDPOINT){
     371                usb_log_debug("USB_DESCTYPE_ENDPOINT\n");
     372                usb_standard_endpoint_descriptor_t * descriptor =
     373                                (usb_standard_endpoint_descriptor_t*)
     374                                malloc(sizeof(usb_standard_endpoint_descriptor_t));
     375                descriptor->attributes = USB_TRANSFER_INTERRUPT;
     376                descriptor->descriptor_type = USB_DESCTYPE_ENDPOINT;
     377                descriptor->endpoint_address = 1 + (1<<7);
     378                descriptor->length = sizeof(usb_standard_endpoint_descriptor_t);
     379                descriptor->max_packet_size = 8;
     380                descriptor->poll_interval = 255;
     381                result_descriptor = descriptor;
     382                size = sizeof(usb_standard_endpoint_descriptor_t);
     383        }else{
     384                usb_log_debug("USB_DESCTYPE_EINVAL %d \n",setup_request->value);
     385                usb_log_debug("\ttype %d\n\trequest %d\n\tvalue %d\n\tindex %d\n\tlen %d\n ",
     386                                setup_request->request_type,
     387                                setup_request->request,
     388                                setup_request_value,
     389                                setup_request->index,
     390                                setup_request->length
     391                                );
     392                return EINVAL;
     393        }
     394#endif
     395        if(request->buffer_size < size){
     396                size = request->buffer_size;
     397        }
     398        request->transfered_size = size;
     399        memcpy(request->buffer,result_descriptor,size);
     400        if (del)
     401                free(result_descriptor);
     402        return EOK;
     403}
     404
     405static int process_get_configuration_request(rh_t *instance,
     406                usb_transfer_batch_t *request){
     407        //set and get configuration requests do not have any meaning, only dummy
     408        //values are returned
     409        if(request->buffer_size != 1)
     410                return EINVAL;
     411        request->buffer[0] = 1;
     412        request->transfered_size = 1;
     413        return EOK;
     414}
     415
     416static int process_hub_feature_set_request(rh_t *instance,
     417                uint16_t feature, bool enable){
     418        if(feature > USB_HUB_FEATURE_C_HUB_OVER_CURRENT)
     419                return EINVAL;
     420        instance->registers->rh_status =
     421                        enable ?
     422                        (instance->registers->rh_status | (1<<feature))
     423                        :
     424                        (instance->registers->rh_status & (~(1<<feature)));
     425        /// \TODO any error?
     426        return EOK;
     427}
     428
     429static int process_port_feature_set_request(rh_t *instance,
     430                uint16_t feature, uint16_t port, bool enable){
     431        if(feature > USB_HUB_FEATURE_C_PORT_RESET)
     432                return EINVAL;
     433        if(port<1 || port>instance->port_count)
     434                return EINVAL;
     435        instance->registers->rh_port_status[port - 1] =
     436                        enable ?
     437                        (instance->registers->rh_port_status[port - 1] | (1<<feature))
     438                        :
     439                        (instance->registers->rh_port_status[port - 1] & (~(1<<feature)));
     440        /// \TODO any error?
     441        return EOK;
     442}
     443
     444static int process_address_set_request(rh_t *instance,
     445                uint16_t address){
     446        instance->address = address;
     447        return EOK;
     448}
     449
     450static int process_request_with_output(rh_t *instance,
     451                usb_transfer_batch_t *request){
     452        usb_device_request_setup_packet_t * setup_request =
     453                        (usb_device_request_setup_packet_t*)request->setup_buffer;
     454        if(setup_request->request == USB_DEVREQ_GET_STATUS){
     455                usb_log_debug("USB_DEVREQ_GET_STATUS\n");
     456                return process_get_status_request(instance, request);
     457        }
     458        if(setup_request->request == USB_DEVREQ_GET_DESCRIPTOR){
     459                usb_log_debug("USB_DEVREQ_GET_DESCRIPTOR\n");
     460                return process_get_descriptor_request(instance, request);
     461        }
     462        if(setup_request->request == USB_DEVREQ_GET_CONFIGURATION){
     463                usb_log_debug("USB_DEVREQ_GET_CONFIGURATION\n");
     464                return process_get_configuration_request(instance, request);
     465        }
     466        return ENOTSUP;
     467}
     468
     469static int process_request_with_input(rh_t *instance,
     470                usb_transfer_batch_t *request){
     471        usb_device_request_setup_packet_t * setup_request =
     472                        (usb_device_request_setup_packet_t*)request->setup_buffer;
     473        request->transfered_size = 0;
     474        if(setup_request->request == USB_DEVREQ_SET_DESCRIPTOR){
     475                return ENOTSUP;
     476        }
     477        if(setup_request->request == USB_DEVREQ_SET_CONFIGURATION){
     478                //set and get configuration requests do not have any meaning,
     479                //only dummy values are returned
     480                return EOK;
     481        }
     482        return ENOTSUP;
     483}
     484
     485
     486static int process_request_without_data(rh_t *instance,
     487                usb_transfer_batch_t *request){
     488        usb_device_request_setup_packet_t * setup_request =
     489                        (usb_device_request_setup_packet_t*)request->setup_buffer;
     490        request->transfered_size = 0;
     491        if(setup_request->request == USB_DEVREQ_CLEAR_FEATURE
     492                                || setup_request->request == USB_DEVREQ_SET_FEATURE){
     493                if(setup_request->request_type == USB_HUB_REQ_TYPE_SET_HUB_FEATURE){
     494                        usb_log_debug("USB_HUB_REQ_TYPE_SET_HUB_FEATURE\n");
     495                        return process_hub_feature_set_request(instance, setup_request->value,
     496                                        setup_request->request == USB_DEVREQ_SET_FEATURE);
     497                }
     498                if(setup_request->request_type == USB_HUB_REQ_TYPE_SET_PORT_FEATURE){
     499                        usb_log_debug("USB_HUB_REQ_TYPE_SET_PORT_FEATURE\n");
     500                        return process_port_feature_set_request(instance, setup_request->value,
     501                                        setup_request->index,
     502                                        setup_request->request == USB_DEVREQ_SET_FEATURE);
     503                }
     504                usb_log_debug("USB_HUB_REQ_TYPE_INVALID %d\n",setup_request->request_type);
     505                return EINVAL;
     506        }
     507        if(setup_request->request == USB_DEVREQ_SET_ADDRESS){
     508                usb_log_debug("USB_DEVREQ_SET_ADDRESS\n");
     509                return process_address_set_request(instance, setup_request->value);
     510        }
     511        usb_log_debug("USB_DEVREQ_SET_ENOTSUP %d\n",setup_request->request_type);
     512        return ENOTSUP;
     513}
     514
     515
     516/**
     517 *
     518 * @param instance
     519 * @param request
     520 * @return
     521 */
    58522int rh_request(rh_t *instance, usb_transfer_batch_t *request)
    59523{
    60524        assert(instance);
    61525        assert(request);
    62         /* TODO: implement */
    63         if (request->setup_buffer) {
    64                 usb_log_info("Root hub got SETUP packet: %s.\n",
    65                     usb_debug_str_buffer((const uint8_t *)request->setup_buffer, 8, 8));
    66         }
    67         usb_log_error("Root hub request processing not implemented.\n");
    68         usb_transfer_batch_finish(request, ENOTSUP);
     526        int opResult;
     527        if(request->transfer_type == USB_TRANSFER_CONTROL){
     528                if (request->setup_buffer) {
     529                        usb_log_info("Root hub got CTRL packet: %s.\n",
     530                                usb_debug_str_buffer((const uint8_t *)request->setup_buffer, 8, 8));
     531                        if(sizeof(usb_device_request_setup_packet_t)>request->setup_size){
     532                                usb_log_error("setup packet too small\n");
     533                                return EINVAL;
     534                        }
     535                        usb_device_request_setup_packet_t * setup_request =
     536                                        (usb_device_request_setup_packet_t*)request->setup_buffer;
     537                        if(
     538                                setup_request->request == USB_DEVREQ_GET_STATUS
     539                                || setup_request->request == USB_DEVREQ_GET_DESCRIPTOR
     540                                || setup_request->request == USB_DEVREQ_GET_CONFIGURATION
     541                        ){
     542                                usb_log_debug("processing request with output\n");
     543                                opResult = process_request_with_output(instance,request);
     544                        }else if(
     545                                setup_request->request == USB_DEVREQ_CLEAR_FEATURE
     546                                || setup_request->request == USB_DEVREQ_SET_FEATURE
     547                                || setup_request->request == USB_DEVREQ_SET_ADDRESS
     548                        ){
     549                                usb_log_debug("processing request without additional data\n");
     550                                opResult = process_request_without_data(instance,request);
     551                        }else if(setup_request->request == USB_DEVREQ_SET_DESCRIPTOR
     552                                        || setup_request->request == USB_DEVREQ_SET_CONFIGURATION
     553                        ){
     554                                usb_log_debug("processing request with input\n");
     555                                opResult = process_request_with_input(instance,request);
     556                        }else{
     557                                usb_log_warning("received unsuported request: %d\n",
     558                                                setup_request->request
     559                                                );
     560                                opResult = ENOTSUP;
     561                        }
     562                }else{
     563                        usb_log_error("root hub received empty transaction?");
     564                        opResult = EINVAL;
     565                }
     566        }else if(request->transfer_type == USB_TRANSFER_INTERRUPT){
     567                usb_log_info("Root hub got INTERRUPT packet\n");
     568                void * buffer;
     569                create_interrupt_mask(instance, &buffer,
     570                        &(request->transfered_size));
     571                memcpy(request->transport_buffer,buffer, request->transfered_size);
     572                opResult = EOK;
     573        }else{
     574                opResult = EINVAL;
     575        }
     576        usb_transfer_batch_finish(request, opResult);
    69577        return EOK;
    70578}
    71579/*----------------------------------------------------------------------------*/
     580
     581
    72582void rh_interrupt(rh_t *instance)
    73583{
  • uspace/drv/ohci/root_hub.h

    r889e8e3 r291b8bc  
    4545        usb_address_t address;
    4646        ddf_dev_t *device;
     47        int port_count;
    4748} rh_t;
    4849
  • uspace/drv/uhci-hcd/Makefile

    r889e8e3 r291b8bc  
    4040        root_hub.c \
    4141        hw_struct/transfer_descriptor.c \
     42        utils/slab.c \
    4243        pci.c \
    4344        batch.c
  • uspace/drv/uhci-hcd/hc.c

    r889e8e3 r291b8bc  
    223223        ret = instance ? EOK : ENOMEM;
    224224        CHECK_RET_DEST_CMDS_RETURN(ret, "Failed to get frame list page.\n");
    225         usb_log_debug("Initialized frame list.\n");
     225        usb_log_debug("Initialized frame list at %p.\n", instance->frame_list);
    226226
    227227        /* Set all frames to point to the first queue head */
     
    336336            instance->transfers[batch->speed][batch->transfer_type];
    337337        assert(list);
     338        if (batch->transfer_type == USB_TRANSFER_CONTROL) {
     339                usb_device_keeper_use_control(
     340                    &instance->manager, batch->target.address);
     341        }
    338342        transfer_list_add_batch(list, batch);
    339343
     
    357361        /* Lower 2 bits are transaction error and transaction complete */
    358362        if (status & 0x3) {
    359                 transfer_list_remove_finished(&instance->transfers_interrupt);
    360                 transfer_list_remove_finished(&instance->transfers_control_slow);
    361                 transfer_list_remove_finished(&instance->transfers_control_full);
    362                 transfer_list_remove_finished(&instance->transfers_bulk_full);
     363                LIST_INITIALIZE(done);
     364                transfer_list_remove_finished(
     365                    &instance->transfers_interrupt, &done);
     366                transfer_list_remove_finished(
     367                    &instance->transfers_control_slow, &done);
     368                transfer_list_remove_finished(
     369                    &instance->transfers_control_full, &done);
     370                transfer_list_remove_finished(
     371                    &instance->transfers_bulk_full, &done);
     372
     373                while (!list_empty(&done)) {
     374                        link_t *item = done.next;
     375                        list_remove(item);
     376                        usb_transfer_batch_t *batch =
     377                            list_get_instance(item, usb_transfer_batch_t, link);
     378                        if (batch->transfer_type == USB_TRANSFER_CONTROL) {
     379                                usb_device_keeper_release_control(
     380                                    &instance->manager, batch->target.address);
     381                        }
     382                        batch->next_step(batch);
     383                }
    363384        }
    364385        /* bits 4 and 5 indicate hc error */
  • uspace/drv/uhci-hcd/root_hub.c

    r889e8e3 r291b8bc  
    4848 * @return Error code.
    4949 */
    50 int rh_init(
    51     rh_t *instance, ddf_fun_t *fun, uintptr_t reg_addr, size_t reg_size)
     50int rh_init(rh_t *instance, ddf_fun_t *fun, uintptr_t reg_addr, size_t reg_size)
    5251{
    5352        assert(fun);
  • uspace/drv/uhci-hcd/transfer_list.c

    r889e8e3 r291b8bc  
    5858        }
    5959        instance->queue_head_pa = addr_to_phys(instance->queue_head);
     60        usb_log_debug2("Transfer list %s setup with QH: %p(%p).\n",
     61            name, instance->queue_head, instance->queue_head_pa);
    6062
    6163        qh_init(instance->queue_head);
     
    118120        qh_set_next_qh(last_qh, pa);
    119121
     122        asm volatile ("": : :"memory");
     123
    120124        /* Add to the driver list */
    121125        list_append(&batch->link, &instance->batch_list);
     
    137141 * this transfer list leading to the deadlock if its done inline.
    138142 */
    139 void transfer_list_remove_finished(transfer_list_t *instance)
    140 {
    141         assert(instance);
    142 
    143         LIST_INITIALIZE(done);
     143void transfer_list_remove_finished(transfer_list_t *instance, link_t *done)
     144{
     145        assert(instance);
     146        assert(done);
    144147
    145148        fibril_mutex_lock(&instance->guard);
     
    153156                        /* Save for post-processing */
    154157                        transfer_list_remove_batch(instance, batch);
    155                         list_append(current, &done);
     158                        list_append(current, done);
    156159                }
    157160                current = next;
     
    159162        fibril_mutex_unlock(&instance->guard);
    160163
    161         while (!list_empty(&done)) {
    162                 link_t *item = done.next;
    163                 list_remove(item);
    164                 usb_transfer_batch_t *batch =
    165                     list_get_instance(item, usb_transfer_batch_t, link);
    166                 batch->next_step(batch);
    167         }
    168164}
    169165/*----------------------------------------------------------------------------*/
     
    222218                qpos = "NOT FIRST";
    223219        }
     220        asm volatile ("": : :"memory");
    224221        /* Remove from the batch list */
    225222        list_remove(&batch->link);
  • uspace/drv/uhci-hcd/transfer_list.h

    r889e8e3 r291b8bc  
    6767void transfer_list_add_batch(transfer_list_t *instance, usb_transfer_batch_t *batch);
    6868
    69 void transfer_list_remove_finished(transfer_list_t *instance);
     69void transfer_list_remove_finished(transfer_list_t *instance, link_t *done);
    7070
    7171void transfer_list_abort_all(transfer_list_t *instance);
  • uspace/drv/uhci-hcd/uhci.c

    r889e8e3 r291b8bc  
    4444#include "pci.h"
    4545
    46 
    4746/** IRQ handling callback, identifies device
    4847 *
     
    108107/*----------------------------------------------------------------------------*/
    109108static ddf_dev_ops_t hc_ops = {
    110         .interfaces[USB_DEV_IFACE] = &usb_iface,
     109//      .interfaces[USB_DEV_IFACE] = &usb_iface,
    111110        .interfaces[USBHC_DEV_IFACE] = &hc_iface, /* see iface.h/c */
    112111};
  • uspace/drv/uhci-hcd/utils/malloc32.h

    r889e8e3 r291b8bc  
    4040#include <as.h>
    4141
     42#include "slab.h"
     43
    4244#define UHCI_STRCUTURES_ALIGNMENT 16
    4345#define UHCI_REQUIRED_PAGE_SIZE 4096
     46
    4447
    4548/** Get physical address translation
     
    5457
    5558        uintptr_t result;
    56         int ret = as_get_physical_mapping(addr, &result);
     59        const int ret = as_get_physical_mapping(addr, &result);
     60        assert(ret == EOK);
    5761
    5862        if (ret != EOK)
     
    6670 * @return Address of the alligned and big enough memory place, NULL on failure.
    6771 */
    68 static inline void * malloc32(size_t size)
    69         { return memalign(UHCI_STRCUTURES_ALIGNMENT, size); }
     72static inline void * malloc32(size_t size) {
     73        if (size <= SLAB_ELEMENT_SIZE)
     74                return slab_malloc_g();
     75        assert(false);
     76        return memalign(UHCI_STRCUTURES_ALIGNMENT, size);
     77}
    7078/*----------------------------------------------------------------------------*/
    7179/** Physical mallocator simulator
     
    7381 * @param[in] addr Address of the place allocated by malloc32
    7482 */
    75 static inline void free32(void *addr)
    76         { if (addr) free(addr); }
     83static inline void free32(void *addr) {
     84        if (!addr)
     85                return;
     86        if (slab_in_range_g(addr))
     87                return slab_free_g(addr);
     88        free(addr);
     89}
    7790/*----------------------------------------------------------------------------*/
    7891/** Create 4KB page mapping
     
    8295static inline void * get_page(void)
    8396{
    84         void * free_address = as_get_mappable_page(UHCI_REQUIRED_PAGE_SIZE);
    85         assert(free_address);
     97        void *free_address = as_get_mappable_page(UHCI_REQUIRED_PAGE_SIZE);
     98        assert(free_address); /* TODO: remove this assert */
    8699        if (free_address == 0)
    87100                return NULL;
    88         void* ret =
    89           as_area_create(free_address, UHCI_REQUIRED_PAGE_SIZE,
     101        void *ret = as_area_create(free_address, UHCI_REQUIRED_PAGE_SIZE,
    90102                  AS_AREA_READ | AS_AREA_WRITE);
    91103        if (ret != free_address)
  • uspace/drv/uhci-hcd/utils/slab.h

    r889e8e3 r291b8bc  
    11/*
    2  * Copyright (c) 2010 Lubos Slovak
     2 * Copyright (c) 2011 Jan Vesely
    33 * All rights reserved.
    44 *
     
    2626 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    2727 */
    28 
    29 /** @addtogroup drvusbhid
     28/** @addtogroup usb
    3029 * @{
    3130 */
    3231/** @file
    33  * Descriptor dumping.
     32 * @brief UHCI driver
    3433 */
     34#ifndef DRV_UHCI_SLAB_H
     35#define DRV_UHCI_SLAB_H
    3536
    36 #ifndef USBHID_DESCDUMP_H_
    37 #define USBHID_DESCDUMP_H_
     37#include <bool.h>
    3838
    39 #include <usb/descriptor.h>
    40 #include <usb/classes/hid.h>
     39#define SLAB_ELEMENT_SIZE 1024
    4140
    42 void dump_standard_configuration_descriptor(
    43     int index, const usb_standard_configuration_descriptor_t *d);
     41void * slab_malloc_g(void);
    4442
    45 void dump_standard_interface_descriptor(
    46     const usb_standard_interface_descriptor_t *d);
     43void slab_free_g(void *addr);
    4744
    48 void dump_standard_endpoint_descriptor(
    49     const usb_standard_endpoint_descriptor_t *d);
     45bool slab_in_range_g(void *addr);
    5046
    51 void dump_standard_hid_descriptor_header(
    52     const usb_standard_hid_descriptor_t *d);
    53 
    54 void dump_standard_hid_class_descriptor_info(
    55     const usb_standard_hid_class_descriptor_info_t *d);
    56 
    57 void dump_hid_class_descriptor(int index, uint8_t type,
    58     const uint8_t *d, size_t size);
    59 
    60 #endif /* USBHID_DESCDUMP_H_ */
    61 
     47#endif
    6248/**
    6349 * @}
  • uspace/drv/usbhub/port_status.h

    r889e8e3 r291b8bc  
    3030 */
    3131
    32 #ifndef PORT_STATUS_H
    33 #define PORT_STATUS_H
     32#ifndef HUB_PORT_STATUS_H
     33#define HUB_PORT_STATUS_H
    3434
    3535#include <bool.h>
     
    335335
    336336
    337 #endif  /* PORT_STATUS_H */
     337#endif  /* HUB_PORT_STATUS_H */
    338338
    339339/**
  • uspace/drv/usbhub/usbhub.c

    r889e8e3 r291b8bc  
    162162            std_descriptor->configuration_count);
    163163        if(std_descriptor->configuration_count<1){
    164                 usb_log_error("THERE ARE NO CONFIGURATIONS AVAILABLE\n");
    165                 //shouldn`t I return?
    166                 //definitely
     164                usb_log_error("there are no configurations available\n");
    167165                return EINVAL;
    168166        }
  • uspace/drv/usbkbd/Makefile

    r889e8e3 r291b8bc  
    3030LIBS = $(LIBDRV_PREFIX)/libdrv.a $(LIBUSB_PREFIX)/libusb.a
    3131EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include -I$(LIBUSB_PREFIX)/include -I.
    32 BINARY = usbhid
     32BINARY = usbkbd
    3333
    3434STOLEN_LAYOUT_SOURCES = \
     
    4040        main.c \
    4141        conv.c \
    42         hidreq.c \
    4342        kbddev.c \
    4443        kbdrepeat.c \
    45         hiddev.c \
    4644        $(STOLEN_LAYOUT_SOURCES)
    4745
  • uspace/drv/usbkbd/conv.h

    r889e8e3 r291b8bc  
    3434 */
    3535
    36 #ifndef USBHID_CONV_H_
    37 #define USBHID_CONV_H_
     36#ifndef USB_KBD_CONV_H_
     37#define USB_KBD_CONV_H_
    3838
    3939unsigned int usbhid_parse_scancode(int scancode);
    4040
    41 #endif /* USBHID_CONV_H_ */
     41#endif /* USB_KBD_CONV_H_ */
    4242
    4343/**
  • uspace/drv/usbkbd/kbddev.c

    r889e8e3 r291b8bc  
    4646
    4747#include <usb/usb.h>
     48#include <usb/dp.h>
     49#include <usb/request.h>
    4850#include <usb/classes/hid.h>
    4951#include <usb/pipes.h>
     
    5254#include <usb/classes/classes.h>
    5355#include <usb/classes/hidut.h>
     56#include <usb/classes/hidreq.h>
     57#include <usb/classes/hidreport.h>
     58
     59#include <usb/devdrv.h>
    5460
    5561#include "kbddev.h"
    56 #include "hiddev.h"
    57 #include "hidreq.h"
     62
    5863#include "layout.h"
    5964#include "conv.h"
     
    8590static const unsigned int DEFAULT_REPEAT_DELAY = 50 * 1000;
    8691
     92/*----------------------------------------------------------------------------*/
     93
    8794/** Keyboard polling endpoint description for boot protocol class. */
    88 static usb_endpoint_description_t poll_endpoint_description = {
     95static usb_endpoint_description_t boot_poll_endpoint_description = {
    8996        .transfer_type = USB_TRANSFER_INTERRUPT,
    9097        .direction = USB_DIRECTION_IN,
     
    95102};
    96103
    97 typedef enum usbhid_kbd_flags {
    98         USBHID_KBD_STATUS_UNINITIALIZED = 0,
    99         USBHID_KBD_STATUS_INITIALIZED = 1,
    100         USBHID_KBD_STATUS_TO_DESTROY = -1
    101 } usbhid_kbd_flags;
     104/* Array of endpoints expected on the device, NULL terminated. */
     105usb_endpoint_description_t
     106    *usb_kbd_endpoints[USB_KBD_POLL_EP_COUNT + 1] = {
     107        &boot_poll_endpoint_description,
     108        NULL
     109};
     110
     111/*----------------------------------------------------------------------------*/
     112
     113enum {
     114        BOOT_REPORT_DESCRIPTOR_SIZE = 63
     115};
     116
     117static const uint8_t BOOT_REPORT_DESCRIPTOR[BOOT_REPORT_DESCRIPTOR_SIZE] = {
     118        0x05, 0x01,  // Usage Page (Generic Desktop),
     119        0x09, 0x06,  // Usage (Keyboard),
     120        0xA1, 0x01,  // Collection (Application),
     121        0x75, 0x01,  //   Report Size (1),
     122        0x95, 0x08,  //   Report Count (8),       
     123        0x05, 0x07,  //   Usage Page (Key Codes);
     124        0x19, 0xE0,  //   Usage Minimum (224),
     125        0x29, 0xE7,  //   Usage Maximum (231),
     126        0x15, 0x00,  //   Logical Minimum (0),
     127        0x25, 0x01,  //   Logical Maximum (1),
     128        0x81, 0x02,  //   Input (Data, Variable, Absolute),   ; Modifier byte
     129        0x95, 0x01,  //   Report Count (1),
     130        0x75, 0x08,  //   Report Size (8),
     131        0x81, 0x01,  //   Input (Constant),                   ; Reserved byte
     132        0x95, 0x05,  //   Report Count (5),
     133        0x75, 0x01,  //   Report Size (1),
     134        0x05, 0x08,  //   Usage Page (Page# for LEDs),
     135        0x19, 0x01,  //   Usage Minimum (1),
     136        0x29, 0x05,  //   Usage Maxmimum (5),
     137        0x91, 0x02,  //   Output (Data, Variable, Absolute),  ; LED report
     138        0x95, 0x01,  //   Report Count (1),
     139        0x75, 0x03,  //   Report Size (3),
     140        0x91, 0x01,  //   Output (Constant),              ; LED report padding
     141        0x95, 0x06,  //   Report Count (6),
     142        0x75, 0x08,  //   Report Size (8),
     143        0x15, 0x00,  //   Logical Minimum (0),
     144        0x25, 0xff,  //   Logical Maximum (255),
     145        0x05, 0x07,  //   Usage Page (Key Codes),
     146        0x19, 0x00,  //   Usage Minimum (0),
     147        0x29, 0xff,  //   Usage Maximum (255),
     148        0x81, 0x00,  //   Input (Data, Array),            ; Key arrays (6 bytes)
     149        0xC0           // End Collection
     150
     151};
     152
     153/*----------------------------------------------------------------------------*/
     154
     155typedef enum usb_kbd_flags {
     156        USB_KBD_STATUS_UNINITIALIZED = 0,
     157        USB_KBD_STATUS_INITIALIZED = 1,
     158        USB_KBD_STATUS_TO_DESTROY = -1
     159} usb_kbd_flags;
    102160
    103161/*----------------------------------------------------------------------------*/
     
    132190
    133191typedef enum usbhid_lock_code {
    134         USBHID_LOCK_NUM = 0x53,
    135         USBHID_LOCK_CAPS = 0x39,
    136         USBHID_LOCK_SCROLL = 0x47,
    137         USBHID_LOCK_COUNT = 3
     192        USB_KBD_LOCK_NUM = 0x53,
     193        USB_KBD_LOCK_CAPS = 0x39,
     194        USB_KBD_LOCK_SCROLL = 0x47,
     195        USB_KBD_LOCK_COUNT = 3
    138196} usbhid_lock_code;
    139197
    140 static const usbhid_lock_code usbhid_lock_codes[USBHID_LOCK_COUNT] = {
    141         USBHID_LOCK_NUM,
    142         USBHID_LOCK_CAPS,
    143         USBHID_LOCK_SCROLL
     198static const usbhid_lock_code usbhid_lock_codes[USB_KBD_LOCK_COUNT] = {
     199        USB_KBD_LOCK_NUM,
     200        USB_KBD_LOCK_CAPS,
     201        USB_KBD_LOCK_SCROLL
    144202};
    145203
     
    149207
    150208static void default_connection_handler(ddf_fun_t *, ipc_callid_t, ipc_call_t *);
    151 static ddf_dev_ops_t keyboard_ops = {
     209ddf_dev_ops_t keyboard_ops = {
    152210        .default_handler = default_connection_handler
    153211};
     
    169227        sysarg_t method = IPC_GET_IMETHOD(*icall);
    170228       
    171         usbhid_kbd_t *kbd_dev = (usbhid_kbd_t *)fun->driver_data;
     229        usb_kbd_t *kbd_dev = (usb_kbd_t *)fun->driver_data;
    172230        assert(kbd_dev != NULL);
    173231
     
    203261 * @param kbd_dev Keyboard device structure.
    204262 */
    205 static void usbhid_kbd_set_led(usbhid_kbd_t *kbd_dev)
     263static void usb_kbd_set_led(usb_kbd_t *kbd_dev)
    206264{
    207265        uint8_t buffer[BOOTP_BUFFER_OUT_SIZE];
     
    237295            usb_debug_str_buffer(buffer, BOOTP_BUFFER_OUT_SIZE, 0));
    238296       
    239         assert(kbd_dev->hid_dev != NULL);
    240         assert(kbd_dev->hid_dev->initialized == USBHID_KBD_STATUS_INITIALIZED);
    241         usbhid_req_set_report(kbd_dev->hid_dev, USB_HID_REPORT_TYPE_OUTPUT,
     297        assert(kbd_dev->usb_dev != NULL);
     298       
     299        usbhid_req_set_report(&kbd_dev->usb_dev->ctrl_pipe,
     300            kbd_dev->usb_dev->interface_no, USB_HID_REPORT_TYPE_OUTPUT,
    242301            buffer, BOOTP_BUFFER_OUT_SIZE);
    243302}
     
    260319 * @param key Key code of the key according to HID Usage Tables.
    261320 */
    262 void usbhid_kbd_push_ev(usbhid_kbd_t *kbd_dev, int type, unsigned int key)
     321void usb_kbd_push_ev(usb_kbd_t *kbd_dev, int type, unsigned int key)
    263322{
    264323        console_event_t ev;
     
    310369                        /* Update keyboard lock indicator lights. */
    311370                        if (kbd_dev->lock_keys != locks_old) {
    312                                 usbhid_kbd_set_led(kbd_dev);
     371                                usb_kbd_set_led(kbd_dev);
    313372                        }
    314373                } else {
     
    358417
    359418/*----------------------------------------------------------------------------*/
    360 /**
    361  * Checks if modifiers were pressed or released and generates key events.
    362  *
    363  * @param kbd_dev Keyboard device structure.
    364  * @param modifiers Bitmap of modifiers.
    365  *
    366  * @sa usbhid_kbd_push_ev()
    367  */
    368 //static void usbhid_kbd_check_modifier_changes(usbhid_kbd_t *kbd_dev,
    369 //    const uint8_t *key_codes, size_t count)
    370 //{
    371 //      /*
    372 //       * TODO: why the USB keyboard has NUM_, SCROLL_ and CAPS_LOCK
    373 //       *       both as modifiers and as keyUSB_HID_LOCK_COUNTs with their own scancodes???
    374 //       *
    375 //       * modifiers should be sent as normal keys to usbhid_parse_scancode()!!
    376 //       * so maybe it would be better if I received it from report parser in
    377 //       * that way
    378 //       */
    379        
    380 //      int i;
    381 //      for (i = 0; i < count; ++i) {
    382 //              if ((modifiers & usb_hid_modifiers_consts[i]) &&
    383 //                  !(kbd_dev->modifiers & usb_hid_modifiers_consts[i])) {
    384 //                      // modifier pressed
    385 //                      if (usbhid_modifiers_keycodes[i] != 0) {
    386 //                              usbhid_kbd_push_ev(kbd_dev, KEY_PRESS,
    387 //                                  usbhid_modifiers_keycodes[i]);
    388 //                      }
    389 //              } else if (!(modifiers & usb_hid_modifiers_consts[i]) &&
    390 //                  (kbd_dev->modifiers & usb_hid_modifiers_consts[i])) {
    391 //                      // modifier released
    392 //                      if (usbhid_modifiers_keycodes[i] != 0) {
    393 //                              usbhid_kbd_push_ev(kbd_dev, KEY_RELEASE,
    394 //                                  usbhid_modifiers_keycodes[i]);
    395 //                      }
    396 //              }       // no change
    397 //      }
    398        
    399 //      kbd_dev->modifiers = modifiers;
    400 //}
    401 
    402 /*----------------------------------------------------------------------------*/
    403 
    404 static inline int usbhid_kbd_is_lock(unsigned int key_code)
     419
     420static inline int usb_kbd_is_lock(unsigned int key_code)
    405421{
    406422        return (key_code == KC_NUM_LOCK
     
    414430 *
    415431 * An event is created only when key is pressed or released. Besides handling
    416  * the events (usbhid_kbd_push_ev()), the auto-repeat fibril is notified about
    417  * key presses and releases (see usbhid_kbd_repeat_start() and
    418  * usbhid_kbd_repeat_stop()).
     432 * the events (usb_kbd_push_ev()), the auto-repeat fibril is notified about
     433 * key presses and releases (see usb_kbd_repeat_start() and
     434 * usb_kbd_repeat_stop()).
    419435 *
    420436 * @param kbd_dev Keyboard device structure.
     
    423439 * @param count Number of key codes in report (size of the report).
    424440 *
    425  * @sa usbhid_kbd_push_ev(), usbhid_kbd_repeat_start(), usbhid_kbd_repeat_stop()
    426  */
    427 static void usbhid_kbd_check_key_changes(usbhid_kbd_t *kbd_dev,
     441 * @sa usb_kbd_push_ev(), usb_kbd_repeat_start(), usb_kbd_repeat_stop()
     442 */
     443static void usb_kbd_check_key_changes(usb_kbd_t *kbd_dev,
    428444    const uint8_t *key_codes, size_t count)
    429445{
     
    434450         * First of all, check if the kbd have reported phantom state.
    435451         *
    436          * TODO: this must be changed as we don't know which keys are modifiers
     452         * this must be changed as we don't know which keys are modifiers
    437453         *       and which are regular keys.
    438454         */
     
    466482                        // not found, i.e. the key was released
    467483                        key = usbhid_parse_scancode(kbd_dev->keys[j]);
    468                         if (!usbhid_kbd_is_lock(key)) {
    469                                 usbhid_kbd_repeat_stop(kbd_dev, key);
     484                        if (!usb_kbd_is_lock(key)) {
     485                                usb_kbd_repeat_stop(kbd_dev, key);
    470486                        }
    471                         usbhid_kbd_push_ev(kbd_dev, KEY_RELEASE, key);
     487                        usb_kbd_push_ev(kbd_dev, KEY_RELEASE, key);
    472488                        usb_log_debug2("Key released: %d\n", key);
    473489                } else {
     
    491507                        usb_log_debug2("Key pressed: %d (keycode: %d)\n", key,
    492508                            key_codes[i]);
    493                         usbhid_kbd_push_ev(kbd_dev, KEY_PRESS, key);
    494                         if (!usbhid_kbd_is_lock(key)) {
    495                                 usbhid_kbd_repeat_start(kbd_dev, key);
     509                        usb_kbd_push_ev(kbd_dev, KEY_PRESS, key);
     510                        if (!usb_kbd_is_lock(key)) {
     511                                usb_kbd_repeat_start(kbd_dev, key);
    496512                        }
    497513                } else {
     
    523539 *            structure representing the keyboard.
    524540 *
    525  * @sa usbhid_kbd_check_key_changes(), usbhid_kbd_check_modifier_changes()
    526  */
    527 static void usbhid_kbd_process_keycodes(const uint8_t *key_codes, size_t count,
     541 * @sa usb_kbd_check_key_changes(), usb_kbd_check_modifier_changes()
     542 */
     543static void usb_kbd_process_keycodes(const uint8_t *key_codes, size_t count,
    528544    uint8_t modifiers, void *arg)
    529545{
     
    534550        }
    535551       
    536         usbhid_kbd_t *kbd_dev = (usbhid_kbd_t *)arg;
     552        usb_kbd_t *kbd_dev = (usb_kbd_t *)arg;
    537553        assert(kbd_dev != NULL);
    538554
     
    546562        }
    547563       
    548         ///usbhid_kbd_check_modifier_changes(kbd_dev, key_codes, count);
    549         usbhid_kbd_check_key_changes(kbd_dev, key_codes, count);
     564        ///usb_kbd_check_modifier_changes(kbd_dev, key_codes, count);
     565        usb_kbd_check_key_changes(kbd_dev, key_codes, count);
    550566}
    551567
     
    558574 * This function uses the HID report parser to translate the data received from
    559575 * the device into generic USB HID key codes and into generic modifiers bitmap.
    560  * The parser then calls the given callback (usbhid_kbd_process_keycodes()).
     576 * The parser then calls the given callback (usb_kbd_process_keycodes()).
    561577 *
    562578 * @note Currently, only the boot protocol is supported.
     
    566582 * @param actual_size Size of the data from keyboard (report size) in bytes.
    567583 *
    568  * @sa usbhid_kbd_process_keycodes(), usb_hid_boot_keyboard_input_report().
    569  */
    570 static void usbhid_kbd_process_data(usbhid_kbd_t *kbd_dev,
     584 * @sa usb_kbd_process_keycodes(), usb_hid_boot_keyboard_input_report(),
     585 *     usb_hid_parse_report().
     586 */
     587static void usb_kbd_process_data(usb_kbd_t *kbd_dev,
    571588                                    uint8_t *buffer, size_t actual_size)
    572589{
    573         assert(kbd_dev->initialized == USBHID_KBD_STATUS_INITIALIZED);
    574         assert(kbd_dev->hid_dev->parser != NULL);
     590        assert(kbd_dev->initialized == USB_KBD_STATUS_INITIALIZED);
     591        assert(kbd_dev->parser != NULL);
    575592       
    576593        usb_hid_report_in_callbacks_t *callbacks =
     
    578595                sizeof(usb_hid_report_in_callbacks_t));
    579596       
    580         callbacks->keyboard = usbhid_kbd_process_keycodes;
     597        callbacks->keyboard = usb_kbd_process_keycodes;
    581598
    582599        usb_log_debug("Calling usb_hid_parse_report() with "
     
    585602//      int rc = usb_hid_boot_keyboard_input_report(buffer, actual_size,
    586603//          callbacks, kbd_dev);
    587         int rc = usb_hid_parse_report(kbd_dev->hid_dev->parser, buffer,
    588             actual_size, callbacks, kbd_dev);
     604        usb_hid_report_path_t *path = usb_hid_report_path();
     605        usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_KEYBOARD, 0);
     606       
     607        int rc = usb_hid_parse_report(kbd_dev->parser, buffer,
     608            actual_size, path, USB_HID_PATH_COMPARE_STRICT, callbacks, kbd_dev);
     609
     610        usb_hid_report_path_free (path);
    589611       
    590612        if (rc != EOK) {
     
    597619/* HID/KBD structure manipulation                                             */
    598620/*----------------------------------------------------------------------------*/
     621
     622static void usb_kbd_mark_unusable(usb_kbd_t *kbd_dev)
     623{
     624        kbd_dev->initialized = USB_KBD_STATUS_TO_DESTROY;
     625}
     626
     627
     628/*----------------------------------------------------------------------------*/
     629/* API functions                                                              */
     630/*----------------------------------------------------------------------------*/
    599631/**
    600632 * Creates a new USB/HID keyboard structure.
    601633 *
    602634 * The structure returned by this function is not initialized. Use
    603  * usbhid_kbd_init() to initialize it prior to polling.
     635 * usb_kbd_init() to initialize it prior to polling.
    604636 *
    605637 * @return New uninitialized structure for representing a USB/HID keyboard or
    606638 *         NULL if not successful (memory error).
    607639 */
    608 static usbhid_kbd_t *usbhid_kbd_new(void)
    609 {
    610         usbhid_kbd_t *kbd_dev =
    611             (usbhid_kbd_t *)malloc(sizeof(usbhid_kbd_t));
     640usb_kbd_t *usb_kbd_new(void)
     641{
     642        usb_kbd_t *kbd_dev =
     643            (usb_kbd_t *)malloc(sizeof(usb_kbd_t));
    612644
    613645        if (kbd_dev == NULL) {
     
    616648        }
    617649       
    618         memset(kbd_dev, 0, sizeof(usbhid_kbd_t));
    619        
    620         kbd_dev->hid_dev = usbhid_dev_new();
    621         if (kbd_dev->hid_dev == NULL) {
    622                 usb_log_fatal("Could not create HID device structure.\n");
     650        memset(kbd_dev, 0, sizeof(usb_kbd_t));
     651       
     652        kbd_dev->parser = (usb_hid_report_parser_t *)(malloc(sizeof(
     653            usb_hid_report_parser_t)));
     654        if (kbd_dev->parser == NULL) {
     655                usb_log_fatal("No memory!\n");
     656                free(kbd_dev);
    623657                return NULL;
    624658        }
    625659       
    626660        kbd_dev->console_phone = -1;
    627         kbd_dev->initialized = USBHID_KBD_STATUS_UNINITIALIZED;
     661        kbd_dev->initialized = USB_KBD_STATUS_UNINITIALIZED;
    628662       
    629663        return kbd_dev;
    630 }
    631 
    632 /*----------------------------------------------------------------------------*/
    633 
    634 static void usbhid_kbd_mark_unusable(usbhid_kbd_t *kbd_dev)
    635 {
    636         kbd_dev->initialized = USBHID_KBD_STATUS_TO_DESTROY;
    637664}
    638665
     
    658685 * @return Other value inherited from function usbhid_dev_init().
    659686 */
    660 static int usbhid_kbd_init(usbhid_kbd_t *kbd_dev, ddf_dev_t *dev)
     687int usb_kbd_init(usb_kbd_t *kbd_dev, usb_device_t *dev)
    661688{
    662689        int rc;
     
    671698       
    672699        if (dev == NULL) {
    673                 usb_log_error("Failed to init keyboard structure: no device"
     700                usb_log_error("Failed to init keyboard structure: no USB device"
    674701                    " given.\n");
    675702                return EINVAL;
    676703        }
    677704       
    678         if (kbd_dev->initialized == USBHID_KBD_STATUS_INITIALIZED) {
     705        if (kbd_dev->initialized == USB_KBD_STATUS_INITIALIZED) {
    679706                usb_log_warning("Keyboard structure already initialized.\n");
    680707                return EINVAL;
    681708        }
    682709       
    683         rc = usbhid_dev_init(kbd_dev->hid_dev, dev, &poll_endpoint_description);
    684        
     710        /* TODO: does not work! */
     711        if (!dev->pipes[USB_KBD_POLL_EP_NO].present) {
     712                usb_log_warning("Required endpoint not found - probably not "
     713                    "a supported device.\n");
     714                return ENOTSUP;
     715        }
     716       
     717        /* The USB device should already be initialized, save it in structure */
     718        kbd_dev->usb_dev = dev;
     719       
     720        /* Initialize the report parser. */
     721        rc = usb_hid_parser_init(kbd_dev->parser);
    685722        if (rc != EOK) {
    686                 usb_log_error("Failed to initialize HID device structure: %s\n",
    687                    str_error(rc));
     723                usb_log_error("Failed to initialize report parser.\n");
    688724                return rc;
    689725        }
    690726       
    691         assert(kbd_dev->hid_dev->initialized == USBHID_KBD_STATUS_INITIALIZED);
    692        
    693         // save the size of the report (boot protocol report by default)
    694 //      kbd_dev->key_count = BOOTP_REPORT_SIZE;
    695        
    696         usb_hid_report_path_t path;
    697         path.usage_page = USB_HIDUT_PAGE_KEYBOARD;
     727        /* Get the report descriptor and parse it. */
     728        rc = usb_hid_process_report_descriptor(kbd_dev->usb_dev,
     729            kbd_dev->parser);
     730        if (rc != EOK) {
     731                usb_log_warning("Could not process report descriptor, "
     732                    "falling back to boot protocol.\n");
     733                rc = usb_hid_parse_report_descriptor(kbd_dev->parser,
     734                    BOOT_REPORT_DESCRIPTOR, BOOT_REPORT_DESCRIPTOR_SIZE);
     735                if (rc != EOK) {
     736                        usb_log_error("Failed to parse boot report descriptor:"
     737                            " %s.\n", str_error(rc));
     738                        return rc;
     739                }
     740               
     741                rc = usbhid_req_set_protocol(&kbd_dev->usb_dev->ctrl_pipe,
     742                    kbd_dev->usb_dev->interface_no, USB_HID_PROTOCOL_BOOT);
     743               
     744                if (rc != EOK) {
     745                        usb_log_warning("Failed to set boot protocol to the "
     746                            "device: %s\n", str_error(rc));
     747                        return rc;
     748                }
     749        }
     750       
     751        /*
     752         * TODO: make more general
     753         */
     754        usb_hid_report_path_t *path = usb_hid_report_path();
     755        usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_KEYBOARD, 0);
    698756        kbd_dev->key_count = usb_hid_report_input_length(
    699             kbd_dev->hid_dev->parser, &path);
     757            kbd_dev->parser, path, USB_HID_PATH_COMPARE_STRICT);
     758        usb_hid_report_path_free (path);
    700759       
    701760        usb_log_debug("Size of the input report: %zu\n", kbd_dev->key_count);
     
    729788       
    730789        /*
    731          * Set boot protocol.
    732790         * Set LEDs according to initial setup.
    733791         * Set Idle rate
    734792         */
    735         assert(kbd_dev->hid_dev != NULL);
    736         assert(kbd_dev->hid_dev->initialized);
    737         //usbhid_req_set_protocol(kbd_dev->hid_dev, USB_HID_PROTOCOL_BOOT);
    738        
    739         usbhid_kbd_set_led(kbd_dev);
    740        
    741         usbhid_req_set_idle(kbd_dev->hid_dev, IDLE_RATE);
    742        
    743         kbd_dev->initialized = USBHID_KBD_STATUS_INITIALIZED;
     793        usb_kbd_set_led(kbd_dev);
     794       
     795        usbhid_req_set_idle(&kbd_dev->usb_dev->ctrl_pipe,
     796            kbd_dev->usb_dev->interface_no, IDLE_RATE);
     797       
     798        kbd_dev->initialized = USB_KBD_STATUS_INITIALIZED;
    744799        usb_log_debug("HID/KBD device structure initialized.\n");
    745800       
     
    748803
    749804/*----------------------------------------------------------------------------*/
    750 /* HID/KBD polling                                                            */
    751 /*----------------------------------------------------------------------------*/
    752 /**
    753  * Main keyboard polling function.
    754  *
    755  * This function uses the Interrupt In pipe of the keyboard to poll for events.
    756  * The keyboard is initialized in a way that it reports only when a key is
    757  * pressed or released, so there is no actual need for any sleeping between
    758  * polls (see usbhid_kbd_try_add_device() or usbhid_kbd_init()).
    759  *
    760  * @param kbd_dev Initialized keyboard structure representing the device to
    761  *                poll.
    762  *
    763  * @sa usbhid_kbd_process_data()
    764  */
    765 static void usbhid_kbd_poll(usbhid_kbd_t *kbd_dev)
    766 {
    767         int rc, sess_rc;
    768         uint8_t buffer[BOOTP_BUFFER_SIZE];
    769         size_t actual_size;
    770        
    771         usb_log_debug("Polling keyboard...\n");
    772        
    773         if (!kbd_dev->initialized) {
    774                 usb_log_error("HID/KBD device not initialized!\n");
    775                 return;
    776         }
    777        
    778         assert(kbd_dev->hid_dev != NULL);
    779         assert(kbd_dev->hid_dev->initialized);
    780 
    781         while (true) {
    782                 sess_rc = usb_pipe_start_session(
    783                     &kbd_dev->hid_dev->poll_pipe);
    784                 if (sess_rc != EOK) {
    785                         usb_log_warning("Failed to start a session: %s.\n",
    786                             str_error(sess_rc));
    787                         break;
    788                 }
    789 
    790                 rc = usb_pipe_read(&kbd_dev->hid_dev->poll_pipe,
    791                     buffer, BOOTP_BUFFER_SIZE, &actual_size);
    792                
    793                 sess_rc = usb_pipe_end_session(
    794                     &kbd_dev->hid_dev->poll_pipe);
    795 
    796                 if (rc != EOK) {
    797                         usb_log_warning("Error polling the keyboard: %s.\n",
    798                             str_error(rc));
    799                         break;
    800                 }
    801 
    802                 if (sess_rc != EOK) {
    803                         usb_log_warning("Error closing session: %s.\n",
    804                             str_error(sess_rc));
    805                         break;
    806                 }
    807 
    808                 /*
    809                  * If the keyboard answered with NAK, it returned no data.
    810                  * This implies that no change happened since last query.
    811                  */
    812                 if (actual_size == 0) {
    813                         usb_log_debug("Keyboard returned NAK\n");
    814                         continue;
    815                 }
    816 
    817                 /*
    818                  * TODO: Process pressed keys.
    819                  */
    820                 usb_log_debug("Calling usbhid_kbd_process_data()\n");
    821                 usbhid_kbd_process_data(kbd_dev, buffer, actual_size);
    822                
    823                 // disabled for now, no reason to sleep
    824                 //async_usleep(kbd_dev->hid_dev->poll_interval);
    825         }
    826 }
    827 
    828 /*----------------------------------------------------------------------------*/
    829 /**
    830  * Function executed by the main driver fibril.
    831  *
    832  * Just starts polling the keyboard for events.
    833  *
    834  * @param arg Initialized keyboard device structure (of type usbhid_kbd_t)
    835  *            representing the device.
    836  *
    837  * @retval EOK if the fibril finished polling the device.
    838  * @retval EINVAL if no device was given in the argument.
    839  *
    840  * @sa usbhid_kbd_poll()
    841  *
    842  * @todo Change return value - only case when the fibril finishes is in case
    843  *       of some error, so the error should probably be propagated from function
    844  *       usbhid_kbd_poll() to here and up.
    845  */
    846 static int usbhid_kbd_fibril(void *arg)
    847 {
    848         if (arg == NULL) {
    849                 usb_log_error("No device!\n");
    850                 return EINVAL;
    851         }
    852        
    853         usbhid_kbd_t *kbd_dev = (usbhid_kbd_t *)arg;
    854 
    855         usbhid_kbd_poll(kbd_dev);
    856        
    857         // as there is another fibril using this device, so we must leave the
    858         // structure to it, but mark it for destroying.
    859         usbhid_kbd_mark_unusable(kbd_dev);
    860         // at the end, properly destroy the KBD structure
    861 //      usbhid_kbd_free(&kbd_dev);
    862 //      assert(kbd_dev == NULL);
    863 
    864         return EOK;
    865 }
    866 
    867 /*----------------------------------------------------------------------------*/
    868 /* API functions                                                              */
    869 /*----------------------------------------------------------------------------*/
    870 /**
    871  * Function for adding a new device of type USB/HID/keyboard.
    872  *
    873  * This functions initializes required structures from the device's descriptors
    874  * and starts new fibril for polling the keyboard for events and another one for
    875  * handling auto-repeat of keys.
    876  *
    877  * During initialization, the keyboard is switched into boot protocol, the idle
    878  * rate is set to 0 (infinity), resulting in the keyboard only reporting event
    879  * when a key is pressed or released. Finally, the LED lights are turned on
    880  * according to the default setup of lock keys.
    881  *
    882  * @note By default, the keyboards is initialized with Num Lock turned on and
    883  *       other locks turned off.
    884  * @note Currently supports only boot-protocol keyboards.
    885  *
    886  * @param dev Device to add.
    887  *
    888  * @retval EOK if successful.
    889  * @retval ENOMEM if there
    890  * @return Other error code inherited from one of functions usbhid_kbd_init(),
    891  *         ddf_fun_bind() and ddf_fun_add_to_class().
    892  *
    893  * @sa usbhid_kbd_fibril(), usbhid_kbd_repeat_fibril()
    894  */
    895 int usbhid_kbd_try_add_device(ddf_dev_t *dev)
    896 {
    897         /*
    898          * Create default function.
    899          */
    900         ddf_fun_t *kbd_fun = ddf_fun_create(dev, fun_exposed, "keyboard");
    901         if (kbd_fun == NULL) {
    902                 usb_log_error("Could not create DDF function node.\n");
    903                 return ENOMEM;
    904         }
    905        
    906         /*
    907          * Initialize device (get and process descriptors, get address, etc.)
    908          */
    909         usb_log_debug("Initializing USB/HID KBD device...\n");
    910        
    911         usbhid_kbd_t *kbd_dev = usbhid_kbd_new();
    912         if (kbd_dev == NULL) {
    913                 usb_log_error("Error while creating USB/HID KBD device "
    914                     "structure.\n");
    915                 ddf_fun_destroy(kbd_fun);
    916                 return ENOMEM;  // TODO: some other code??
    917         }
    918        
    919         int rc = usbhid_kbd_init(kbd_dev, dev);
    920        
    921         if (rc != EOK) {
    922                 usb_log_error("Failed to initialize USB/HID KBD device.\n");
    923                 ddf_fun_destroy(kbd_fun);
    924                 usbhid_kbd_free(&kbd_dev);
    925                 return rc;
    926         }       
    927        
    928         usb_log_debug("USB/HID KBD device structure initialized.\n");
    929        
    930         /*
    931          * Store the initialized keyboard device and keyboard ops
    932          * to the DDF function.
    933          */
    934         kbd_fun->driver_data = kbd_dev;
    935         kbd_fun->ops = &keyboard_ops;
    936 
    937         rc = ddf_fun_bind(kbd_fun);
    938         if (rc != EOK) {
    939                 usb_log_error("Could not bind DDF function: %s.\n",
    940                     str_error(rc));
    941                 // TODO: Can / should I destroy the DDF function?
    942                 ddf_fun_destroy(kbd_fun);
    943                 usbhid_kbd_free(&kbd_dev);
    944                 return rc;
    945         }
    946        
    947         rc = ddf_fun_add_to_class(kbd_fun, "keyboard");
    948         if (rc != EOK) {
    949                 usb_log_error(
    950                     "Could not add DDF function to class 'keyboard': %s.\n",
    951                     str_error(rc));
    952                 // TODO: Can / should I destroy the DDF function?
    953                 ddf_fun_destroy(kbd_fun);
    954                 usbhid_kbd_free(&kbd_dev);
    955                 return rc;
    956         }
    957        
    958         /*
    959          * Create new fibril for handling this keyboard
    960          */
    961         fid_t fid = fibril_create(usbhid_kbd_fibril, kbd_dev);
    962         if (fid == 0) {
    963                 usb_log_error("Failed to start fibril for `%s' device.\n",
    964                     dev->name);
    965                 return ENOMEM;
    966         }
    967         fibril_add_ready(fid);
    968        
    969         /*
    970          * Create new fibril for auto-repeat
    971          */
    972         fid = fibril_create(usbhid_kbd_repeat_fibril, kbd_dev);
    973         if (fid == 0) {
    974                 usb_log_error("Failed to start fibril for KBD auto-repeat");
    975                 return ENOMEM;
    976         }
    977         fibril_add_ready(fid);
    978 
    979         (void)keyboard_ops;
    980 
    981         /*
    982          * Hurrah, device is initialized.
    983          */
    984         return EOK;
    985 }
    986 
    987 /*----------------------------------------------------------------------------*/
    988 
    989 int usbhid_kbd_is_usable(const usbhid_kbd_t *kbd_dev)
    990 {
    991         return (kbd_dev->initialized == USBHID_KBD_STATUS_INITIALIZED);
     805
     806bool usb_kbd_polling_callback(usb_device_t *dev, uint8_t *buffer,
     807     size_t buffer_size, void *arg)
     808{
     809        if (dev == NULL || buffer == NULL || arg == NULL) {
     810                // do not continue polling (???)
     811                return false;
     812        }
     813       
     814        usb_kbd_t *kbd_dev = (usb_kbd_t *)arg;
     815       
     816        // TODO: add return value from this function
     817        usb_kbd_process_data(kbd_dev, buffer, buffer_size);
     818       
     819        return true;
     820}
     821
     822/*----------------------------------------------------------------------------*/
     823
     824void usb_kbd_polling_ended_callback(usb_device_t *dev, bool reason,
     825     void *arg)
     826{
     827        if (dev == NULL || arg == NULL) {
     828                return;
     829        }
     830       
     831        usb_kbd_t *kbd = (usb_kbd_t *)arg;
     832       
     833        usb_kbd_mark_unusable(kbd);
     834}
     835
     836/*----------------------------------------------------------------------------*/
     837
     838int usb_kbd_is_initialized(const usb_kbd_t *kbd_dev)
     839{
     840        return (kbd_dev->initialized == USB_KBD_STATUS_INITIALIZED);
     841}
     842
     843/*----------------------------------------------------------------------------*/
     844
     845int usb_kbd_is_ready_to_destroy(const usb_kbd_t *kbd_dev)
     846{
     847        return (kbd_dev->initialized == USB_KBD_STATUS_TO_DESTROY);
    992848}
    993849
     
    998854 * @param kbd_dev Pointer to the structure to be destroyed.
    999855 */
    1000 void usbhid_kbd_free(usbhid_kbd_t **kbd_dev)
     856void usb_kbd_free(usb_kbd_t **kbd_dev)
    1001857{
    1002858        if (kbd_dev == NULL || *kbd_dev == NULL) {
     
    1007863        async_hangup((*kbd_dev)->console_phone);
    1008864       
    1009         if ((*kbd_dev)->hid_dev != NULL) {
    1010                 usbhid_dev_free(&(*kbd_dev)->hid_dev);
    1011                 assert((*kbd_dev)->hid_dev == NULL);
    1012         }
     865//      if ((*kbd_dev)->hid_dev != NULL) {
     866//              usbhid_dev_free(&(*kbd_dev)->hid_dev);
     867//              assert((*kbd_dev)->hid_dev == NULL);
     868//      }
    1013869       
    1014870        if ((*kbd_dev)->repeat_mtx != NULL) {
     
    1017873                free((*kbd_dev)->repeat_mtx);
    1018874        }
     875       
     876        // destroy the parser
     877        if ((*kbd_dev)->parser != NULL) {
     878                usb_hid_free_report_parser((*kbd_dev)->parser);
     879        }
     880       
     881        /* TODO: what about the USB device structure?? */
    1019882
    1020883        free(*kbd_dev);
  • uspace/drv/usbkbd/kbddev.h

    r889e8e3 r291b8bc  
    3434 */
    3535
    36 #ifndef USBHID_KBDDEV_H_
    37 #define USBHID_KBDDEV_H_
     36#ifndef USB_KBDDEV_H_
     37#define USB_KBDDEV_H_
    3838
    3939#include <stdint.h>
     
    4545#include <ddf/driver.h>
    4646#include <usb/pipes.h>
     47#include <usb/devdrv.h>
    4748
    48 #include "hiddev.h"
     49#include "kbdrepeat.h"
    4950
    5051/*----------------------------------------------------------------------------*/
    51 /**
    52  * Structure for keeping information needed for auto-repeat of keys.
    53  */
    54 typedef struct {
    55         /** Last pressed key. */
    56         unsigned int key_new;
    57         /** Key to be repeated. */
    58         unsigned int key_repeated;
    59         /** Delay before first repeat in microseconds. */
    60         unsigned int delay_before;
    61         /** Delay between repeats in microseconds. */
    62         unsigned int delay_between;
    63 } usbhid_kbd_repeat_t;
    64 
    6552/**
    6653 * USB/HID keyboard device type.
     
    7562 *       being device-specific.
    7663 */
    77 typedef struct {
    78         /** Structure holding generic USB/HID device information. */
    79         usbhid_dev_t *hid_dev;
     64typedef struct usb_kbd_t {
     65        /** Structure holding generic USB device information. */
     66        //usbhid_dev_t *hid_dev;
     67        usb_device_t *usb_dev;
    8068       
    8169        /** Currently pressed keys (not translated to key codes). */
     
    9684       
    9785        /** Information for auto-repeat of keys. */
    98         usbhid_kbd_repeat_t repeat;
     86        usb_kbd_repeat_t repeat;
    9987       
    10088        /** Mutex for accessing the information about auto-repeat. */
    10189        fibril_mutex_t *repeat_mtx;
     90       
     91        /** Report descriptor. */
     92        uint8_t *report_desc;
     93
     94        /** Report descriptor size. */
     95        size_t report_desc_size;
     96
     97        /** HID Report parser. */
     98        usb_hid_report_parser_t *parser;
    10299       
    103100        /** State of the structure (for checking before use).
     
    108105         */
    109106        int initialized;
    110 } usbhid_kbd_t;
     107} usb_kbd_t;
    111108
    112109/*----------------------------------------------------------------------------*/
    113110
    114 int usbhid_kbd_try_add_device(ddf_dev_t *dev);
     111enum {
     112        USB_KBD_POLL_EP_NO = 0,
     113        USB_KBD_POLL_EP_COUNT = 1
     114};
    115115
    116 int usbhid_kbd_is_usable(const usbhid_kbd_t *kbd_dev);
     116usb_endpoint_description_t *usb_kbd_endpoints[USB_KBD_POLL_EP_COUNT + 1];
    117117
    118 void usbhid_kbd_free(usbhid_kbd_t **kbd_dev);
     118ddf_dev_ops_t keyboard_ops;
    119119
    120 void usbhid_kbd_push_ev(usbhid_kbd_t *kbd_dev, int type, unsigned int key);
     120/*----------------------------------------------------------------------------*/
    121121
    122 #endif /* USBHID_KBDDEV_H_ */
     122usb_kbd_t *usb_kbd_new(void);
     123
     124int usb_kbd_init(usb_kbd_t *kbd_dev, usb_device_t *dev);
     125
     126bool usb_kbd_polling_callback(usb_device_t *dev, uint8_t *buffer,
     127     size_t buffer_size, void *arg);
     128
     129void usb_kbd_polling_ended_callback(usb_device_t *dev, bool reason,
     130     void *arg);
     131
     132int usb_kbd_is_initialized(const usb_kbd_t *kbd_dev);
     133
     134int usb_kbd_is_ready_to_destroy(const usb_kbd_t *kbd_dev);
     135
     136void usb_kbd_free(usb_kbd_t **kbd_dev);
     137
     138void usb_kbd_push_ev(usb_kbd_t *kbd_dev, int type, unsigned int key);
     139
     140#endif /* USB_KBDDEV_H_ */
    123141
    124142/**
  • uspace/drv/usbkbd/kbdrepeat.c

    r889e8e3 r291b8bc  
    6262 *
    6363 * If the currently repeated key is not pressed any more (
    64  * usbhid_kbd_repeat_stop() was called), it stops repeating it and starts
     64 * usb_kbd_repeat_stop() was called), it stops repeating it and starts
    6565 * checking again.
    6666 *
     
    7070 * @param kbd Keyboard device structure.
    7171 */
    72 static void usbhid_kbd_repeat_loop(usbhid_kbd_t *kbd)
     72static void usb_kbd_repeat_loop(usb_kbd_t *kbd)
    7373{
    7474        unsigned int delay = 0;
     
    7878        while (true) {
    7979                // check if the kbd structure is usable
    80                 if (!usbhid_kbd_is_usable(kbd)) {
    81                         usbhid_kbd_free(&kbd);
    82                         assert(kbd == NULL);
     80                if (!usb_kbd_is_initialized(kbd)) {
     81                        if (usb_kbd_is_ready_to_destroy(kbd)) {
     82                                usb_kbd_free(&kbd);
     83                                assert(kbd == NULL);
     84                        }
    8385                        return;
    8486                }
     
    9092                                usb_log_debug2("Repeating key: %u.\n",
    9193                                    kbd->repeat.key_repeated);
    92                                 usbhid_kbd_push_ev(kbd, KEY_PRESS,
     94                                usb_kbd_push_ev(kbd, KEY_PRESS,
    9395                                    kbd->repeat.key_repeated);
    9496                                delay = kbd->repeat.delay_between;
     
    125127 * @retval EINVAL if no argument is supplied.
    126128 */
    127 int usbhid_kbd_repeat_fibril(void *arg)
     129int usb_kbd_repeat_fibril(void *arg)
    128130{
    129131        usb_log_debug("Autorepeat fibril spawned.\n");
     
    134136        }
    135137       
    136         usbhid_kbd_t *kbd = (usbhid_kbd_t *)arg;
     138        usb_kbd_t *kbd = (usb_kbd_t *)arg;
    137139       
    138         usbhid_kbd_repeat_loop(kbd);
     140        usb_kbd_repeat_loop(kbd);
    139141       
    140142        return EOK;
     
    152154 * @param key Key to start repeating.
    153155 */
    154 void usbhid_kbd_repeat_start(usbhid_kbd_t *kbd, unsigned int key)
     156void usb_kbd_repeat_start(usb_kbd_t *kbd, unsigned int key)
    155157{
    156158        fibril_mutex_lock(kbd->repeat_mtx);
     
    170172 * @param key Key to stop repeating.
    171173 */
    172 void usbhid_kbd_repeat_stop(usbhid_kbd_t *kbd, unsigned int key)
     174void usb_kbd_repeat_stop(usb_kbd_t *kbd, unsigned int key)
    173175{
    174176        fibril_mutex_lock(kbd->repeat_mtx);
  • uspace/drv/usbkbd/kbdrepeat.h

    r889e8e3 r291b8bc  
    11/*
    2  * Copyright (c) 2010 Vojtech Horky
    32 * Copyright (c) 2011 Lubos Slovak
    43 * All rights reserved.
     
    3130 * @{
    3231 */
    33 /**
    34  * @file
    35  * Main routines of USB HID driver.
     32/** @file
     33 * USB HID keyboard autorepeat facilities
    3634 */
    3735
    38 #include <ddf/driver.h>
    39 #include <usb/debug.h>
    40 #include <errno.h>
    41 #include <str_error.h>
     36#ifndef USB_KBDREPEAT_H_
     37#define USB_KBDREPEAT_H_
    4238
    43 #include "kbddev.h"
     39struct usb_kbd_t;
     40
     41/*----------------------------------------------------------------------------*/
     42/**
     43 * Structure for keeping information needed for auto-repeat of keys.
     44 */
     45typedef struct {
     46        /** Last pressed key. */
     47        unsigned int key_new;
     48        /** Key to be repeated. */
     49        unsigned int key_repeated;
     50        /** Delay before first repeat in microseconds. */
     51        unsigned int delay_before;
     52        /** Delay between repeats in microseconds. */
     53        unsigned int delay_between;
     54} usb_kbd_repeat_t;
    4455
    4556/*----------------------------------------------------------------------------*/
    4657
    47 #define NAME "usbhid"
     58int usb_kbd_repeat_fibril(void *arg);
    4859
    49 /*----------------------------------------------------------------------------*/
    50 /**
    51  * Callback for passing a new device to the driver.
    52  *
    53  * @note Currently, only boot-protocol keyboards are supported by this driver.
    54  *
    55  * @param dev Structure representing the new device.
    56  *
    57  * @retval EOK if successful.
    58  * @retval EREFUSED if the device is not supported.
    59  */
    60 static int usbhid_add_device(ddf_dev_t *dev)
    61 {
    62         usb_log_debug("usbhid_add_device()\n");
    63        
    64         int rc = usbhid_kbd_try_add_device(dev);
    65        
    66         if (rc != EOK) {
    67                 usb_log_warning("Device is not a supported keyboard.\n");
    68                 usb_log_error("Failed to add HID device: %s.\n",
    69                     str_error(rc));
    70                 return rc;
    71         }
    72        
    73         usb_log_info("Keyboard `%s' ready to use.\n", dev->name);
     60void usb_kbd_repeat_start(struct usb_kbd_t *kbd, unsigned int key);
    7461
    75         return EOK;
    76 }
     62void usb_kbd_repeat_stop(struct usb_kbd_t *kbd, unsigned int key);
    7763
    78 /*----------------------------------------------------------------------------*/
    79 
    80 static driver_ops_t kbd_driver_ops = {
    81         .add_device = usbhid_add_device,
    82 };
    83 
    84 /*----------------------------------------------------------------------------*/
    85 
    86 static driver_t kbd_driver = {
    87         .name = NAME,
    88         .driver_ops = &kbd_driver_ops
    89 };
    90 
    91 /*----------------------------------------------------------------------------*/
    92 
    93 int main(int argc, char *argv[])
    94 {
    95         printf(NAME ": HelenOS USB HID driver.\n");
    96 
    97         usb_log_enable(USB_LOG_LEVEL_DEFAULT, NAME);
    98 
    99         return ddf_driver_main(&kbd_driver);
    100 }
     64#endif /* USB_KBDREPEAT_H_ */
    10165
    10266/**
  • uspace/drv/usbkbd/layout.h

    r889e8e3 r291b8bc  
    3636 */
    3737
    38 #ifndef USBHID_LAYOUT_H_
    39 #define USBHID_LAYOUT_H_
     38#ifndef USB_KBD_LAYOUT_H_
     39#define USB_KBD_LAYOUT_H_
    4040
    4141#include <sys/types.h>
  • uspace/lib/c/generic/malloc.c

    r889e8e3 r291b8bc  
    240240        size_t asize = ALIGN_UP(size, PAGE_SIZE);
    241241       
    242         astart = as_area_create(astart, asize, AS_AREA_WRITE | AS_AREA_READ);
     242        astart = as_area_create(astart, asize, AS_AREA_WRITE | AS_AREA_READ | AS_AREA_CACHEABLE);
    243243        if (astart == (void *) -1)
    244244                return false;
  • uspace/lib/usb/Makefile

    r889e8e3 r291b8bc  
    5050        src/usb.c \
    5151        src/usbdevice.c \
     52        src/hidreq.c \
     53        src/hidreport.c \
    5254        src/host/device_keeper.c \
    5355        src/host/batch.c
  • uspace/lib/usb/include/usb/classes/hidparser.h

    r889e8e3 r291b8bc  
    7070 * Description of path of usage pages and usages in report descriptor
    7171 */
     72#define USB_HID_PATH_COMPARE_STRICT                             0
     73#define USB_HID_PATH_COMPARE_END                                1
     74#define USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY    4
     75
    7276typedef struct {
    7377        int32_t usage_page;
     78        int32_t usage;
     79
     80        link_t link;
     81} usb_hid_report_usage_path_t;
     82
     83typedef struct {
     84        int depth;     
     85        link_t link;
    7486} usb_hid_report_path_t;
    7587
     
    7991typedef struct {
    8092        int32_t id;
    81         int32_t usage_page;
    82         int32_t usage; 
    8393        int32_t usage_minimum;
    8494        int32_t usage_maximum;
     
    107117        uint8_t item_flags;
    108118
     119        usb_hid_report_path_t *usage_path;
    109120        link_t link;
    110121} usb_hid_report_item_t;
     
    117128        link_t feature;
    118129} usb_hid_report_parser_t;     
    119 
    120130
    121131
     
    194204int usb_hid_parse_report(const usb_hid_report_parser_t *parser, 
    195205    const uint8_t *data, size_t size,
     206    usb_hid_report_path_t *path, int flags,
    196207    const usb_hid_report_in_callbacks_t *callbacks, void *arg);
    197208
    198209int usb_hid_report_input_length(const usb_hid_report_parser_t *parser,
    199         const usb_hid_report_path_t *path);
     210        usb_hid_report_path_t *path, int flags);
    200211
    201212
     
    204215void usb_hid_descriptor_print(usb_hid_report_parser_t *parser);
    205216
     217/* usage path functions */
     218usb_hid_report_path_t *usb_hid_report_path(void);
     219void usb_hid_report_path_free(usb_hid_report_path_t *path);
     220int usb_hid_report_path_append_item(usb_hid_report_path_t *usage_path, int32_t usage_page, int32_t usage);
     221void usb_hid_report_remove_last_item(usb_hid_report_path_t *usage_path);
     222void usb_hid_report_null_last_item(usb_hid_report_path_t *usage_path);
     223void usb_hid_report_set_last_item(usb_hid_report_path_t *usage_path, int32_t tag, int32_t data);
     224int usb_hid_report_compare_usage_path(usb_hid_report_path_t *report_path, usb_hid_report_path_t *path, int flags);
     225int     usb_hid_report_path_clone(usb_hid_report_path_t *new_usage_path, usb_hid_report_path_t *usage_path);
     226
     227
     228// output
     229//      - funkce co vrati cesty poli v output reportu
     230//      - funkce co pro danou cestu nastavi data
     231//      - finalize
     232
    206233#endif
    207234/**
  • uspace/lib/usb/include/usb/classes/hidreq.h

    r889e8e3 r291b8bc  
    2727 */
    2828
    29 /** @addtogroup drvusbhid
     29/** @addtogroup libusb
    3030 * @{
    3131 */
     
    3434 */
    3535
    36 #ifndef USBHID_HIDREQ_H_
    37 #define USBHID_HIDREQ_H_
     36#ifndef USB_KBD_HIDREQ_H_
     37#define USB_KBD_HIDREQ_H_
    3838
    3939#include <stdint.h>
    4040
    4141#include <usb/classes/hid.h>
    42 
    43 #include "hiddev.h"
     42#include <usb/pipes.h>
    4443
    4544/*----------------------------------------------------------------------------*/
    4645
    47 int usbhid_req_set_report(usbhid_dev_t *hid_dev,
     46int usbhid_req_set_report(usb_pipe_t *ctrl_pipe, int iface_no,
    4847    usb_hid_report_type_t type, uint8_t *buffer, size_t buf_size);
    4948
    50 int usbhid_req_set_protocol(usbhid_dev_t *hid_dev, usb_hid_protocol_t protocol);
     49int usbhid_req_set_protocol(usb_pipe_t *ctrl_pipe, int iface_no,
     50    usb_hid_protocol_t protocol);
    5151
    52 int usbhid_req_set_idle(usbhid_dev_t *hid_dev, uint8_t duration);
     52int usbhid_req_set_idle(usb_pipe_t *ctrl_pipe, int iface_no, uint8_t duration);
    5353
    54 int usbhid_req_get_report(usbhid_dev_t *hid_dev, usb_hid_report_type_t type,
    55     uint8_t *buffer, size_t buf_size, size_t *actual_size);
     54int usbhid_req_get_report(usb_pipe_t *ctrl_pipe, int iface_no,
     55    usb_hid_report_type_t type, uint8_t *buffer, size_t buf_size,
     56    size_t *actual_size);
    5657
    57 int usbhid_req_get_protocol(usbhid_dev_t *hid_dev, usb_hid_protocol_t *protocol);
     58int usbhid_req_get_protocol(usb_pipe_t *ctrl_pipe, int iface_no,
     59    usb_hid_protocol_t *protocol);
    5860
    59 int usbhid_req_get_idle(usbhid_dev_t *hid_dev, uint8_t *duration);
     61int usbhid_req_get_idle(usb_pipe_t *ctrl_pipe, int iface_no, uint8_t *duration);
    6062
    6163/*----------------------------------------------------------------------------*/
    6264
    63 #endif /* USBHID_HIDREQ_H_ */
     65#endif /* USB_KBD_HIDREQ_H_ */
    6466
    6567/**
  • uspace/lib/usb/include/usb/host/device_keeper.h

    r889e8e3 r291b8bc  
    5151        usb_speed_t speed;
    5252        bool occupied;
     53        bool control_used;
    5354        uint16_t toggle_status[2];
    5455        devman_handle_t handle;
     
    6162        struct usb_device_info devices[USB_ADDRESS_COUNT];
    6263        fibril_mutex_t guard;
    63         fibril_condvar_t default_address_occupied;
     64        fibril_condvar_t change;
    6465        usb_address_t last_address;
    6566} usb_device_keeper_t;
     
    9798    usb_address_t address);
    9899
     100void usb_device_keeper_use_control(usb_device_keeper_t *instance,
     101    usb_address_t address);
     102
     103void usb_device_keeper_release_control(usb_device_keeper_t *instance,
     104    usb_address_t address);
     105
    99106#endif
    100107/**
  • uspace/lib/usb/src/hidparser.c

    r889e8e3 r291b8bc  
    4747
    4848int usb_hid_report_parse_tag(uint8_t tag, uint8_t class, const uint8_t *data, size_t item_size,
    49                              usb_hid_report_item_t *report_item);
     49                             usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path);
    5050int usb_hid_report_parse_main_tag(uint8_t tag, const uint8_t *data, size_t item_size,
    51                              usb_hid_report_item_t *report_item);
     51                             usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path);
    5252int usb_hid_report_parse_global_tag(uint8_t tag, const uint8_t *data, size_t item_size,
    53                              usb_hid_report_item_t *report_item);
     53                             usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path);
    5454int usb_hid_report_parse_local_tag(uint8_t tag, const uint8_t *data, size_t item_size,
    55                              usb_hid_report_item_t *report_item);
     55                             usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path);
    5656
    5757void usb_hid_descriptor_print_list(link_t *head);
     
    6363int usb_pow(int a, int b);
    6464
     65
    6566int usb_pow(int a, int b)
    6667{
     
    8485{
    8586   if(parser == NULL) {
    86         return -1;
     87        return EINVAL;
    8788   }
    8889
     
    110111        int ret;
    111112        usb_hid_report_item_t *report_item=0;
    112         usb_hid_report_item_t *new_report_item;
     113        usb_hid_report_item_t *new_report_item;
     114        usb_hid_report_path_t *usage_path;
     115        usb_hid_report_path_t *tmp_usage_path;
    113116
    114117        size_t offset_input=0;
     
    117120       
    118121
     122        /* parser structure initialization*/
     123        if(usb_hid_parser_init(parser) != EOK) {
     124                return EINVAL;
     125        }
     126       
     127
     128        /*report item initialization*/
    119129        if(!(report_item=malloc(sizeof(usb_hid_report_item_t)))){
    120130                return ENOMEM;
    121131        }
    122132        memset(report_item, 0, sizeof(usb_hid_report_item_t));
    123        
    124         link_initialize(&(report_item->link)); 
    125 
     133        list_initialize(&(report_item->link)); 
     134
     135        /* usage path context initialization */
     136        if(!(usage_path=usb_hid_report_path())){
     137                return ENOMEM;
     138        }
     139       
    126140        while(i<size){ 
    127141                if(!USB_HID_ITEM_IS_LONG(data[i])){
    128142
    129143                        if((i+USB_HID_ITEM_SIZE(data[i]))>= size){
    130                                 return -1; // TODO ERROR CODE
     144                                return EINVAL; // TODO ERROR CODE
    131145                        }
    132146                       
     
    141155                       
    142156                        ret = usb_hid_report_parse_tag(tag,class,data+i+1,
    143                                                  item_size,report_item);
     157                                                       item_size,report_item, usage_path);
    144158                        usb_log_debug2("ret: %u\n", ret);
    145159                        switch(ret){
    146160                                case USB_HID_NEW_REPORT_ITEM:
    147161                                        // store report item to report and create the new one
    148                                         usb_log_debug("\nNEW REPORT ITEM: %X",tag);
     162                                        usb_log_debug("\nNEW REPORT ITEM: %X",ret);
     163
     164                                        // store current usage path
     165                                        report_item->usage_path = usage_path;
     166
     167                                        // new current usage path
     168                                        tmp_usage_path = usb_hid_report_path();
     169                                       
     170                                        // copy old path to the new one
     171                                        usb_hid_report_path_clone(tmp_usage_path, usage_path);
     172
     173                                        // swap
     174                                        usage_path = tmp_usage_path;
     175                                        tmp_usage_path = NULL;
     176
    149177                                       
    150178                                        switch(tag) {
     
    184212                                        link_initialize(&(new_report_item->link));
    185213                                        report_item = new_report_item;
    186                                        
     214                                                                               
    187215                                        break;
    188216                                case USB_HID_REPORT_TAG_PUSH:
     
    284312 */
    285313int usb_hid_report_parse_tag(uint8_t tag, uint8_t class, const uint8_t *data, size_t item_size,
    286                              usb_hid_report_item_t *report_item)
     314                             usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path)
    287315{       
    288316        int ret;
     
    291319                case USB_HID_TAG_CLASS_MAIN:
    292320
    293                         if((ret=usb_hid_report_parse_main_tag(tag,data,item_size,report_item)) == EOK) {
     321                        if((ret=usb_hid_report_parse_main_tag(tag,data,item_size,report_item, usage_path)) == EOK) {
    294322                                return USB_HID_NEW_REPORT_ITEM;
    295323                        }
     
    301329
    302330                case USB_HID_TAG_CLASS_GLOBAL: 
    303                         return usb_hid_report_parse_global_tag(tag,data,item_size,report_item);
     331                        return usb_hid_report_parse_global_tag(tag,data,item_size,report_item, usage_path);
    304332                        break;
    305333
    306334                case USB_HID_TAG_CLASS_LOCAL:                   
    307                         return usb_hid_report_parse_local_tag(tag,data,item_size,report_item);
     335                        return usb_hid_report_parse_local_tag(tag,data,item_size,report_item, usage_path);
    308336                        break;
    309337                default:
     
    323351
    324352int usb_hid_report_parse_main_tag(uint8_t tag, const uint8_t *data, size_t item_size,
    325                              usb_hid_report_item_t *report_item)
    326 {
     353                             usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path)
     354{               
    327355        switch(tag)
    328356        {
     
    335363                       
    336364                case USB_HID_REPORT_TAG_COLLECTION:
    337                         // TODO
     365                        usb_hid_report_path_append_item(usage_path, 0, 0);
     366                                               
    338367                        return USB_HID_NO_ACTION;
    339368                        break;
    340369                       
    341370                case USB_HID_REPORT_TAG_END_COLLECTION:
    342                         /* should be ignored */
     371                        // TODO
     372                        // znici posledni uroven ve vsech usage paths
     373                        // otazka jestli nema nicit dve, respektive novou posledni vynulovat?
     374                        usb_hid_report_remove_last_item(usage_path);
    343375                        return USB_HID_NO_ACTION;
    344376                        break;
     
    361393
    362394int usb_hid_report_parse_global_tag(uint8_t tag, const uint8_t *data, size_t item_size,
    363                              usb_hid_report_item_t *report_item)
     395                             usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path)
    364396{
    365397        // TODO take care about the bit length of data
     
    367399        {
    368400                case USB_HID_REPORT_TAG_USAGE_PAGE:
    369                         report_item->usage_page = usb_hid_report_tag_data_int32(data,item_size);
     401                        // zmeni to jenom v poslednim poli aktualni usage path
     402                        usb_hid_report_set_last_item(usage_path, USB_HID_TAG_CLASS_GLOBAL,
     403                                usb_hid_report_tag_data_int32(data,item_size));
    370404                        break;
    371405                case USB_HID_REPORT_TAG_LOGICAL_MINIMUM:
     
    418452 */
    419453int usb_hid_report_parse_local_tag(uint8_t tag, const uint8_t *data, size_t item_size,
    420                              usb_hid_report_item_t *report_item)
     454                             usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path)
    421455{
    422456        switch(tag)
    423457        {
    424458                case USB_HID_REPORT_TAG_USAGE:
    425                         report_item->usage = usb_hid_report_tag_data_int32(data,item_size);
     459                        usb_hid_report_set_last_item(usage_path, USB_HID_TAG_CLASS_LOCAL,
     460                                usb_hid_report_tag_data_int32(data,item_size));
    426461                        break;
    427462                case USB_HID_REPORT_TAG_USAGE_MINIMUM:
     
    491526{
    492527        usb_hid_report_item_t *report_item;
     528        usb_hid_report_usage_path_t *path_item;
     529        link_t *path;
    493530        link_t *item;
    494531       
     
    507544                usb_log_debug("\tCONSTANT/VAR: %X\n", USB_HID_ITEM_FLAG_CONSTANT(report_item->item_flags));
    508545                usb_log_debug("\tVARIABLE/ARRAY: %X\n", USB_HID_ITEM_FLAG_VARIABLE(report_item->item_flags));
    509                 usb_log_debug("\tUSAGE: %X\n", report_item->usage);
    510                 usb_log_debug("\tUSAGE PAGE: %X\n", report_item->usage_page);
     546                usb_log_debug("\tUSAGE PATH:\n");
     547
     548                path = report_item->usage_path->link.next;
     549                while(path != &report_item->usage_path->link)   {
     550                        path_item = list_get_instance(path, usb_hid_report_usage_path_t, link);
     551                        usb_log_debug("\t\tUSAGE PAGE: %X, USAGE: %X\n", path_item->usage_page, path_item->usage);
     552                        path = path->next;
     553                }
     554               
     555               
     556//              usb_log_debug("\tUSAGE: %X\n", report_item->usage);
     557//              usb_log_debug("\tUSAGE PAGE: %X\n", report_item->usage_page);
    511558                usb_log_debug("\tLOGMIN: %X\n", report_item->logical_minimum);
    512559                usb_log_debug("\tLOGMAX: %X\n", report_item->logical_maximum);         
     
    530577void usb_hid_descriptor_print(usb_hid_report_parser_t *parser)
    531578{
     579        if(parser == NULL) {
     580                return;
     581        }
     582       
    532583        usb_log_debug("INPUT:\n");
    533584        usb_hid_descriptor_print_list(&parser->input);
     
    561612       
    562613            report_item = list_get_instance(next, usb_hid_report_item_t, link);
     614
     615                while(!list_empty(&report_item->usage_path->link)) {
     616                        usb_hid_report_remove_last_item(report_item->usage_path);
     617                }
     618
     619               
    563620            next = next->next;
    564621           
     
    600657int usb_hid_parse_report(const usb_hid_report_parser_t *parser, 
    601658    const uint8_t *data, size_t size,
     659    usb_hid_report_path_t *path, int flags,
    602660    const usb_hid_report_in_callbacks_t *callbacks, void *arg)
    603661{
     
    615673        size_t j=0;
    616674
     675        if(parser == NULL) {
     676                return EINVAL;
     677        }
     678
     679       
    617680        // get the size of result keycodes array
    618         usb_hid_report_path_t path;
    619         path.usage_page = BAD_HACK_USAGE_PAGE;
    620         key_count = usb_hid_report_input_length(parser, &path);
     681        key_count = usb_hid_report_input_length(parser, path, flags);
    621682
    622683        if(!(keys = malloc(sizeof(uint8_t) * key_count))){
     
    629690
    630691                item = list_get_instance(list_item, usb_hid_report_item_t, link);
    631                 if(!USB_HID_ITEM_FLAG_CONSTANT(item->item_flags) &&
    632                    (item->usage_page == path.usage_page)) {
     692                if(!USB_HID_ITEM_FLAG_CONSTANT(item->item_flags) && 
     693                   (usb_hid_report_compare_usage_path(item->usage_path, path, flags) == EOK)) {
    633694                        for(j=0; j<(size_t)(item->count); j++) {
    634695                                if((USB_HID_ITEM_FLAG_VARIABLE(item->item_flags) == 0) ||
     
    640701                                        // bitmapa
    641702                                        if((item_value = usb_hid_translate_data(item, data, j)) != 0) {
    642                                                 keys[i++] = j + item->usage_minimum;
     703                                                keys[i++] = (item->count - 1 - j) + item->usage_minimum;
    643704                                        }
    644705                                        else {
     
    736797
    737798int usb_hid_report_input_length(const usb_hid_report_parser_t *parser,
    738         const usb_hid_report_path_t *path)
    739 {
     799        usb_hid_report_path_t *path, int flags)
     800{       
    740801        int ret = 0;
    741802        link_t *item;
    742803        usb_hid_report_item_t *report_item;
    743804
     805        if(parser == NULL) {
     806                return EINVAL;
     807        }
     808       
    744809        item = (&parser->input)->next;
    745810        while(&parser->input != item) {
    746811                report_item = list_get_instance(item, usb_hid_report_item_t, link);
    747812                if(!USB_HID_ITEM_FLAG_CONSTANT(report_item->item_flags) &&
    748                    (report_item->usage_page == path->usage_page)) {
     813                   (usb_hid_report_compare_usage_path(report_item->usage_path, path, flags) == EOK)) {
    749814                        ret += report_item->count;
    750815                }
     
    757822
    758823
     824/**
     825 *
     826 */
     827int usb_hid_report_path_append_item(usb_hid_report_path_t *usage_path,
     828                                    int32_t usage_page, int32_t usage)
     829{       
     830        usb_hid_report_usage_path_t *item;
     831
     832        if(!(item=malloc(sizeof(usb_hid_report_usage_path_t)))) {
     833                return ENOMEM;
     834        }
     835        list_initialize(&item->link);
     836
     837        item->usage = usage;
     838        item->usage_page = usage_page;
     839       
     840        list_append (&usage_path->link, &item->link);
     841        usage_path->depth++;
     842        return EOK;
     843}
     844
     845/**
     846 *
     847 */
     848void usb_hid_report_remove_last_item(usb_hid_report_path_t *usage_path)
     849{
     850        usb_hid_report_usage_path_t *item;
     851       
     852        if(!list_empty(&usage_path->link)){
     853                item = list_get_instance(usage_path->link.prev, usb_hid_report_usage_path_t, link);             
     854                list_remove(usage_path->link.prev);
     855                usage_path->depth--;
     856                free(item);
     857        }
     858}
     859
     860/**
     861 *
     862 */
     863void usb_hid_report_null_last_item(usb_hid_report_path_t *usage_path)
     864{
     865        usb_hid_report_usage_path_t *item;
     866       
     867        if(!list_empty(&usage_path->link)){     
     868                item = list_get_instance(usage_path->link.prev, usb_hid_report_usage_path_t, link);
     869                memset(item, 0, sizeof(usb_hid_report_usage_path_t));
     870        }
     871}
     872
     873/**
     874 *
     875 */
     876void usb_hid_report_set_last_item(usb_hid_report_path_t *usage_path, int32_t tag, int32_t data)
     877{
     878        usb_hid_report_usage_path_t *item;
     879       
     880        if(!list_empty(&usage_path->link)){     
     881                item = list_get_instance(usage_path->link.prev, usb_hid_report_usage_path_t, link);
     882
     883                switch(tag) {
     884                        case USB_HID_TAG_CLASS_GLOBAL:
     885                                item->usage_page = data;
     886                                break;
     887                        case USB_HID_TAG_CLASS_LOCAL:
     888                                item->usage = data;
     889                                break;
     890                }
     891        }
     892       
     893}
     894
     895/**
     896 *
     897 */
     898int usb_hid_report_compare_usage_path(usb_hid_report_path_t *report_path,
     899                                      usb_hid_report_path_t *path,
     900                                      int flags)
     901{
     902        usb_hid_report_usage_path_t *report_item;
     903        usb_hid_report_usage_path_t *path_item;
     904
     905        link_t *report_link;
     906        link_t *path_link;
     907
     908        int only_page;
     909
     910        if(path->depth == 0){
     911                return EOK;
     912        }
     913
     914
     915        if((only_page = flags & USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY) != 0){
     916                flags -= USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY;
     917        }
     918       
     919        switch(flags){
     920                /* path must be completly identical */
     921                case USB_HID_PATH_COMPARE_STRICT:
     922                                if(report_path->depth != path->depth){
     923                                        return 1;
     924                                }
     925
     926                                report_link = report_path->link.next;
     927                                path_link = path->link.next;
     928                       
     929                                while((report_link != &report_path->link) && (path_link != &path->link)) {
     930                                        report_item = list_get_instance(report_link, usb_hid_report_usage_path_t, link);
     931                                        path_item = list_get_instance(path_link, usb_hid_report_usage_path_t, link);           
     932
     933                                        if((report_item->usage_page != path_item->usage_page) ||
     934                                           ((only_page == 0) && (report_item->usage != path_item->usage))) {
     935                                                   return 1;
     936                                        } else {
     937                                                report_link = report_link->next;
     938                                                path_link = path_link->next;                   
     939                                        }
     940                       
     941                                }
     942
     943                                if((report_link == &report_path->link) && (path_link == &path->link)) {
     944                                        return EOK;
     945                                }
     946                                else {
     947                                        return 1;
     948                                }                                               
     949                        break;
     950
     951                /* given path must be the end of the report one*/
     952                case USB_HID_PATH_COMPARE_END:
     953                                report_link = report_path->link.prev;
     954                                path_link = path->link.prev;
     955
     956                                if(list_empty(&path->link)){
     957                                        return EOK;
     958                                }
     959                       
     960                                while((report_link != &report_path->link) && (path_link != &path->link)) {
     961                                        report_item = list_get_instance(report_link, usb_hid_report_usage_path_t, link);
     962                                        path_item = list_get_instance(path_link, usb_hid_report_usage_path_t, link);           
     963
     964                                        if((report_item->usage_page != path_item->usage_page) ||
     965                                           ((only_page == 0) && (report_item->usage != path_item->usage))) {
     966                                                   return 1;
     967                                        } else {
     968                                                report_link = report_link->prev;
     969                                                path_link = path_link->prev;                   
     970                                        }
     971                       
     972                                }
     973
     974                                if(path_link == &path->link) {
     975                                        return EOK;
     976                                }
     977                                else {
     978                                        return 1;
     979                                }                                               
     980                       
     981                        break;
     982
     983                default:
     984                        return EINVAL;
     985        }
     986       
     987       
     988       
     989       
     990}
     991
     992/**
     993 *
     994 */
     995usb_hid_report_path_t *usb_hid_report_path(void)
     996{
     997        usb_hid_report_path_t *path;
     998        path = malloc(sizeof(usb_hid_report_path_t));
     999        if(!path){
     1000                return NULL;
     1001        }
     1002        else {
     1003                path->depth = 0;
     1004                list_initialize(&path->link);
     1005                return path;
     1006        }
     1007}
     1008
     1009/**
     1010 *
     1011 */
     1012void usb_hid_report_path_free(usb_hid_report_path_t *path)
     1013{
     1014        while(!list_empty(&path->link)){
     1015                usb_hid_report_remove_last_item(path);
     1016        }
     1017}
     1018
     1019
     1020/**
     1021 *
     1022 */
     1023int     usb_hid_report_path_clone(usb_hid_report_path_t *new_usage_path, usb_hid_report_path_t *usage_path)
     1024{
     1025        usb_hid_report_usage_path_t *path_item;
     1026        link_t *path_link;
     1027
     1028       
     1029        if(list_empty(&usage_path->link)){
     1030                return EOK;
     1031        }
     1032
     1033        path_link = usage_path->link.next;
     1034        while(path_link != &usage_path->link) {
     1035                path_item = list_get_instance(path_link, usb_hid_report_usage_path_t, link);
     1036                usb_hid_report_path_append_item (new_usage_path, path_item->usage_page, path_item->usage);
     1037
     1038                path_link = path_link->next;
     1039        }
     1040
     1041        return EOK;
     1042}
     1043
    7591044
    7601045/**
  • uspace/lib/usb/src/hidreq.c

    r889e8e3 r291b8bc  
    4141#include <usb/debug.h>
    4242#include <usb/request.h>
    43 
    44 #include "hidreq.h"
    45 #include "hiddev.h"
     43#include <usb/pipes.h>
     44
     45#include <usb/classes/hidreq.h>
    4646
    4747/*----------------------------------------------------------------------------*/
     
    6060 *         usb_control_request_set().
    6161 */
    62 int usbhid_req_set_report(usbhid_dev_t *hid_dev,
     62int usbhid_req_set_report(usb_pipe_t *ctrl_pipe, int iface_no,
    6363    usb_hid_report_type_t type, uint8_t *buffer, size_t buf_size)
    6464{
    65         if (hid_dev == NULL) {
    66                 usb_log_error("usbhid_req_set_report(): no HID device structure"
    67                     " given.\n");
    68                 return EINVAL;
    69         }
    70        
    71         /*
    72          * No need for checking other parameters, as they are checked in
    73          * the called function (usb_control_request_set()).
    74          */
    75        
    76         int rc, sess_rc;
    77        
    78         sess_rc = usb_pipe_start_session(&hid_dev->ctrl_pipe);
     65        if (ctrl_pipe == NULL) {
     66                usb_log_warning("usbhid_req_set_report(): no pipe given.\n");
     67                return EINVAL;
     68        }
     69       
     70        if (iface_no < 0) {
     71                usb_log_warning("usbhid_req_set_report(): no interface given."
     72                    "\n");
     73                return EINVAL;
     74        }
     75       
     76        /*
     77         * No need for checking other parameters, as they are checked in
     78         * the called function (usb_control_request_set()).
     79         */
     80       
     81        int rc, sess_rc;
     82       
     83        sess_rc = usb_pipe_start_session(ctrl_pipe);
    7984        if (sess_rc != EOK) {
    8085                usb_log_warning("Failed to start a session: %s.\n",
     
    8893        usb_log_debug("Sending Set_Report request to the device.\n");
    8994       
    90         rc = usb_control_request_set(&hid_dev->ctrl_pipe,
    91             USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE,
    92             USB_HIDREQ_SET_REPORT, value, hid_dev->iface, buffer, buf_size);
    93 
    94         sess_rc = usb_pipe_end_session(&hid_dev->ctrl_pipe);
     95        rc = usb_control_request_set(ctrl_pipe,
     96            USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE,
     97            USB_HIDREQ_SET_REPORT, value, iface_no, buffer, buf_size);
     98
     99        sess_rc = usb_pipe_end_session(ctrl_pipe);
    95100
    96101        if (rc != EOK) {
     
    122127 *         usb_control_request_set().
    123128 */
    124 int usbhid_req_set_protocol(usbhid_dev_t *hid_dev, usb_hid_protocol_t protocol)
    125 {
    126         if (hid_dev == NULL) {
    127                 usb_log_error("usbhid_req_set_protocol(): no HID device "
    128                     "structure given.\n");
    129                 return EINVAL;
    130         }
    131        
    132         /*
    133          * No need for checking other parameters, as they are checked in
    134          * the called function (usb_control_request_set()).
    135          */
    136        
    137         int rc, sess_rc;
    138        
    139         sess_rc = usb_pipe_start_session(&hid_dev->ctrl_pipe);
     129int usbhid_req_set_protocol(usb_pipe_t *ctrl_pipe, int iface_no,
     130    usb_hid_protocol_t protocol)
     131{
     132        if (ctrl_pipe == NULL) {
     133                usb_log_warning("usbhid_req_set_report(): no pipe given.\n");
     134                return EINVAL;
     135        }
     136       
     137        if (iface_no < 0) {
     138                usb_log_warning("usbhid_req_set_report(): no interface given."
     139                    "\n");
     140                return EINVAL;
     141        }
     142       
     143        /*
     144         * No need for checking other parameters, as they are checked in
     145         * the called function (usb_control_request_set()).
     146         */
     147       
     148        int rc, sess_rc;
     149       
     150        sess_rc = usb_pipe_start_session(ctrl_pipe);
    140151        if (sess_rc != EOK) {
    141152                usb_log_warning("Failed to start a session: %s.\n",
     
    145156
    146157        usb_log_debug("Sending Set_Protocol request to the device ("
    147             "protocol: %d, iface: %d).\n", protocol, hid_dev->iface);
    148        
    149         rc = usb_control_request_set(&hid_dev->ctrl_pipe,
    150             USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE,
    151             USB_HIDREQ_SET_PROTOCOL, protocol, hid_dev->iface, NULL, 0);
    152 
    153         sess_rc = usb_pipe_end_session(&hid_dev->ctrl_pipe);
     158            "protocol: %d, iface: %d).\n", protocol, iface_no);
     159       
     160        rc = usb_control_request_set(ctrl_pipe,
     161            USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE,
     162            USB_HIDREQ_SET_PROTOCOL, protocol, iface_no, NULL, 0);
     163
     164        sess_rc = usb_pipe_end_session(ctrl_pipe);
    154165
    155166        if (rc != EOK) {
     
    182193 *         usb_control_request_set().
    183194 */
    184 int usbhid_req_set_idle(usbhid_dev_t *hid_dev, uint8_t duration)
    185 {
    186         if (hid_dev == NULL) {
    187                 usb_log_error("usbhid_req_set_idle(): no HID device "
    188                     "structure given.\n");
    189                 return EINVAL;
    190         }
    191        
    192         /*
    193          * No need for checking other parameters, as they are checked in
    194          * the called function (usb_control_request_set()).
    195          */
    196        
    197         int rc, sess_rc;
    198        
    199         sess_rc = usb_pipe_start_session(&hid_dev->ctrl_pipe);
     195int usbhid_req_set_idle(usb_pipe_t *ctrl_pipe, int iface_no, uint8_t duration)
     196{
     197        if (ctrl_pipe == NULL) {
     198                usb_log_warning("usbhid_req_set_report(): no pipe given.\n");
     199                return EINVAL;
     200        }
     201       
     202        if (iface_no < 0) {
     203                usb_log_warning("usbhid_req_set_report(): no interface given."
     204                    "\n");
     205                return EINVAL;
     206        }
     207       
     208        /*
     209         * No need for checking other parameters, as they are checked in
     210         * the called function (usb_control_request_set()).
     211         */
     212       
     213        int rc, sess_rc;
     214       
     215        sess_rc = usb_pipe_start_session(ctrl_pipe);
    200216        if (sess_rc != EOK) {
    201217                usb_log_warning("Failed to start a session: %s.\n",
     
    205221
    206222        usb_log_debug("Sending Set_Idle request to the device ("
    207             "duration: %u, iface: %d).\n", duration, hid_dev->iface);
     223            "duration: %u, iface: %d).\n", duration, iface_no);
    208224       
    209225        uint16_t value = duration << 8;
    210226       
    211         rc = usb_control_request_set(&hid_dev->ctrl_pipe,
    212             USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE,
    213             USB_HIDREQ_SET_IDLE, value, hid_dev->iface, NULL, 0);
    214 
    215         sess_rc = usb_pipe_end_session(&hid_dev->ctrl_pipe);
     227        rc = usb_control_request_set(ctrl_pipe,
     228            USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE,
     229            USB_HIDREQ_SET_IDLE, value, iface_no, NULL, 0);
     230
     231        sess_rc = usb_pipe_end_session(ctrl_pipe);
    216232
    217233        if (rc != EOK) {
     
    247263 *         usb_control_request_set().
    248264 */
    249 int usbhid_req_get_report(usbhid_dev_t *hid_dev, usb_hid_report_type_t type,
    250     uint8_t *buffer, size_t buf_size, size_t *actual_size)
    251 {
    252         if (hid_dev == NULL) {
    253                 usb_log_error("usbhid_req_set_report(): no HID device structure"
    254                     " given.\n");
    255                 return EINVAL;
    256         }
    257        
    258         /*
    259          * No need for checking other parameters, as they are checked in
    260          * the called function (usb_control_request_set()).
    261          */
    262        
    263         int rc, sess_rc;
    264        
    265         sess_rc = usb_pipe_start_session(&hid_dev->ctrl_pipe);
     265int usbhid_req_get_report(usb_pipe_t *ctrl_pipe, int iface_no,
     266    usb_hid_report_type_t type, uint8_t *buffer, size_t buf_size,
     267    size_t *actual_size)
     268{
     269        if (ctrl_pipe == NULL) {
     270                usb_log_warning("usbhid_req_set_report(): no pipe given.\n");
     271                return EINVAL;
     272        }
     273       
     274        if (iface_no < 0) {
     275                usb_log_warning("usbhid_req_set_report(): no interface given."
     276                    "\n");
     277                return EINVAL;
     278        }
     279       
     280        /*
     281         * No need for checking other parameters, as they are checked in
     282         * the called function (usb_control_request_set()).
     283         */
     284       
     285        int rc, sess_rc;
     286       
     287        sess_rc = usb_pipe_start_session(ctrl_pipe);
    266288        if (sess_rc != EOK) {
    267289                usb_log_warning("Failed to start a session: %s.\n",
     
    275297        usb_log_debug("Sending Get_Report request to the device.\n");
    276298       
    277         rc = usb_control_request_get(&hid_dev->ctrl_pipe,
    278             USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE,
    279             USB_HIDREQ_GET_REPORT, value, hid_dev->iface, buffer, buf_size,
     299        rc = usb_control_request_get(ctrl_pipe,
     300            USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE,
     301            USB_HIDREQ_GET_REPORT, value, iface_no, buffer, buf_size,
    280302            actual_size);
    281303
    282         sess_rc = usb_pipe_end_session(&hid_dev->ctrl_pipe);
     304        sess_rc = usb_pipe_end_session(ctrl_pipe);
    283305
    284306        if (rc != EOK) {
     
    310332 *         usb_control_request_set().
    311333 */
    312 int usbhid_req_get_protocol(usbhid_dev_t *hid_dev, usb_hid_protocol_t *protocol)
    313 {
    314         if (hid_dev == NULL) {
    315                 usb_log_error("usbhid_req_set_protocol(): no HID device "
    316                     "structure given.\n");
    317                 return EINVAL;
    318         }
    319        
    320         /*
    321          * No need for checking other parameters, as they are checked in
    322          * the called function (usb_control_request_set()).
    323          */
    324        
    325         int rc, sess_rc;
    326        
    327         sess_rc = usb_pipe_start_session(&hid_dev->ctrl_pipe);
     334int usbhid_req_get_protocol(usb_pipe_t *ctrl_pipe, int iface_no,
     335    usb_hid_protocol_t *protocol)
     336{
     337        if (ctrl_pipe == NULL) {
     338                usb_log_warning("usbhid_req_set_report(): no pipe given.\n");
     339                return EINVAL;
     340        }
     341       
     342        if (iface_no < 0) {
     343                usb_log_warning("usbhid_req_set_report(): no interface given."
     344                    "\n");
     345                return EINVAL;
     346        }
     347       
     348        /*
     349         * No need for checking other parameters, as they are checked in
     350         * the called function (usb_control_request_set()).
     351         */
     352       
     353        int rc, sess_rc;
     354       
     355        sess_rc = usb_pipe_start_session(ctrl_pipe);
    328356        if (sess_rc != EOK) {
    329357                usb_log_warning("Failed to start a session: %s.\n",
     
    333361
    334362        usb_log_debug("Sending Get_Protocol request to the device ("
    335             "iface: %d).\n", hid_dev->iface);
     363            "iface: %d).\n", iface_no);
    336364       
    337365        uint8_t buffer[1];
    338366        size_t actual_size = 0;
    339367       
    340         rc = usb_control_request_get(&hid_dev->ctrl_pipe,
    341             USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE,
    342             USB_HIDREQ_GET_PROTOCOL, 0, hid_dev->iface, buffer, 1, &actual_size);
    343 
    344         sess_rc = usb_pipe_end_session(&hid_dev->ctrl_pipe);
     368        rc = usb_control_request_get(ctrl_pipe,
     369            USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE,
     370            USB_HIDREQ_GET_PROTOCOL, 0, iface_no, buffer, 1, &actual_size);
     371
     372        sess_rc = usb_pipe_end_session(ctrl_pipe);
    345373
    346374        if (rc != EOK) {
     
    381409 *         usb_control_request_set().
    382410 */
    383 int usbhid_req_get_idle(usbhid_dev_t *hid_dev, uint8_t *duration)
    384 {
    385         if (hid_dev == NULL) {
    386                 usb_log_error("usbhid_req_set_idle(): no HID device "
    387                     "structure given.\n");
    388                 return EINVAL;
    389         }
    390        
    391         /*
    392          * No need for checking other parameters, as they are checked in
    393          * the called function (usb_control_request_set()).
    394          */
    395        
    396         int rc, sess_rc;
    397        
    398         sess_rc = usb_pipe_start_session(&hid_dev->ctrl_pipe);
     411int usbhid_req_get_idle(usb_pipe_t *ctrl_pipe, int iface_no, uint8_t *duration)
     412{
     413        if (ctrl_pipe == NULL) {
     414                usb_log_warning("usbhid_req_set_report(): no pipe given.\n");
     415                return EINVAL;
     416        }
     417       
     418        if (iface_no < 0) {
     419                usb_log_warning("usbhid_req_set_report(): no interface given."
     420                    "\n");
     421                return EINVAL;
     422        }
     423       
     424        /*
     425         * No need for checking other parameters, as they are checked in
     426         * the called function (usb_control_request_set()).
     427         */
     428       
     429        int rc, sess_rc;
     430       
     431        sess_rc = usb_pipe_start_session(ctrl_pipe);
    399432        if (sess_rc != EOK) {
    400433                usb_log_warning("Failed to start a session: %s.\n",
     
    404437
    405438        usb_log_debug("Sending Get_Idle request to the device ("
    406             "iface: %d).\n", hid_dev->iface);
     439            "iface: %d).\n", iface_no);
    407440       
    408441        uint16_t value = 0;
     
    410443        size_t actual_size = 0;
    411444       
    412         rc = usb_control_request_get(&hid_dev->ctrl_pipe,
    413             USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE,
    414             USB_HIDREQ_GET_IDLE, value, hid_dev->iface, buffer, 1,
     445        rc = usb_control_request_get(ctrl_pipe,
     446            USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE,
     447            USB_HIDREQ_GET_IDLE, value, iface_no, buffer, 1,
    415448            &actual_size);
    416449
    417         sess_rc = usb_pipe_end_session(&hid_dev->ctrl_pipe);
     450        sess_rc = usb_pipe_end_session(ctrl_pipe);
    418451
    419452        if (rc != EOK) {
  • uspace/lib/usb/src/host/device_keeper.c

    r889e8e3 r291b8bc  
    4949        assert(instance);
    5050        fibril_mutex_initialize(&instance->guard);
    51         fibril_condvar_initialize(&instance->default_address_occupied);
     51        fibril_condvar_initialize(&instance->change);
    5252        instance->last_address = 0;
    5353        unsigned i = 0;
    5454        for (; i < USB_ADDRESS_COUNT; ++i) {
    5555                instance->devices[i].occupied = false;
     56                instance->devices[i].control_used = false;
    5657                instance->devices[i].handle = 0;
    5758                instance->devices[i].toggle_status[0] = 0;
     
    7172        fibril_mutex_lock(&instance->guard);
    7273        while (instance->devices[USB_ADDRESS_DEFAULT].occupied) {
    73                 fibril_condvar_wait(&instance->default_address_occupied,
    74                     &instance->guard);
     74                fibril_condvar_wait(&instance->change, &instance->guard);
    7575        }
    7676        instance->devices[USB_ADDRESS_DEFAULT].occupied = true;
     
    9090        instance->devices[USB_ADDRESS_DEFAULT].occupied = false;
    9191        fibril_mutex_unlock(&instance->guard);
    92         fibril_condvar_signal(&instance->default_address_occupied);
     92        fibril_condvar_signal(&instance->change);
    9393}
    9494/*----------------------------------------------------------------------------*/
     
    309309        return instance->devices[address].speed;
    310310}
    311 
     311/*----------------------------------------------------------------------------*/
     312void usb_device_keeper_use_control(usb_device_keeper_t *instance,
     313    usb_address_t address)
     314{
     315        assert(instance);
     316        fibril_mutex_lock(&instance->guard);
     317        while (instance->devices[address].control_used) {
     318                fibril_condvar_wait(&instance->change, &instance->guard);
     319        }
     320        instance->devices[address].control_used = true;
     321        fibril_mutex_unlock(&instance->guard);
     322}
     323/*----------------------------------------------------------------------------*/
     324void usb_device_keeper_release_control(usb_device_keeper_t *instance,
     325    usb_address_t address)
     326{
     327        assert(instance);
     328        fibril_mutex_lock(&instance->guard);
     329        instance->devices[address].control_used = false;
     330        fibril_mutex_unlock(&instance->guard);
     331        fibril_condvar_signal(&instance->change);
     332}
    312333/**
    313334 * @}
Note: See TracChangeset for help on using the changeset viewer.