Changeset cc5908e in mainline


Ignore:
Timestamp:
2011-05-07T14:28:51Z (14 years ago)
Author:
Matej Klonfar <maklf@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
252cf2a, 68b614e
Parents:
bd2394b (diff), 7205209 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Development changes merged

Files:
3 added
6 deleted
45 edited
6 moved

Legend:

Unmodified
Added
Removed
  • .bzrignore

    rbd2394b rcc5908e  
    4949./uspace/app/killall/killall
    5050./uspace/app/klog/klog
     51./uspace/app/lsusb/lsusb
    5152./uspace/app/mkfat/mkfat
    5253./uspace/app/netstart/netstart
  • boot/Makefile.common

    rbd2394b rcc5908e  
    128128        $(USPACE_PATH)/app/killall/killall \
    129129        $(USPACE_PATH)/app/mkfat/mkfat \
     130        $(USPACE_PATH)/app/lsusb/lsusb \
    130131        $(USPACE_PATH)/app/sbi/sbi \
    131132        $(USPACE_PATH)/app/redir/redir \
     
    140141        $(USPACE_PATH)/app/stats/stats \
    141142        $(USPACE_PATH)/app/sysinfo/sysinfo \
    142         $(USPACE_PATH)/app/tasks/tasks \
    143143        $(USPACE_PATH)/app/top/top \
    144144        $(USPACE_PATH)/app/usbinfo/usbinfo \
    145         $(USPACE_PATH)/app/virtusbkbd/vuk \
    146145        $(USPACE_PATH)/app/vuhid/vuh \
    147146        $(USPACE_PATH)/app/websrv/websrv
  • uspace/Makefile

    rbd2394b rcc5908e  
    4141        app/killall \
    4242        app/klog \
     43        app/lsusb \
    4344        app/mkfat \
    4445        app/redir \
     
    5152        app/top \
    5253        app/usbinfo \
    53         app/virtusbkbd \
    5454        app/vuhid \
    5555        app/netecho \
  • uspace/app/lsusb/Makefile

    rbd2394b rcc5908e  
    11#
    2 # Copyright (c) 2010 Vojtech Horky
     2# Copyright (c) 2011 Vojtech Horky
    33# All rights reserved.
    44#
     
    2828
    2929USPACE_PREFIX = ../..
    30 # acronym for virtual usb keyboard
    31 # (it is really annoying to write long names)
    32 BINARY = vuk
     30BINARY = lsusb
    3331
    34 LIBS = $(LIBUSBVIRT_PREFIX)/libusbvirt.a $(LIBUSB_PREFIX)/libusb.a
    35 EXTRA_CFLAGS = -I$(LIBUSB_PREFIX)/include -I$(LIBUSBVIRT_PREFIX)/include -I$(LIBDRV_PREFIX)/include
     32LIBS = $(LIBUSB_PREFIX)/libusb.a $(LIBDRV_PREFIX)/libdrv.a
     33EXTRA_CFLAGS = -I$(LIBUSB_PREFIX)/include -I$(LIBDRV_PREFIX)/include
    3634
    3735SOURCES = \
    38         kbdconfig.c \
    39         keys.c \
    40         stdreq.c \
    41         virtusbkbd.c
     36        main.c
    4237
    4338include $(USPACE_PREFIX)/Makefile.common
  • uspace/app/lsusb/main.c

    rbd2394b rcc5908e  
    11/*
    2  * Copyright (c) 2010 Vojtech Horky
     2 * Copyright (c) 2010-2011 Vojtech Horky
    33 * All rights reserved.
    44 *
     
    2727 */
    2828
    29 /** @addtogroup usbvirtkbd
     29/** @addtogroup lsusb
    3030 * @{
    3131 */
    3232/**
    3333 * @file
    34  * @brief Keyboard configuration.
     34 * Listing of USB host controllers.
    3535 */
     36
     37#include <inttypes.h>
     38#include <stdio.h>
     39#include <stdlib.h>
    3640#include <errno.h>
    37 #include <usb/descriptor.h>
    38 #include "stdreq.h"
    39 #include "kbdconfig.h"
     41#include <str_error.h>
     42#include <bool.h>
     43#include <getopt.h>
     44#include <devman.h>
     45#include <devmap.h>
     46#include <usb/host.h>
    4047
    41 int req_get_descriptor(usbvirt_device_t *device,
    42     const usb_device_request_setup_packet_t *setup_packet,
    43     uint8_t *data, size_t *act_size)
     48#define NAME "lsusb"
     49
     50#define MAX_FAILED_ATTEMPTS 4
     51#define MAX_PATH_LENGTH 1024
     52
     53int main(int argc, char *argv[])
    4454{
    45         if (setup_packet->value_high == USB_DESCTYPE_HID_REPORT) {
    46                 /*
    47                  * For simplicity, always return the same
    48                  * report descriptor.
    49                  */
    50                 usbvirt_control_reply_helper(setup_packet,
    51                     data, act_size,
    52                     report_descriptor, report_descriptor_size);
     55        size_t class_index = 0;
     56        size_t failed_attempts = 0;
    5357
    54                 return EOK;
     58        while (failed_attempts < MAX_FAILED_ATTEMPTS) {
     59                class_index++;
     60                devman_handle_t hc_handle = 0;
     61                int rc = usb_ddf_get_hc_handle_by_class(class_index, &hc_handle);
     62                if (rc != EOK) {
     63                        failed_attempts++;
     64                        continue;
     65                }
     66                char path[MAX_PATH_LENGTH];
     67                rc = devman_get_device_path(hc_handle, path, MAX_PATH_LENGTH);
     68                if (rc != EOK) {
     69                        continue;
     70                }
     71                printf(NAME ": host controller %zu is `%s'.\n",
     72                    class_index, path);
    5573        }
    56        
    57         /* Let the framework handle all the rest. */
    58         return EFORWARD;
     74
     75        return 0;
    5976}
    60 
    6177
    6278
  • uspace/app/usbinfo/main.c

    rbd2394b rcc5908e  
    4545#include <usb/usbdevice.h>
    4646#include <usb/pipes.h>
     47#include <usb/host.h>
    4748#include "usbinfo.h"
     49
     50static bool try_parse_class_and_address(const char *path,
     51    devman_handle_t *out_hc_handle, usb_address_t *out_device_address)
     52{
     53        size_t class_index;
     54        size_t address;
     55        int rc;
     56        char *ptr;
     57
     58        rc = str_size_t(path, &ptr, 10, false, &class_index);
     59        if (rc != EOK) {
     60                return false;
     61        }
     62        if ((*ptr == ':') || (*ptr == '.')) {
     63                ptr++;
     64        } else {
     65                return false;
     66        }
     67        rc = str_size_t(ptr, NULL, 10, true, &address);
     68        if (rc != EOK) {
     69                return false;
     70        }
     71        rc = usb_ddf_get_hc_handle_by_class(class_index, out_hc_handle);
     72        if (rc != EOK) {
     73                return false;
     74        }
     75        if (out_device_address != NULL) {
     76                *out_device_address = (usb_address_t) address;
     77        }
     78        return true;
     79}
    4880
    4981static bool resolve_hc_handle_and_dev_addr(const char *devpath,
     
    6092        if (str_cmp(devpath, "virt") == 0) {
    6193                devpath = "/virt/usbhc/usb00_a1/usb00_a2";
     94        }
     95
     96        if (try_parse_class_and_address(devpath,
     97            out_hc_handle, out_device_address)) {
     98                return true;
    6299        }
    63100
  • uspace/app/vuhid/device.c

    rbd2394b rcc5908e  
    7777{
    7878        vuhid_interface_t *iface = arg;
     79        vuhid_data_t *hid_data = iface->vuhid_data;
    7980
    8081        if (iface->live != NULL) {
    8182                iface->live(iface);
    8283        }
     84
     85        fibril_mutex_lock(&hid_data->iface_count_mutex);
     86        hid_data->iface_died_count++;
     87        fibril_condvar_broadcast(&hid_data->iface_count_cv);
     88        fibril_mutex_unlock(&hid_data->iface_count_mutex);
    8389
    8490        return EOK;
     
    110116        if ((iface->in_data_size == 0) && (iface->out_data_size == 0)) {
    111117                return EEMPTY;
     118        }
     119
     120        // FIXME - we shall set vuhid_data to NULL in the main() rather
     121        // than to depend on individual interfaces
     122        /* Already used interface. */
     123        if (iface->vuhid_data != NULL) {
     124                return EEXISTS;
    112125        }
    113126
     
    252265
    253266        /* Launch the "life" fibril. */
     267        iface->vuhid_data = hid_data;
    254268        fid_t life_fibril = fibril_create(interface_life_fibril, iface);
    255269        if (life_fibril == 0) {
     
    310324            += total_descr_size;
    311325
     326        hid_data->iface_count++;
    312327        fibril_add_ready(life_fibril);
    313328
     
    331346}
    332347
     348void wait_for_interfaces_death(usbvirt_device_t *dev)
     349{
     350        vuhid_data_t *hid_data = dev->device_data;
     351
     352        fibril_mutex_lock(&hid_data->iface_count_mutex);
     353        while (hid_data->iface_died_count < hid_data->iface_count) {
     354                fibril_condvar_wait(&hid_data->iface_count_cv,
     355                    &hid_data->iface_count_mutex);
     356        }
     357        fibril_mutex_unlock(&hid_data->iface_count_mutex);
     358}
    333359
    334360/** @}
  • uspace/app/vuhid/hids/bootkbd.c

    rbd2394b rcc5908e  
    3939#include <usb/classes/hidut.h>
    4040
    41 #include "../../virtusbkbd/report.h"
     41#include "../report.h"
    4242
    4343uint8_t report_descriptor[] = {
     
    169169        .on_data_out = on_data_out,
    170170
    171         .live = live
     171        .live = live,
     172
     173        .vuhid_data = NULL
    172174};
    173175
  • uspace/app/vuhid/main.c

    rbd2394b rcc5908e  
    132132        .in_endpoint_first_free = 1,
    133133        .out_endpoints_mapping = { NULL },
    134         .out_endpoint_first_free = 1
    135 };
     134        .out_endpoint_first_free = 1,
     135
     136        .iface_count = 0,
     137        .iface_died_count = 0
     138        // mutex and CV must be initialized elsewhere
     139};
     140
    136141
    137142/** Keyboard device.
     
    151156
    152157        usb_log_enable(USB_LOG_LEVEL_DEBUG2, "vusbhid");
     158
     159        fibril_mutex_initialize(&vuhid_data.iface_count_mutex);
     160        fibril_condvar_initialize(&vuhid_data.iface_count_cv);
    153161
    154162        /* Determine which interfaces to initialize. */
     
    182190        printf("Connected to VHCD...\n");
    183191
    184         while (true) {
    185                 async_usleep(10 * 1000 * 1000);
    186         }
     192        wait_for_interfaces_death(&hid_dev);
    187193       
    188194        printf("Terminating...\n");
    189195       
     196        usbvirt_device_unplug(&hid_dev);
     197
    190198        return 0;
    191199}
  • uspace/app/vuhid/virthid.h

    rbd2394b rcc5908e  
    3838#include <usb/usb.h>
    3939#include <usbvirt/device.h>
     40#include <fibril_synch.h>
    4041
    4142#define VUHID_ENDPOINT_MAX USB11_ENDPOINT_MAX
     
    4344
    4445typedef struct vuhid_interface vuhid_interface_t;
     46
     47typedef struct {
     48        vuhid_interface_t *in_endpoints_mapping[VUHID_ENDPOINT_MAX];
     49        size_t in_endpoint_first_free;
     50        vuhid_interface_t *out_endpoints_mapping[VUHID_ENDPOINT_MAX];
     51        size_t out_endpoint_first_free;
     52        vuhid_interface_t *interface_mapping[VUHID_INTERFACE_MAX];
     53
     54        fibril_mutex_t iface_count_mutex;
     55        fibril_condvar_t iface_count_cv;
     56        size_t iface_count;
     57        size_t iface_died_count;
     58} vuhid_data_t;
    4559
    4660struct vuhid_interface {
     
    6377
    6478        void *interface_data;
     79
     80        vuhid_data_t *vuhid_data;
    6581};
    66 
    67 typedef struct {
    68         vuhid_interface_t *in_endpoints_mapping[VUHID_ENDPOINT_MAX];
    69         size_t in_endpoint_first_free;
    70         vuhid_interface_t *out_endpoints_mapping[VUHID_ENDPOINT_MAX];
    71         size_t out_endpoint_first_free;
    72         vuhid_interface_t *interface_mapping[VUHID_INTERFACE_MAX];
    73 } vuhid_data_t;
    7482
    7583typedef struct {
     
    8492
    8593int add_interface_by_id(vuhid_interface_t **, const char *, usbvirt_device_t *);
     94void wait_for_interfaces_death(usbvirt_device_t *);
    8695
    8796#endif
  • uspace/doc/doxygroups.h

    rbd2394b rcc5908e  
    220220
    221221        /**
     222         * @defgroup lsusb HelenOS version of lsusb command
     223         * @ingroup usb
     224         * @brief Application for listing USB host controllers.
     225         * @details
     226         * List all found host controllers.
     227         */
     228
     229        /**
    222230         * @defgroup drvusbmid USB multi interface device driver
    223231         * @ingroup usb
  • uspace/drv/ehci-hcd/main.c

    rbd2394b rcc5908e  
    9797        }
    9898        hc_fun->ops = &hc_ops;
     99
    99100        ret = ddf_fun_bind(hc_fun);
    100 
    101101        CHECK_RET_RETURN(ret,
    102102            "Failed to bind EHCI function: %s.\n",
     103            str_error(ret));
     104        ret = ddf_fun_add_to_class(hc_fun, USB_HC_DDF_CLASS_NAME);
     105        CHECK_RET_RETURN(ret,
     106            "Failed to add EHCI to HC class: %s.\n",
    103107            str_error(ret));
    104108
  • uspace/drv/ohci/hc.c

    rbd2394b rcc5908e  
    4949static int interrupt_emulator(hc_t *instance);
    5050static void hc_gain_control(hc_t *instance);
    51 static void hc_init_hw(hc_t *instance);
    5251static int hc_init_transfer_lists(hc_t *instance);
    5352static int hc_init_memory(hc_t *instance);
     
    9291                usb_log_error("Failed add root hub match-id.\n");
    9392        }
     93        ret = ddf_fun_bind(hub_fun);
    9494        return ret;
    9595}
     
    111111            ret, str_error(ret));
    112112
     113        list_initialize(&instance->pending_batches);
    113114        usb_device_keeper_init(&instance->manager);
    114115        ret = usb_endpoint_manager_init(&instance->ep_manager,
     
    117118            str_error(ret));
    118119
    119         hc_gain_control(instance);
    120120        ret = hc_init_memory(instance);
    121121        CHECK_RET_RETURN(ret, "Failed to create OHCI memory structures: %s.\n",
    122122            str_error(ret));
    123         hc_init_hw(instance);
     123#undef CHECK_RET_RETURN
     124
     125
     126//      hc_init_hw(instance);
     127        hc_gain_control(instance);
    124128        fibril_mutex_initialize(&instance->guard);
    125129
     
    132136        }
    133137
    134         list_initialize(&instance->pending_batches);
    135 #undef CHECK_RET_RETURN
    136138        return EOK;
    137139}
     
    287289{
    288290        assert(instance);
    289         usb_log_debug("OHCI interrupt: %x.\n", status);
     291        usb_log_debug("OHCI(%p) interrupt: %x.\n", instance, status);
    290292        if ((status & ~I_SF) == 0) /* ignore sof status */
    291293                return;
     
    339341            (uint32_t*)((char*)instance->registers + 0x100);
    340342        usb_log_debug("OHCI legacy register %p: %x.\n",
    341                 ohci_emulation_reg, *ohci_emulation_reg);
    342         *ohci_emulation_reg &= ~0x1;
     343            ohci_emulation_reg, *ohci_emulation_reg);
     344        /* Do not change A20 state */
     345        *ohci_emulation_reg &= 0x100;
     346        usb_log_debug("OHCI legacy register %p: %x.\n",
     347            ohci_emulation_reg, *ohci_emulation_reg);
    343348
    344349        /* Interrupt routing enabled => smm driver is active */
     
    350355                }
    351356                usb_log_info("SMM driver: Ownership taken.\n");
     357                instance->registers->control &= (C_HCFS_RESET << C_HCFS_SHIFT);
     358                async_usleep(50000);
    352359                return;
    353360        }
     
    375382}
    376383/*----------------------------------------------------------------------------*/
    377 void hc_init_hw(hc_t *instance)
     384void hc_start_hw(hc_t *instance)
    378385{
    379386        /* OHCI guide page 42 */
     
    474481{
    475482        assert(instance);
     483
     484        bzero(&instance->rh, sizeof(instance->rh));
    476485        /* Init queues */
    477486        hc_init_transfer_lists(instance);
  • uspace/drv/ohci/hc.h

    rbd2394b rcc5908e  
    8080     uintptr_t regs, size_t reg_size, bool interrupts);
    8181
     82void hc_start_hw(hc_t *instance);
     83
    8284/** Safely dispose host controller internal structures
    8385 *
  • uspace/drv/ohci/main.c

    rbd2394b rcc5908e  
    7575                return ret;
    7676        }
    77         device->driver_data = ohci;
     77//      device->driver_data = ohci;
     78        hc_register_hub(&ohci->hc, ohci->rh_fun);
    7879
    7980        usb_log_info("Controlling new OHCI device `%s'.\n", device->name);
     
    9394{
    9495        usb_log_enable(USB_LOG_LEVEL_DEFAULT, NAME);
    95         sleep(5);
    9696        return ddf_driver_main(&ohci_driver);
    9797}
  • uspace/drv/ohci/ohci.c

    rbd2394b rcc5908e  
    5454{
    5555        assert(dev);
     56        assert(dev->driver_data);
    5657        hc_t *hc = &((ohci_t*)dev->driver_data)->hc;
    5758        uint16_t status = IPC_GET_ARG1(*call);
     
    152153        usb_log_debug("Memory mapped regs at %p (size %zu), IRQ %d.\n",
    153154            (void *) mem_reg_base, mem_reg_size, irq);
    154 
    155         ret = pci_disable_legacy(device);
    156         CHECK_RET_DEST_FUN_RETURN(ret,
    157             "Failed(%d) to disable legacy USB: %s.\n", ret, str_error(ret));
    158155
    159156        bool interrupts = false;
     
    188185            "Failed(%d) to bind OHCI device function: %s.\n",
    189186            ret, str_error(ret));
     187        ret = ddf_fun_add_to_class(instance->hc_fun, USB_HC_DDF_CLASS_NAME);
     188        CHECK_RET_DEST_FUN_RETURN(ret,
     189            "Failed to add OHCI to HC class: %s.\n", str_error(ret));
     190
    190191#undef CHECK_RET_HC_RETURN
    191192
     
    212213            "Failed(%d) to create root hub function.\n", ret);
    213214
    214         hc_register_hub(&instance->hc, instance->rh_fun);
    215215
    216216        instance->rh_fun->ops = &rh_ops;
    217217        instance->rh_fun->driver_data = NULL;
    218         ret = ddf_fun_bind(instance->rh_fun);
    219         CHECK_RET_FINI_RETURN(ret,
    220             "Failed(%d) to register OHCI root hub.\n", ret);
    221 
     218       
     219        device->driver_data = instance;
     220
     221        hc_start_hw(&instance->hc);
    222222        return EOK;
    223223#undef CHECK_RET_FINI_RETURN
  • uspace/drv/ohci/pci.c

    rbd2394b rcc5908e  
    136136        return enabled ? EOK : EIO;
    137137}
    138 /*----------------------------------------------------------------------------*/
    139 /** Implements BIOS handoff routine as decribed in OHCI spec
    140  *
    141  * @param[in] device Device asking for interrupts
    142  * @return Error code.
    143  */
    144 int pci_disable_legacy(ddf_dev_t *device)
    145 {
    146         /* TODO: implement */
    147         return EOK;
    148 }
    149 /*----------------------------------------------------------------------------*/
    150138/**
    151139 * @}
  • uspace/drv/ohci/root_hub.c

    rbd2394b rcc5908e  
    4545
    4646/**
    47  *      standart device descriptor for ohci root hub
     47 * standart device descriptor for ohci root hub
    4848 */
    4949static const usb_standard_device_descriptor_t ohci_rh_device_descriptor = {
     
    6969 */
    7070static const usb_standard_configuration_descriptor_t ohci_rh_conf_descriptor = {
    71         /// \TODO some values are default or guessed
    7271        .attributes = 1 << 7,
    7372        .configuration_number = 1,
     
    8786        .endpoint_count = 1,
    8887        .interface_class = USB_CLASS_HUB,
    89         /// \TODO is this correct?
    9088        .interface_number = 1,
    9189        .interface_protocol = 0,
     
    107105};
    108106
     107/**
     108 * bitmask of hub features that are valid to be cleared
     109 */
    109110static const uint32_t hub_clear_feature_valid_mask =
    110         (1 << USB_HUB_FEATURE_C_HUB_LOCAL_POWER) |
     111    (1 << USB_HUB_FEATURE_C_HUB_LOCAL_POWER) |
    111112(1 << USB_HUB_FEATURE_C_HUB_OVER_CURRENT);
    112113
     114/**
     115 * bitmask of hub features that are cleared by writing 1 (and not 0)
     116 */
    113117static const uint32_t hub_clear_feature_by_writing_one_mask =
    114         1 << USB_HUB_FEATURE_C_HUB_LOCAL_POWER;
    115 
     118    1 << USB_HUB_FEATURE_C_HUB_LOCAL_POWER;
     119
     120/**
     121 * bitmask of hub features that are valid to be set
     122 */
    116123static const uint32_t hub_set_feature_valid_mask =
    117         (1 << USB_HUB_FEATURE_C_HUB_OVER_CURRENT) |
     124    (1 << USB_HUB_FEATURE_C_HUB_OVER_CURRENT) |
    118125(1 << USB_HUB_FEATURE_C_HUB_LOCAL_POWER);
    119126
    120 
     127/**
     128 * bitmask of hub features that are set by writing 1 and cleared by writing 0
     129 */
    121130static const uint32_t hub_set_feature_direct_mask =
    122         (1 << USB_HUB_FEATURE_C_HUB_OVER_CURRENT);
    123 
     131    (1 << USB_HUB_FEATURE_C_HUB_OVER_CURRENT);
     132
     133/**
     134 * bitmask of port features that are valid to be set
     135 */
    124136static const uint32_t port_set_feature_valid_mask =
    125         (1 << USB_HUB_FEATURE_PORT_ENABLE) |
     137    (1 << USB_HUB_FEATURE_PORT_ENABLE) |
    126138(1 << USB_HUB_FEATURE_PORT_SUSPEND) |
    127139(1 << USB_HUB_FEATURE_PORT_RESET) |
    128140(1 << USB_HUB_FEATURE_PORT_POWER);
    129141
     142/**
     143 * bitmask of port features that can be cleared
     144 */
    130145static const uint32_t port_clear_feature_valid_mask =
    131         (1 << USB_HUB_FEATURE_PORT_CONNECTION) |
     146    (1 << USB_HUB_FEATURE_PORT_CONNECTION) |
    132147(1 << USB_HUB_FEATURE_PORT_SUSPEND) |
    133148(1 << USB_HUB_FEATURE_PORT_OVER_CURRENT) |
     
    141156//USB_HUB_FEATURE_PORT_LOW_SPEED
    142157
     158/**
     159 * bitmask with port status changes
     160 */
    143161static const uint32_t port_status_change_mask =
    144 (1<< USB_HUB_FEATURE_C_PORT_CONNECTION) |
    145 (1<< USB_HUB_FEATURE_C_PORT_ENABLE) |
    146 (1<< USB_HUB_FEATURE_C_PORT_OVER_CURRENT) |
    147 (1<< USB_HUB_FEATURE_C_PORT_RESET) |
    148 (1<< USB_HUB_FEATURE_C_PORT_SUSPEND);
     162    (1 << USB_HUB_FEATURE_C_PORT_CONNECTION) |
     163(1 << USB_HUB_FEATURE_C_PORT_ENABLE) |
     164(1 << USB_HUB_FEATURE_C_PORT_OVER_CURRENT) |
     165(1 << USB_HUB_FEATURE_C_PORT_RESET) |
     166(1 << USB_HUB_FEATURE_C_PORT_SUSPEND);
    149167
    150168
     
    154172
    155173static int process_get_port_status_request(rh_t *instance, uint16_t port,
    156         usb_transfer_batch_t * request);
     174    usb_transfer_batch_t * request);
    157175
    158176static int process_get_hub_status_request(rh_t *instance,
    159         usb_transfer_batch_t * request);
     177    usb_transfer_batch_t * request);
    160178
    161179static int process_get_status_request(rh_t *instance,
    162         usb_transfer_batch_t * request);
     180    usb_transfer_batch_t * request);
    163181
    164182static void create_interrupt_mask_in_instance(rh_t *instance);
    165183
    166184static int process_get_descriptor_request(rh_t *instance,
    167         usb_transfer_batch_t *request);
     185    usb_transfer_batch_t *request);
    168186
    169187static int process_get_configuration_request(rh_t *instance,
    170         usb_transfer_batch_t *request);
     188    usb_transfer_batch_t *request);
    171189
    172190static int process_hub_feature_set_request(rh_t *instance, uint16_t feature);
    173191
    174192static int process_hub_feature_clear_request(rh_t *instance,
    175         uint16_t feature);
     193    uint16_t feature);
    176194
    177195static int process_port_feature_set_request(rh_t *instance,
    178         uint16_t feature, uint16_t port);
     196    uint16_t feature, uint16_t port);
    179197
    180198static int process_port_feature_clear_request(rh_t *instance,
    181         uint16_t feature, uint16_t port);
     199    uint16_t feature, uint16_t port);
    182200
    183201static int process_address_set_request(rh_t *instance,
    184         uint16_t address);
     202    uint16_t address);
    185203
    186204static int process_request_with_output(rh_t *instance,
    187         usb_transfer_batch_t *request);
     205    usb_transfer_batch_t *request);
    188206
    189207static int process_request_with_input(rh_t *instance,
    190         usb_transfer_batch_t *request);
     208    usb_transfer_batch_t *request);
    191209
    192210static int process_request_without_data(rh_t *instance,
    193         usb_transfer_batch_t *request);
     211    usb_transfer_batch_t *request);
    194212
    195213static int process_ctrl_request(rh_t *instance, usb_transfer_batch_t *request);
     
    198216
    199217static bool is_zeros(void * buffer, size_t size);
    200 
    201 
    202218
    203219/** Root hub initialization
     
    210226            (instance->registers->rh_desc_a >> RHDA_NDS_SHIFT) & RHDA_NDS_MASK;
    211227        int opResult = rh_init_descriptors(instance);
    212         if(opResult != EOK){
     228        if (opResult != EOK) {
    213229                return opResult;
    214230        }
     
    216232        instance->registers->rh_desc_a |= RHDA_NPS_FLAG;
    217233        instance->unfinished_interrupt_transfer = NULL;
    218         instance->interrupt_mask_size = (instance->port_count + 8)/8;
     234        instance->interrupt_mask_size = (instance->port_count + 8) / 8;
    219235        instance->interrupt_buffer = malloc(instance->interrupt_mask_size);
    220         if(!instance->interrupt_buffer)
     236        if (!instance->interrupt_buffer)
    221237                return ENOMEM;
    222        
    223 
    224         usb_log_info("OHCI root hub with %d ports.\n", instance->port_count);
     238
     239        usb_log_info("OHCI root hub with %d ports initialized.\n",
     240            instance->port_count);
     241
    225242        return EOK;
    226243}
     
    245262                usb_log_info("Root hub got INTERRUPT packet\n");
    246263                create_interrupt_mask_in_instance(instance);
    247                 if(is_zeros(instance->interrupt_buffer,
    248                     instance->interrupt_mask_size)){
     264                if (is_zeros(instance->interrupt_buffer,
     265                    instance->interrupt_mask_size)) {
    249266                        usb_log_debug("no changes..\n");
    250267                        instance->unfinished_interrupt_transfer = request;
    251268                        //will be finished later
    252                 }else{
     269                } else {
    253270                        usb_log_debug("processing changes..\n");
    254271                        process_interrupt_mask_in_instance(instance, request);
     
    256273                opResult = EOK;
    257274        } else {
     275
    258276                opResult = EINVAL;
    259277                usb_transfer_batch_finish_error(request, opResult);
     
    271289 */
    272290void rh_interrupt(rh_t *instance) {
    273         if(!instance->unfinished_interrupt_transfer){
     291        if (!instance->unfinished_interrupt_transfer) {
    274292                return;
    275293        }
     
    292310static int create_serialized_hub_descriptor(rh_t *instance) {
    293311        size_t size = 7 +
    294             ((instance->port_count +7 )/ 8) * 2;
    295         size_t var_size = (instance->port_count +7 )/ 8;
     312            ((instance->port_count + 7) / 8) * 2;
     313        size_t var_size = (instance->port_count + 7) / 8;
    296314        uint8_t * result = (uint8_t*) malloc(size);
    297         if(!result) return ENOMEM;
     315        if (!result) return ENOMEM;
    298316
    299317        bzero(result, size);
     
    305323        uint32_t hub_desc_reg = instance->registers->rh_desc_a;
    306324        result[3] =
    307                 ((hub_desc_reg >> 8) % 2) +
    308                 (((hub_desc_reg >> 9) % 2) << 1) +
    309                 (((hub_desc_reg >> 10) % 2) << 2) +
    310                 (((hub_desc_reg >> 11) % 2) << 3) +
    311                 (((hub_desc_reg >> 12) % 2) << 4);
     325            ((hub_desc_reg >> 8) % 2) +
     326            (((hub_desc_reg >> 9) % 2) << 1) +
     327            (((hub_desc_reg >> 10) % 2) << 2) +
     328            (((hub_desc_reg >> 11) % 2) << 3) +
     329            (((hub_desc_reg >> 12) % 2) << 4);
    312330        result[4] = 0;
    313331        result[5] = /*descriptor->pwr_on_2_good_time*/ 50;
    314332        result[6] = 50;
    315333
    316         int port;
     334        size_t port;
    317335        for (port = 1; port <= instance->port_count; ++port) {
    318336                uint8_t is_non_removable =
    319                         instance->registers->rh_desc_b >> port % 2;
     337                    instance->registers->rh_desc_b >> port % 2;
    320338                result[7 + port / 8] +=
    321                         is_non_removable << (port % 8);
     339                    is_non_removable << (port % 8);
    322340        }
    323341        size_t i;
     
    327345        instance->hub_descriptor = result;
    328346        instance->descriptor_size = size;
     347
    329348        return EOK;
    330349}
     
    340359static int rh_init_descriptors(rh_t *instance) {
    341360        memcpy(&instance->descriptors.device, &ohci_rh_device_descriptor,
    342                 sizeof (ohci_rh_device_descriptor)
    343                 );
     361            sizeof (ohci_rh_device_descriptor)
     362            );
    344363        usb_standard_configuration_descriptor_t descriptor;
    345364        memcpy(&descriptor, &ohci_rh_conf_descriptor,
    346                 sizeof (ohci_rh_conf_descriptor));
     365            sizeof (ohci_rh_conf_descriptor));
    347366
    348367        int opResult = create_serialized_hub_descriptor(instance);
    349         if(opResult != EOK){
     368        if (opResult != EOK) {
    350369                return opResult;
    351370        }
    352371        descriptor.total_length =
    353                 sizeof (usb_standard_configuration_descriptor_t) +
    354                 sizeof (usb_standard_endpoint_descriptor_t) +
    355                 sizeof (usb_standard_interface_descriptor_t) +
    356                 instance->descriptor_size;
     372            sizeof (usb_standard_configuration_descriptor_t) +
     373            sizeof (usb_standard_endpoint_descriptor_t) +
     374            sizeof (usb_standard_interface_descriptor_t) +
     375            instance->descriptor_size;
    357376
    358377        uint8_t * full_config_descriptor =
    359                 (uint8_t*) malloc(descriptor.total_length);
    360         if(!full_config_descriptor){
     378            (uint8_t*) malloc(descriptor.total_length);
     379        if (!full_config_descriptor) {
    361380                return ENOMEM;
    362381        }
    363382        memcpy(full_config_descriptor, &descriptor, sizeof (descriptor));
    364383        memcpy(full_config_descriptor + sizeof (descriptor),
    365                 &ohci_rh_iface_descriptor, sizeof (ohci_rh_iface_descriptor));
     384            &ohci_rh_iface_descriptor, sizeof (ohci_rh_iface_descriptor));
    366385        memcpy(full_config_descriptor + sizeof (descriptor) +
    367                 sizeof (ohci_rh_iface_descriptor),
    368                 &ohci_rh_ep_descriptor, sizeof (ohci_rh_ep_descriptor));
     386            sizeof (ohci_rh_iface_descriptor),
     387            &ohci_rh_ep_descriptor, sizeof (ohci_rh_ep_descriptor));
    369388        memcpy(full_config_descriptor + sizeof (descriptor) +
    370                 sizeof (ohci_rh_iface_descriptor) +
    371                 sizeof (ohci_rh_ep_descriptor),
    372                 instance->hub_descriptor, instance->descriptor_size);
    373        
     389            sizeof (ohci_rh_iface_descriptor) +
     390            sizeof (ohci_rh_ep_descriptor),
     391            instance->hub_descriptor, instance->descriptor_size);
     392
    374393        instance->descriptors.configuration = full_config_descriptor;
    375394        instance->descriptors.configuration_size = descriptor.total_length;
     395
    376396        return EOK;
    377397}
     
    389409 */
    390410static int process_get_port_status_request(rh_t *instance, uint16_t port,
    391         usb_transfer_batch_t * request) {
     411    usb_transfer_batch_t * request) {
    392412        if (port < 1 || port > instance->port_count)
    393413                return EINVAL;
     
    398418        int i;
    399419        for (i = 0; i < instance->port_count; ++i) {
     420
    400421                usb_log_debug("port status %d,x%x\n",
    401                         instance->registers->rh_port_status[i],
    402                         instance->registers->rh_port_status[i]);
     422                    instance->registers->rh_port_status[i],
     423                    instance->registers->rh_port_status[i]);
    403424        }
    404425#endif
     
    417438 */
    418439static int process_get_hub_status_request(rh_t *instance,
    419         usb_transfer_batch_t * request) {
     440    usb_transfer_batch_t * request) {
    420441        uint32_t * uint32_buffer = (uint32_t*) request->data_buffer;
    421442        request->transfered_size = 4;
     
    423444        uint32_t mask = 1 | (1 << 1) | (1 << 16) | (1 << 17);
    424445        uint32_buffer[0] = mask & instance->registers->rh_status;
     446
    425447        return EOK;
    426448}
     
    437459 */
    438460static int process_get_status_request(rh_t *instance,
    439         usb_transfer_batch_t * request) {
     461    usb_transfer_batch_t * request) {
    440462        size_t buffer_size = request->buffer_size;
    441463        usb_device_request_setup_packet_t * request_packet =
    442                 (usb_device_request_setup_packet_t*)
    443                 request->setup_buffer;
     464            (usb_device_request_setup_packet_t*)
     465            request->setup_buffer;
    444466
    445467        usb_hub_bm_request_type_t request_type = request_packet->request_type;
     
    453475        if (request_type == USB_HUB_REQ_TYPE_GET_PORT_STATUS)
    454476                return process_get_port_status_request(instance,
    455                 request_packet->index,
    456                 request);
     477            request_packet->index,
     478            request);
     479
    457480        return ENOTSUP;
    458481}
     
    472495        uint8_t * bitmap = (uint8_t*) (instance->interrupt_buffer);
    473496        uint32_t mask = (1 << (USB_HUB_FEATURE_C_HUB_LOCAL_POWER + 16))
    474                 | (1 << (USB_HUB_FEATURE_C_HUB_OVER_CURRENT + 16));
     497            | (1 << (USB_HUB_FEATURE_C_HUB_OVER_CURRENT + 16));
    475498        bzero(bitmap, instance->interrupt_mask_size);
    476499        if (instance->registers->rh_status & mask) {
    477500                bitmap[0] = 1;
    478501        }
    479         int port;
     502        size_t port;
    480503        mask = port_status_change_mask;
    481504        for (port = 1; port <= instance->port_count; ++port) {
    482505                if (mask & instance->registers->rh_port_status[port - 1]) {
     506
    483507                        bitmap[(port) / 8] += 1 << (port % 8);
    484508                }
     
    497521 */
    498522static int process_get_descriptor_request(rh_t *instance,
    499         usb_transfer_batch_t *request) {
     523    usb_transfer_batch_t *request) {
    500524        usb_device_request_setup_packet_t * setup_request =
    501                 (usb_device_request_setup_packet_t*) request->setup_buffer;
     525            (usb_device_request_setup_packet_t*) request->setup_buffer;
    502526        size_t size;
    503527        const void * result_descriptor = NULL;
     
    543567                {
    544568                        usb_log_debug("USB_DESCTYPE_EINVAL %d \n",
    545                                 setup_request->value);
     569                            setup_request->value);
    546570                        usb_log_debug("\ttype %d\n\trequest %d\n\tvalue "
    547                                 "%d\n\tindex %d\n\tlen %d\n ",
    548                                 setup_request->request_type,
    549                                 setup_request->request,
    550                                 setup_request_value,
    551                                 setup_request->index,
    552                                 setup_request->length
    553                                 );
     571                            "%d\n\tindex %d\n\tlen %d\n ",
     572                            setup_request->request_type,
     573                            setup_request->request,
     574                            setup_request_value,
     575                            setup_request->index,
     576                            setup_request->length
     577                            );
    554578                        return EINVAL;
    555579                }
     
    560584        request->transfered_size = size;
    561585        memcpy(request->data_buffer, result_descriptor, size);
     586
    562587        return EOK;
    563588}
     
    573598 */
    574599static int process_get_configuration_request(rh_t *instance,
    575         usb_transfer_batch_t *request) {
     600    usb_transfer_batch_t *request) {
    576601        //set and get configuration requests do not have any meaning, only dummy
    577602        //values are returned
     
    580605        request->data_buffer[0] = 1;
    581606        request->transfered_size = 1;
     607
    582608        return EOK;
    583609}
     
    592618 */
    593619static int process_hub_feature_set_request(rh_t *instance,
    594         uint16_t feature) {
     620    uint16_t feature) {
    595621        if (!((1 << feature) & hub_set_feature_valid_mask))
    596622                return EINVAL;
    597         if(feature == USB_HUB_FEATURE_C_HUB_LOCAL_POWER)
     623        if (feature == USB_HUB_FEATURE_C_HUB_LOCAL_POWER)
    598624                feature = USB_HUB_FEATURE_C_HUB_LOCAL_POWER << 16;
    599625        instance->registers->rh_status =
    600                 (instance->registers->rh_status | (1 << feature))
    601                 & (~hub_clear_feature_by_writing_one_mask);
     626            (instance->registers->rh_status | (1 << feature))
     627            & (~hub_clear_feature_by_writing_one_mask);
     628
    602629        return EOK;
    603630}
     
    612639 */
    613640static int process_hub_feature_clear_request(rh_t *instance,
    614         uint16_t feature) {
     641    uint16_t feature) {
    615642        if (!((1 << feature) & hub_clear_feature_valid_mask))
    616643                return EINVAL;
     
    618645        if ((1 << feature) & hub_set_feature_direct_mask) {
    619646                instance->registers->rh_status =
    620                         (instance->registers->rh_status & (~(1 << feature)))
    621                         & (~hub_clear_feature_by_writing_one_mask);
     647                    (instance->registers->rh_status & (~(1 << feature)))
     648                    & (~hub_clear_feature_by_writing_one_mask);
    622649        } else {//the feature is cleared by writing '1'
     650
    623651                instance->registers->rh_status =
    624                         (instance->registers->rh_status
    625                         & (~hub_clear_feature_by_writing_one_mask))
    626                         | (1 << feature);
     652                    (instance->registers->rh_status
     653                    & (~hub_clear_feature_by_writing_one_mask))
     654                    | (1 << feature);
    627655        }
    628656        return EOK;
     
    640668 */
    641669static int process_port_feature_set_request(rh_t *instance,
    642         uint16_t feature, uint16_t port) {
     670    uint16_t feature, uint16_t port) {
    643671        if (!((1 << feature) & port_set_feature_valid_mask))
    644672                return EINVAL;
     
    646674                return EINVAL;
    647675        instance->registers->rh_port_status[port - 1] =
    648                 (instance->registers->rh_port_status[port - 1] | (1 << feature))
    649                 & (~port_clear_feature_valid_mask);
     676            (instance->registers->rh_port_status[port - 1] | (1 << feature))
     677            & (~port_clear_feature_valid_mask);
    650678        /// \TODO any error?
     679
    651680        return EOK;
    652681}
     
    663692 */
    664693static int process_port_feature_clear_request(rh_t *instance,
    665         uint16_t feature, uint16_t port) {
     694    uint16_t feature, uint16_t port) {
    666695        if (!((1 << feature) & port_clear_feature_valid_mask))
    667696                return EINVAL;
     
    673702                feature = USB_HUB_FEATURE_PORT_OVER_CURRENT;
    674703        instance->registers->rh_port_status[port - 1] =
    675                 (instance->registers->rh_port_status[port - 1]
    676                 & (~port_clear_feature_valid_mask))
    677                 | (1 << feature);
     704            (instance->registers->rh_port_status[port - 1]
     705            & (~port_clear_feature_valid_mask))
     706            | (1 << feature);
    678707        /// \TODO any error?
     708
    679709        return EOK;
    680710}
     
    689719 */
    690720static int process_address_set_request(rh_t *instance,
    691         uint16_t address) {
     721    uint16_t address) {
    692722        instance->address = address;
     723
    693724        return EOK;
    694725}
     
    705736 */
    706737static int process_request_with_output(rh_t *instance,
    707         usb_transfer_batch_t *request) {
     738    usb_transfer_batch_t *request) {
    708739        usb_device_request_setup_packet_t * setup_request =
    709                 (usb_device_request_setup_packet_t*) request->setup_buffer;
     740            (usb_device_request_setup_packet_t*) request->setup_buffer;
    710741        if (setup_request->request == USB_DEVREQ_GET_STATUS) {
    711742                usb_log_debug("USB_DEVREQ_GET_STATUS\n");
     
    718749        if (setup_request->request == USB_DEVREQ_GET_CONFIGURATION) {
    719750                usb_log_debug("USB_DEVREQ_GET_CONFIGURATION\n");
     751
    720752                return process_get_configuration_request(instance, request);
    721753        }
     
    734766 */
    735767static int process_request_with_input(rh_t *instance,
    736         usb_transfer_batch_t *request) {
     768    usb_transfer_batch_t *request) {
    737769        usb_device_request_setup_packet_t * setup_request =
    738                 (usb_device_request_setup_packet_t*) request->setup_buffer;
     770            (usb_device_request_setup_packet_t*) request->setup_buffer;
    739771        request->transfered_size = 0;
    740772        if (setup_request->request == USB_DEVREQ_SET_DESCRIPTOR) {
     
    744776                //set and get configuration requests do not have any meaning,
    745777                //only dummy values are returned
     778
    746779                return EOK;
    747780        }
     
    760793 */
    761794static int process_request_without_data(rh_t *instance,
    762         usb_transfer_batch_t *request) {
     795    usb_transfer_batch_t *request) {
    763796        usb_device_request_setup_packet_t * setup_request =
    764                 (usb_device_request_setup_packet_t*) request->setup_buffer;
     797            (usb_device_request_setup_packet_t*) request->setup_buffer;
    765798        request->transfered_size = 0;
    766799        if (setup_request->request == USB_DEVREQ_CLEAR_FEATURE) {
     
    768801                        usb_log_debug("USB_HUB_REQ_TYPE_SET_HUB_FEATURE\n");
    769802                        return process_hub_feature_clear_request(instance,
    770                                 setup_request->value);
     803                            setup_request->value);
    771804                }
    772805                if (setup_request->request_type == USB_HUB_REQ_TYPE_SET_PORT_FEATURE) {
    773806                        usb_log_debug("USB_HUB_REQ_TYPE_SET_PORT_FEATURE\n");
    774807                        return process_port_feature_clear_request(instance,
    775                                 setup_request->value,
    776                                 setup_request->index);
     808                            setup_request->value,
     809                            setup_request->index);
    777810                }
    778811                usb_log_debug("USB_HUB_REQ_TYPE_INVALID %d\n",
    779                         setup_request->request_type);
     812                    setup_request->request_type);
    780813                return EINVAL;
    781814        }
     
    784817                        usb_log_debug("USB_HUB_REQ_TYPE_SET_HUB_FEATURE\n");
    785818                        return process_hub_feature_set_request(instance,
    786                                 setup_request->value);
     819                            setup_request->value);
    787820                }
    788821                if (setup_request->request_type == USB_HUB_REQ_TYPE_SET_PORT_FEATURE) {
    789822                        usb_log_debug("USB_HUB_REQ_TYPE_SET_PORT_FEATURE\n");
    790823                        return process_port_feature_set_request(instance,
    791                                 setup_request->value,
    792                                 setup_request->index);
     824                            setup_request->value,
     825                            setup_request->index);
    793826                }
    794827                usb_log_debug("USB_HUB_REQ_TYPE_INVALID %d\n",
    795                         setup_request->request_type);
     828                    setup_request->request_type);
    796829                return EINVAL;
    797830        }
     
    799832                usb_log_debug("USB_DEVREQ_SET_ADDRESS\n");
    800833                return process_address_set_request(instance,
    801                         setup_request->value);
     834                    setup_request->value);
    802835        }
    803836        usb_log_debug("USB_DEVREQ_SET_ENOTSUP %d\n",
    804                 setup_request->request_type);
     837            setup_request->request_type);
     838
    805839        return ENOTSUP;
    806840}
     
    836870        }
    837871        usb_log_info("CTRL packet: %s.\n",
    838                 usb_debug_str_buffer(
    839                 (const uint8_t *) request->setup_buffer, 8, 8));
     872            usb_debug_str_buffer(
     873            (const uint8_t *) request->setup_buffer, 8, 8));
    840874        usb_device_request_setup_packet_t * setup_request =
    841                 (usb_device_request_setup_packet_t*)
    842                 request->setup_buffer;
     875            (usb_device_request_setup_packet_t*)
     876            request->setup_buffer;
    843877        switch (setup_request->request) {
    844878                case USB_DEVREQ_GET_STATUS:
     
    847881                        usb_log_debug("processing request with output\n");
    848882                        opResult = process_request_with_output(
    849                                 instance, request);
     883                            instance, request);
    850884                        break;
    851885                case USB_DEVREQ_CLEAR_FEATURE:
     
    853887                case USB_DEVREQ_SET_ADDRESS:
    854888                        usb_log_debug("processing request without "
    855                                 "additional data\n");
     889                            "additional data\n");
    856890                        opResult = process_request_without_data(
    857                                 instance, request);
     891                            instance, request);
    858892                        break;
    859893                case USB_DEVREQ_SET_DESCRIPTOR:
    860894                case USB_DEVREQ_SET_CONFIGURATION:
    861895                        usb_log_debug("processing request with "
    862                                 "input\n");
     896                            "input\n");
    863897                        opResult = process_request_with_input(
    864                                 instance, request);
     898                            instance, request);
     899
    865900                        break;
    866901                default:
    867902                        usb_log_warning("received unsuported request: "
    868                                 "%d\n",
    869                                 setup_request->request
    870                                 );
     903                            "%d\n",
     904                            setup_request->request
     905                            );
    871906                        opResult = ENOTSUP;
    872907        }
     
    888923 * @return
    889924 */
    890 static int process_interrupt_mask_in_instance(rh_t *instance, usb_transfer_batch_t * request){
     925static int process_interrupt_mask_in_instance(rh_t *instance, usb_transfer_batch_t * request) {
    891926        memcpy(request->data_buffer, instance->interrupt_buffer,
    892927            instance->interrupt_mask_size);
     
    894929        instance->unfinished_interrupt_transfer = NULL;
    895930        usb_transfer_batch_finish_error(request, EOK);
     931
    896932        return EOK;
    897933}
     
    907943 * @return
    908944 */
    909 static bool is_zeros(void * buffer, size_t size){
    910         if(!buffer) return true;
    911         if(!size) return true;
     945static bool is_zeros(void * buffer, size_t size) {
     946        if (!buffer) return true;
     947        if (!size) return true;
    912948        size_t i;
    913         for(i=0;i<size;++i){
    914                 if(((char*)buffer)[i])
     949        for (i = 0; i < size; ++i) {
     950                if (((char*) buffer)[i])
    915951                        return false;
    916952        }
  • uspace/drv/ohci/root_hub.h

    rbd2394b rcc5908e  
    5151        usb_address_t address;
    5252        /** hub port count */
    53         int port_count;
     53        size_t port_count;
    5454        /** hubs descriptors */
    5555        usb_device_descriptors_t descriptors;
  • uspace/drv/uhci-hcd/uhci.c

    rbd2394b rcc5908e  
    210210            "Failed(%d) to bind UHCI device function: %s.\n",
    211211            ret, str_error(ret));
     212        ret = ddf_fun_add_to_class(instance->hc_fun, USB_HC_DDF_CLASS_NAME);
     213        CHECK_RET_DEST_FUN_RETURN(ret,
     214            "Failed to add UHCI to HC class: %s.\n", str_error(ret));
     215
    212216#undef CHECK_RET_HC_RETURN
    213217
  • uspace/drv/usbhid/generic/hiddev.c

    rbd2394b rcc5908e  
    3939#include <errno.h>
    4040#include <str_error.h>
     41#include <bool.h>
    4142
    4243#include <usbhid_iface.h>
     
    6465    size_t size, size_t *act_size, unsigned int flags);
    6566
     67static int usb_generic_hid_client_connected(ddf_fun_t *fun);
     68
    6669/*----------------------------------------------------------------------------*/
    6770
     
    7275
    7376static ddf_dev_ops_t usb_generic_hid_ops = {
    74         .interfaces[USBHID_DEV_IFACE] = &usb_generic_iface
     77        .interfaces[USBHID_DEV_IFACE] = &usb_generic_iface,
     78        .open = usb_generic_hid_client_connected
    7579};
    7680
     
    104108       
    105109        /*! @todo This should probably be atomic. */
    106         memcpy(buffer, hid_dev->input_report, hid_dev->input_report_size);
    107         *act_size = hid_dev->input_report_size;
     110        if (usb_hid_report_ready()) {
     111                memcpy(buffer, hid_dev->input_report,
     112                    hid_dev->input_report_size);
     113                *act_size = hid_dev->input_report_size;
     114                usb_hid_report_received();
     115        }
    108116       
    109117        // clear the buffer so that it will not be received twice
    110         memset(hid_dev->input_report, 0, hid_dev->input_report_size);
     118        //memset(hid_dev->input_report, 0, hid_dev->input_report_size);
    111119       
     120        // note that we already received this report
     121//      report_received = true;
     122       
     123        return EOK;
     124}
     125
     126/*----------------------------------------------------------------------------*/
     127
     128static int usb_generic_hid_client_connected(ddf_fun_t *fun)
     129{
     130        usb_hid_report_received();
    112131        return EOK;
    113132}
  • uspace/drv/usbhid/kbd/kbddev.c

    rbd2394b rcc5908e  
    255255       
    256256        if (hid_dev == NULL || hid_dev->data == NULL) {
     257                usb_log_debug("default_connection_handler: "
     258                    "Missing parameter.\n");
    257259                async_answer_0(icallid, EINVAL);
    258260                return;
     
    267269
    268270                if (kbd_dev->console_phone != -1) {
     271                        usb_log_debug("default_connection_handler: "
     272                            "console phone already set\n");
    269273                        async_answer_0(icallid, ELIMIT);
    270274                        return;
     
    272276
    273277                kbd_dev->console_phone = callback;
     278               
     279                usb_log_debug("default_connection_handler: OK\n");
    274280                async_answer_0(icallid, EOK);
    275281                return;
    276282        }
    277283       
     284        usb_log_debug("default_connection_handler: Wrong function.\n");
    278285        async_answer_0(icallid, EINVAL);
    279286}
     
    555562                        usb_log_debug2("Key pressed: %d (keycode: %d)\n", key,
    556563                            kbd_dev->keys[i]);
    557                         usb_kbd_push_ev(hid_dev, kbd_dev, KEY_PRESS, key);
    558564                        if (!usb_kbd_is_lock(key)) {
    559565                                usb_kbd_repeat_start(kbd_dev, key);
    560566                        }
     567                        usb_kbd_push_ev(hid_dev, kbd_dev, KEY_PRESS, key);
    561568                } else {
    562569                        // found, nothing happens
  • uspace/drv/usbhid/mouse/mousedev.c

    rbd2394b rcc5908e  
    4343#include <str_error.h>
    4444#include <ipc/mouse.h>
     45#include <io/console.h>
     46
     47#include <ipc/kbd.h>
     48#include <io/keycode.h>
    4549
    4650#include "mousedev.h"
     
    6165
    6266const char *HID_MOUSE_FUN_NAME = "mouse";
     67const char *HID_MOUSE_WHEEL_FUN_NAME = "mouse-wheel";
    6368const char *HID_MOUSE_CLASS_NAME = "mouse";
     69const char *HID_MOUSE_WHEEL_CLASS_NAME = "keyboard";
    6470
    6571/** Default idle rate for mouses. */
     
    119125       
    120126        if (hid_dev == NULL || hid_dev->data == NULL) {
     127                usb_log_debug("default_connection_handler: Missing "
     128                    "parameters.\n");
    121129                async_answer_0(icallid, EINVAL);
    122130                return;
     
    127135        usb_mouse_t *mouse_dev = (usb_mouse_t *)hid_dev->data;
    128136       
     137        int *phone = (str_cmp(fun->name, HID_MOUSE_FUN_NAME) == 0)
     138                     ? &mouse_dev->mouse_phone : &mouse_dev->wheel_phone;
     139       
    129140        if (method == IPC_M_CONNECT_TO_ME) {
    130141                int callback = IPC_GET_ARG5(*icall);
    131142
    132                 if (mouse_dev->console_phone != -1) {
     143                if (*phone != -1) {
     144                        usb_log_debug("default_connection_handler: Console "
     145                            "phone to mouse already set.\n");
    133146                        async_answer_0(icallid, ELIMIT);
     147                        //async_answer_0(icallid, EOK);
    134148                        return;
    135149                }
    136150
    137                 mouse_dev->console_phone = callback;
     151                *phone = callback;
    138152                usb_log_debug("Console phone to mouse set ok (%d).\n", callback);
    139153                async_answer_0(icallid, EOK);
     
    141155        }
    142156
     157        usb_log_debug("default_connection_handler: Invalid function.\n");
    143158        async_answer_0(icallid, EINVAL);
    144159}
     
    152167                return NULL;
    153168        }
    154         mouse->console_phone = -1;
     169        mouse->mouse_phone = -1;
     170        mouse->wheel_phone = -1;
    155171       
    156172        return mouse;
     
    164180       
    165181        // hangup phone to the console
    166         if ((*mouse_dev)->console_phone >= 0) {
    167                 async_hangup((*mouse_dev)->console_phone);
     182        if ((*mouse_dev)->mouse_phone >= 0) {
     183                async_hangup((*mouse_dev)->mouse_phone);
     184        }
     185       
     186        if ((*mouse_dev)->wheel_phone >= 0) {
     187                async_hangup((*mouse_dev)->wheel_phone);
    168188        }
    169189       
     
    174194/*----------------------------------------------------------------------------*/
    175195
    176 static bool usb_mouse_process_boot_report(usb_hid_dev_t *hid_dev,
    177     uint8_t *buffer, size_t buffer_size)
     196static void usb_mouse_send_wheel(const usb_mouse_t *mouse_dev, int wheel)
     197{
     198        console_event_t ev;
     199       
     200        ev.type = KEY_PRESS;
     201        ev.key = (wheel > 0) ? KC_UP : (wheel < 0) ? KC_DOWN : 0;
     202        ev.mods = 0;
     203        ev.c = 0;
     204
     205        if (mouse_dev->wheel_phone < 0) {
     206                usb_log_warning(
     207                    "Connection to console not ready, key discarded.\n");
     208                return;
     209        }
     210       
     211        int count = (wheel < 0) ? -wheel : wheel;
     212        int i;
     213       
     214        for (i = 0; i < count * 3; ++i) {
     215                usb_log_debug2("Sending key %d to the console\n", ev.key);
     216                async_msg_4(mouse_dev->wheel_phone, KBD_EVENT, ev.type,
     217                    ev.key, ev.mods, ev.c);
     218                // send key release right away
     219                async_msg_4(mouse_dev->wheel_phone, KBD_EVENT, KEY_RELEASE,
     220                    ev.key, ev.mods, ev.c);
     221        }
     222}
     223
     224/*----------------------------------------------------------------------------*/
     225
     226static bool usb_mouse_process_report(usb_hid_dev_t *hid_dev, uint8_t *buffer,
     227    size_t buffer_size)
    178228{
    179229        usb_mouse_t *mouse_dev = (usb_mouse_t *)hid_dev->data;
     
    182232            usb_debug_str_buffer(buffer, buffer_size, 0));
    183233       
    184         if (mouse_dev->console_phone < 0) {
     234        if (mouse_dev->mouse_phone < 0) {
    185235                usb_log_error(NAME " No console phone.\n");
    186236                return false;   // ??
     
    252302       
    253303        if ((shift_x != 0) || (shift_y != 0)) {
    254                 async_req_2_0(mouse_dev->console_phone,
     304                async_req_2_0(mouse_dev->mouse_phone,
    255305                    MEVENT_MOVE, shift_x, shift_y);
    256306        }
     307       
     308        /*
     309         * Wheel
     310         */
     311        int wheel = 0;
     312       
     313        path = usb_hid_report_path();
     314        usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_GENERIC_DESKTOP,
     315            USB_HIDUT_USAGE_GENERIC_DESKTOP_WHEEL);
     316
     317        usb_hid_report_path_set_report_id(path, report_id);
     318       
     319        field = usb_hid_report_get_sibling(
     320            hid_dev->report, NULL, path, USB_HID_PATH_COMPARE_END,
     321            USB_HID_REPORT_TYPE_INPUT);
     322
     323        if (field != NULL) {
     324                usb_log_debug(NAME " VALUE(%X) USAGE(%X)\n", field->value,
     325                    field->usage);
     326                wheel = field->value;
     327        }
     328
     329        usb_hid_report_path_free(path);
     330       
     331        // send arrow up for positive direction and arrow down for negative
     332        // direction; three arrows for difference of 1
     333        usb_mouse_send_wheel(mouse_dev, wheel);
     334       
    257335       
    258336        /*
     
    274352                if (mouse_dev->buttons[field->usage - field->usage_minimum] == 0
    275353                    && field->value != 0) {
    276                         async_req_2_0(mouse_dev->console_phone,
     354                        async_req_2_0(mouse_dev->mouse_phone,
    277355                            MEVENT_BUTTON, field->usage, 1);
    278356                        mouse_dev->buttons[field->usage - field->usage_minimum]
     
    281359                    mouse_dev->buttons[field->usage - field->usage_minimum] != 0
    282360                    && field->value == 0) {
    283                        async_req_2_0(mouse_dev->console_phone,
     361                       async_req_2_0(mouse_dev->mouse_phone,
    284362                           MEVENT_BUTTON, field->usage, 0);
    285363                       mouse_dev->buttons[field->usage - field->usage_minimum]
     
    337415        }
    338416       
     417        /*
     418         * Special function for acting as keyboard (wheel)
     419         */
     420        usb_log_debug("Creating DDF function %s...\n",
     421                      HID_MOUSE_WHEEL_FUN_NAME);
     422        fun = ddf_fun_create(hid_dev->usb_dev->ddf_dev, fun_exposed,
     423            HID_MOUSE_WHEEL_FUN_NAME);
     424        if (fun == NULL) {
     425                usb_log_error("Could not create DDF function node.\n");
     426                return ENOMEM;
     427        }
     428       
     429        /*
     430         * Store the initialized HID device and HID ops
     431         * to the DDF function.
     432         */
     433        fun->ops = &hid_dev->ops;
     434        fun->driver_data = hid_dev;   // TODO: maybe change to hid_dev->data
     435
     436        rc = ddf_fun_bind(fun);
     437        if (rc != EOK) {
     438                usb_log_error("Could not bind DDF function: %s.\n",
     439                    str_error(rc));
     440                ddf_fun_destroy(fun);
     441                return rc;
     442        }
     443       
     444        usb_log_debug("Adding DDF function to class %s...\n",
     445            HID_MOUSE_WHEEL_CLASS_NAME);
     446        rc = ddf_fun_add_to_class(fun, HID_MOUSE_WHEEL_CLASS_NAME);
     447        if (rc != EOK) {
     448                usb_log_error(
     449                    "Could not add DDF function to class %s: %s.\n",
     450                    HID_MOUSE_WHEEL_CLASS_NAME, str_error(rc));
     451                ddf_fun_destroy(fun);
     452                return rc;
     453        }
     454       
    339455        return EOK;
    340456}
     
    407523        }
    408524       
    409         return usb_mouse_process_boot_report(hid_dev, buffer, buffer_size);
     525        return usb_mouse_process_report(hid_dev, buffer, buffer_size);
    410526}
    411527
  • uspace/drv/usbhid/mouse/mousedev.h

    rbd2394b rcc5908e  
    4848        //suseconds_t poll_interval_us;
    4949        /** IPC phone to console (consumer). */
    50         int console_phone;
     50        int mouse_phone;
     51        int wheel_phone;
    5152       
    5253        int32_t *buttons;
  • uspace/drv/usbhid/subdrivers.c

    rbd2394b rcc5908e  
    3636#include "subdrivers.h"
    3737#include "usb/classes/hidut.h"
     38#include "usb/classes/hidpath.h"
    3839
    3940#include "lgtch-ultrax/lgtch-ultrax.h"
     41#include "mouse/mousedev.h"
    4042
    4143static usb_hid_subdriver_usage_t path_kbd[] = {
    4244        {USB_HIDUT_PAGE_KEYBOARD, 0},
     45        {0, 0}
     46};
     47
     48static usb_hid_subdriver_usage_t path_mouse2[] = {
     49        {USB_HIDUT_PAGE_GENERIC_DESKTOP, USB_HIDUT_USAGE_GENERIC_DESKTOP_X},
    4350        {0, 0}
    4451};
     
    7986                }
    8087        },
     88        {
     89                path_mouse2,
     90                -1,
     91                USB_HID_PATH_COMPARE_END
     92                | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY,
     93                -1,
     94                -1,
     95                {
     96                        .init = usb_mouse_init,
     97                        .deinit = usb_mouse_deinit,
     98                        .poll = usb_mouse_polling_callback,
     99                        .poll_end = NULL
     100                }
     101        },
    81102        {NULL, -1, 0, -1, -1, {NULL, NULL, NULL, NULL}}
    82103};
  • uspace/drv/usbhid/usbhid.c

    rbd2394b rcc5908e  
    6363static const int USB_HID_MAX_SUBDRIVERS = 10;
    6464
     65static fibril_local bool report_received;
     66
    6567/*----------------------------------------------------------------------------*/
    6668
     
    412414        }
    413415       
    414         // TODO: remove the mouse hack
    415         if (hid_dev->poll_pipe_index == USB_HID_MOUSE_POLL_EP_NO ||
    416             fallback) {
     416        if (fallback) {
    417417                // fall back to boot protocol
    418418                switch (hid_dev->poll_pipe_index) {
     
    509509                                free(input_old);
    510510                        }
     511                        usb_hid_new_report();
    511512                }
    512513        }
     
    589590/*----------------------------------------------------------------------------*/
    590591
     592void usb_hid_new_report(void)
     593{
     594        report_received = false;
     595}
     596
     597/*----------------------------------------------------------------------------*/
     598
     599void usb_hid_report_received(void)
     600{
     601        report_received = true;
     602}
     603
     604/*----------------------------------------------------------------------------*/
     605
     606bool usb_hid_report_ready(void)
     607{
     608        return !report_received;
     609}
     610
     611/*----------------------------------------------------------------------------*/
     612
    591613void usb_hid_free(usb_hid_dev_t **hid_dev)
    592614{
  • uspace/drv/usbhid/usbhid.h

    rbd2394b rcc5908e  
    4444#include <usb/devdrv.h>
    4545#include <usb/classes/hid.h>
     46#include <bool.h>
    4647
    4748struct usb_hid_dev;
     
    128129//const char *usb_hid_get_class_name(const usb_hid_dev_t *hid_dev);
    129130
     131void usb_hid_new_report(void);
     132
     133void usb_hid_report_received(void);
     134
     135bool usb_hid_report_ready(void);
     136
    130137void usb_hid_free(usb_hid_dev_t **hid_dev);
    131138
  • uspace/drv/usbhub/ports.c

    rbd2394b rcc5908e  
    5353        size_t port;
    5454        usb_speed_t speed;
     55};
     56
     57/**
     58 * count of port status changes that are not explicitly handled by
     59 * any function here and must be cleared by hand
     60 */
     61static const unsigned int non_handled_changes_count = 2;
     62
     63/**
     64 * port status changes that are not explicitly handled by
     65 * any function here and must be cleared by hand
     66 */
     67static const int non_handled_changes[] =  {
     68        USB_HUB_FEATURE_C_PORT_ENABLE,
     69        USB_HUB_FEATURE_C_PORT_SUSPEND
    5570};
    5671
     
    131146            &status, USB_HUB_FEATURE_C_PORT_CONNECTION,false);
    132147        usb_port_status_set_bit(
    133             &status, USB_HUB_FEATURE_PORT_RESET,false);
    134         usb_port_status_set_bit(
    135148            &status, USB_HUB_FEATURE_C_PORT_RESET,false);
    136149        usb_port_status_set_bit(
    137150            &status, USB_HUB_FEATURE_C_PORT_OVER_CURRENT,false);
    138         /// \TODO what about port power change?
    139         if (status >> 16) {
    140                 usb_log_info("there was unsupported change on port %d: %X\n",
    141                         port, status);
    142 
     151       
     152        //clearing not yet handled changes     
     153        unsigned int feature_idx;
     154        for(feature_idx = 0;feature_idx<non_handled_changes_count;
     155            ++feature_idx){
     156                unsigned int bit_idx = non_handled_changes[feature_idx];
     157                if(status & (1<<bit_idx)){
     158                        usb_log_info(
     159                            "there was not yet handled change on port %d: %d"
     160                            ";clearing it\n",
     161                        port, bit_idx);
     162                        int opResult = usb_hub_clear_port_feature(
     163                            hub->control_pipe,
     164                            port, bit_idx);
     165                        if (opResult != EOK) {
     166                                usb_log_warning(
     167                                    "could not clear port flag %d: %d\n",
     168                                    bit_idx, opResult
     169                                    );
     170                        }
     171                        usb_port_status_set_bit(
     172                            &status, bit_idx,false);
     173                }
     174        }
     175        if(status>>16){
     176                usb_log_info("there is still some unhandled change %X\n",
     177                    status);
    143178        }
    144179}
     
    222257                    "Port %zu reset complete but port not enabled.\n",
    223258                    (size_t) port);
     259        }
     260        /* Clear the port reset change. */
     261        int rc = usb_hub_clear_port_feature(hub->control_pipe,
     262            port, USB_HUB_FEATURE_C_PORT_RESET);
     263        if (rc != EOK) {
     264                usb_log_error("Failed to clear port %d reset feature: %s.\n",
     265                    port, str_error(rc));
    224266        }
    225267}
     
    319361        fibril_mutex_unlock(&my_port->reset_mutex);
    320362
    321         /* Clear the port reset change. */
    322         rc = usb_hub_clear_port_feature(hub->control_pipe,
    323             port_no, USB_HUB_FEATURE_C_PORT_RESET);
    324         if (rc != EOK) {
    325                 usb_log_error("Failed to clear port %d reset feature: %s.\n",
    326                     port_no, str_error(rc));
    327                 return rc;
    328         }
    329 
    330363        if (my_port->reset_okay) {
    331364                return EOK;
  • uspace/drv/vhc/main.c

    rbd2394b rcc5908e  
    104104        }
    105105
    106         ddf_fun_add_to_class(hc, "usbhc");
     106        rc = ddf_fun_add_to_class(hc, USB_HC_DDF_CLASS_NAME);
     107        if (rc != EOK) {
     108                usb_log_fatal("Failed to add function to HC class: %s.\n",
     109                    str_error(rc));
     110                free(data);
     111                return rc;
     112        }
    107113
    108114        virtual_hub_device_init(hc);
  • uspace/drv/vhc/transfer.c

    rbd2394b rcc5908e  
    135135                if (transfer->direction == USB_DIRECTION_IN) {
    136136                        rc = usbvirt_ipc_send_control_read(phone,
    137                             transfer->endpoint,
    138137                            transfer->setup_buffer, transfer->setup_buffer_size,
    139138                            transfer->data_buffer, transfer->data_buffer_size,
     
    142141                        assert(transfer->direction == USB_DIRECTION_OUT);
    143142                        rc = usbvirt_ipc_send_control_write(phone,
    144                             transfer->endpoint,
    145143                            transfer->setup_buffer, transfer->setup_buffer_size,
    146144                            transfer->data_buffer, transfer->data_buffer_size);
  • uspace/lib/c/generic/devman.c

    rbd2394b rcc5908e  
    374374}
    375375
     376int devman_get_device_path(devman_handle_t handle, char *path, size_t path_size)
     377{
     378        int phone = devman_get_phone(DEVMAN_CLIENT, 0);
     379
     380        if (phone < 0)
     381                return phone;
     382
     383        async_serialize_start();
     384
     385        ipc_call_t answer;
     386        aid_t req = async_send_1(phone, DEVMAN_DEVICE_GET_DEVICE_PATH,
     387            handle, &answer);
     388
     389        ipc_call_t data_request_call;
     390        aid_t data_request = async_data_read(phone, path, path_size,
     391            &data_request_call);
     392        if (data_request == 0) {
     393                async_wait_for(req, NULL);
     394                async_serialize_end();
     395                return ENOMEM;
     396        }
     397
     398        sysarg_t data_request_rc;
     399        sysarg_t opening_request_rc;
     400        async_wait_for(data_request, &data_request_rc);
     401        async_wait_for(req, &opening_request_rc);
     402
     403        async_serialize_end();
     404
     405        if (data_request_rc != EOK) {
     406                /* Prefer the return code of the opening request. */
     407                if (opening_request_rc != EOK) {
     408                        return (int) opening_request_rc;
     409                } else {
     410                        return (int) data_request_rc;
     411                }
     412        }
     413        if (opening_request_rc != EOK) {
     414                return (int) opening_request_rc;
     415        }
     416
     417        path[path_size - 1] = 0;
     418
     419        if (IPC_GET_ARG2(data_request_call) >= path_size) {
     420                return ELIMIT;
     421        }
     422
     423        return EOK;
     424}
     425
    376426
    377427/** @}
  • uspace/lib/c/include/devman.h

    rbd2394b rcc5908e  
    5555extern int devman_device_get_handle_by_class(const char *, const char *,
    5656    devman_handle_t *, unsigned int);
     57extern int devman_get_device_path(devman_handle_t, char *, size_t);
    5758
    5859extern int devman_add_device_to_class(devman_handle_t, const char *);
  • uspace/lib/c/include/ipc/devman.h

    rbd2394b rcc5908e  
    149149typedef enum {
    150150        DEVMAN_DEVICE_GET_HANDLE = IPC_FIRST_USER_METHOD,
    151         DEVMAN_DEVICE_GET_HANDLE_BY_CLASS
     151        DEVMAN_DEVICE_GET_HANDLE_BY_CLASS,
     152        DEVMAN_DEVICE_GET_DEVICE_PATH
    152153} client_to_devman_t;
    153154
  • uspace/lib/usb/Makefile

    rbd2394b rcc5908e  
    4646        src/hidparser.c \
    4747        src/hiddescriptor.c \
     48        src/host.c \
    4849        src/hub.c \
    4950        src/pipepriv.c \
  • uspace/lib/usb/include/usb/classes/hid_report_items.h

    rbd2394b rcc5908e  
    4646#define USB_HID_ITEM_IS_LONG(data)      (data == 0xFE)
    4747
     48
     49/**
     50 * Extended usage macros
     51 */
     52#define USB_HID_IS_EXTENDED_USAGE(usage)        ((usage & 0xFFFF0000) != 0)
     53#define USB_HID_EXTENDED_USAGE_PAGE(usage)      ((usage & 0xFFFF0000) >> 16)
     54#define USB_HID_EXTENDED_USAGE(usage)           (usage & 0xFFFF)
    4855
    4956/**
  • uspace/lib/usb/include/usb/classes/hidtypes.h

    rbd2394b rcc5908e  
    3939#include <adt/list.h>
    4040
    41 #define USB_HID_MAX_USAGES      20
     41#define USB_HID_MAX_USAGES      0xffff
    4242
    4343#define USB_HID_UINT32_TO_INT32(x, size)        ((((x) & (1 << ((size) - 1))) != 0) ? -(~(x - 1) & ((1 << size) - 1)) : (x)) //(-(~((x) - 1)))
     
    9292        int32_t physical_minimum;
    9393        int32_t physical_maximum;
    94         uint32_t usage_minimum;
    95         uint32_t usage_maximum;
     94        int32_t usage_minimum;
     95        int32_t usage_maximum;
    9696        uint32_t unit;
    9797        uint32_t unit_exponent;
    98        
     98
     99        uint32_t *usages;
     100        size_t usages_count;
    99101
    100102        int32_t value;
     
    121123
    122124        /** */ 
    123         uint32_t usage_minimum;
    124         /** */ 
    125         uint32_t usage_maximum;
     125        int32_t usage_minimum;
     126        /** */ 
     127        int32_t usage_maximum;
    126128        /** */ 
    127129        int32_t logical_minimum;
  • uspace/lib/usb/include/usb/host.h

    rbd2394b rcc5908e  
    11/*
    2  * Copyright (c) 2010 Vojtech Horky
     2 * Copyright (c) 2011 Vojtech Horky
    33 * All rights reserved.
    44 *
     
    2727 */
    2828
    29 /** @addtogroup usbvirtkbd
     29/** @addtogroup libusb
    3030 * @{
    3131 */
    3232/** @file
    33  * @brief Standard device request handlers.
     33 * Host controller common functions.
    3434 */
    35 #ifndef VUK_STDREQ_H_
    36 #define VUK_STDREQ_H_
     35#ifndef LIBUSB_HOST_H_
     36#define LIBUSB_HOST_H_
    3737
    38 #include <usbvirt/device.h>
     38#include <sys/types.h>
     39#include <ipc/devman.h>
    3940
    40 int req_get_descriptor(usbvirt_device_t *device,
    41     const usb_device_request_setup_packet_t *setup_packet,
    42     uint8_t *data, size_t *act_size);
     41int usb_ddf_get_hc_handle_by_class(size_t, devman_handle_t *);
    4342
    4443#endif
  • uspace/lib/usb/include/usb/usb.h

    rbd2394b rcc5908e  
    172172} usb_packet_id;
    173173
     174/** Class name for USB host controllers. */
     175#define USB_HC_DDF_CLASS_NAME "usbhc"
     176
    174177#endif
    175178/**
  • uspace/lib/usb/src/hiddescriptor.c

    rbd2394b rcc5908e  
    116116        int i;
    117117
    118         for(i=0; i<report_item->usages_count; i++){
    119                 usb_log_debug("usages (%d) - %x\n", i, report_item->usages[i]);
    120         }
    121 
     118        usb_log_debug("usages_count  - %zu\n", report_item->usages_count);
     119
     120        uint32_t *usages;
     121        int usages_used=0;
     122        if(report_item->usages_count > 0){
     123                usages = malloc(sizeof(int32_t) * report_item->usages_count);
     124                memcpy(usages, report_item->usages, sizeof(int32_t) * report_item->usages_count);
     125        }
     126        else {
     127                usages = NULL;
     128        }
     129       
    122130        usb_hid_report_path_t *path = report_item->usage_path; 
    123131        for(i=0; i<report_item->count; i++){
     
    133141                field->physical_maximum = report_item->physical_maximum;
    134142
    135                 field->usage_minimum = report_item->usage_minimum;
    136                 field->usage_maximum = report_item->usage_maximum;
    137                 if(report_item->extended_usage_page != 0){
    138                         field->usage_page = report_item->extended_usage_page;
     143                if(USB_HID_ITEM_FLAG_VARIABLE(report_item->item_flags) == 0){
     144                        /*
     145                                Store usage array. The Correct Usage Page and Usage is depending
     146                                on data in report and will be filled later
     147                        */
     148                        field->usage = 0;
     149                        field->usage_page = report_item->usage_page;
     150
     151                        field->usages_count = report_item->usages_count;
     152                        field->usages = usages;
     153                        usages_used = 1;
    139154                }
    140155                else {
    141                         field->usage_page = report_item->usage_page;
    142                 }
    143 
    144                 if(report_item->usages_count > 0 && ((report_item->usage_minimum == 0) && (report_item->usage_maximum == 0))) {
    145                         uint32_t usage;
    146                         if(i < report_item->usages_count){
     156                        /* Fill the correct Usage and Usage Page */
     157                        int32_t usage;
     158                        if(i < report_item->usages_count) {
    147159                                usage = report_item->usages[i];
    148160                        }
     
    151163                        }
    152164
    153                                                
    154                         if((usage & 0xFFFF0000) != 0){
    155                                 field->usage_page = (usage >> 16);                                     
    156                                 field->usage = (usage & 0xFFFF);
     165                        if(USB_HID_IS_EXTENDED_USAGE(usage)){
     166                                field->usage = USB_HID_EXTENDED_USAGE(usage);
     167                                field->usage_page = USB_HID_EXTENDED_USAGE_PAGE(usage);
    157168                        }
    158169                        else {
    159170                                field->usage = usage;
    160                         }
    161 
    162                        
    163                 }       
    164 
    165                 if((USB_HID_ITEM_FLAG_VARIABLE(report_item->item_flags) != 0) && (!((report_item->usage_minimum == 0) && (report_item->usage_maximum == 0)))) {
    166                         field->usage = report_item->usage_minimum + i;                                 
     171                                field->usage_page = report_item->usage_page;
     172                        }
    167173                }
    168174               
     
    209215        }
    210216
     217        // free only when not used!!!
     218        if(usages && usages_used == 0) {
     219                free(usages);
     220        }
    211221
    212222        return EOK;
     
    565575                        }
    566576                        break;
    567                 case USB_HID_REPORT_TAG_USAGE_MINIMUM:
    568 
    569                         usb_log_debug("USAGE_MINIMUM (SIZE: %d), data[0](%x), data[1](%x), data[2](%x) data[3](%x)\n",
    570                                       item_size, *data, *(data+1), *(data+2), *(data+3));
    571                        
     577                case USB_HID_REPORT_TAG_USAGE_MINIMUM:                 
    572578                        if (item_size == 3) {
    573579                                // usage extended usages
     
    581587                case USB_HID_REPORT_TAG_USAGE_MAXIMUM:
    582588                        if (item_size == 3) {
     589
     590                                if(report_item->extended_usage_page != ((usb_hid_report_tag_data_uint32(data,item_size) & 0xFF00) >> 16)) {
     591                                        return EINVAL;
     592                                }
     593                               
    583594                                // usage extended usages
    584595                                report_item->extended_usage_page = (usb_hid_report_tag_data_uint32(data,item_size) & 0xFF00) >> 16;
     
    588599                                report_item->usage_maximum = usb_hid_report_tag_data_uint32(data,item_size);
    589600                        }
     601
     602                        // vlozit zaznamy do pole usages
     603                        int32_t i;
     604                        for(i=report_item->usage_minimum; i<=report_item->usage_maximum; i++) {
     605                                if(report_item->extended_usage_page) {
     606                                        report_item->usages[report_item->usages_count++] = (report_item->extended_usage_page << 16) + i;
     607                                }
     608                                else {
     609                                        report_item->usages[report_item->usages_count++] = i;
     610                                }
     611                        }
     612                        report_item->extended_usage_page = 0;
     613                       
    590614                        break;
    591615                case USB_HID_REPORT_TAG_DESIGNATOR_INDEX:
     
    660684
    661685                usb_log_debug("\t\tOFFSET: %X\n", report_item->offset);
    662                 usb_log_debug("\t\tSIZE: %X\n", report_item->size);                             
     686                usb_log_debug("\t\tSIZE: %zu\n", report_item->size);                           
    663687                usb_log_debug("\t\tLOGMIN: %d\n", report_item->logical_minimum);
    664688                usb_log_debug("\t\tLOGMAX: %d\n", report_item->logical_maximum);               
     
    699723                usb_log_debug("Report ID: %d\n", report_des->report_id);
    700724                usb_log_debug("\tType: %d\n", report_des->type);
    701                 usb_log_debug("\tLength: %d\n", report_des->bit_length);               
    702                 usb_log_debug("\tItems: %d\n", report_des->item_length);               
     725                usb_log_debug("\tLength: %zu\n", report_des->bit_length);               
     726                usb_log_debug("\tItems: %zu\n", report_des->item_length);               
    703727
    704728                usb_hid_descriptor_print_list(&report_des->report_items);
  • uspace/lib/usb/src/hidparser.c

    rbd2394b rcc5908e  
    138138                                // array
    139139                                item->value = usb_hid_translate_data(item, data);
    140                             item->usage = (item->value - item->physical_minimum) + item->usage_minimum;
     140               
     141                                item->usage = USB_HID_EXTENDED_USAGE(item->usages[item->value - item->physical_minimum]);
     142                                item->usage_page = USB_HID_EXTENDED_USAGE_PAGE(item->usages[item->value - item->physical_minimum]);
     143
    141144                        }
    142145                        else {
  • uspace/lib/usb/src/host.c

    rbd2394b rcc5908e  
    11/*
    2  * Copyright (c) 2010 Vojtech Horky
     2 * Copyright (c) 2011 Vojtech Horky
    33 * All rights reserved.
    44 *
     
    2727 */
    2828
    29 /** @addtogroup usbvirtkbd
     29/** @addtogroup libusb
    3030 * @{
    3131 */
    32 /** @file
    33  * @brief USB keyboard configuration.
     32/**
     33 * @file
     34 * Host controller common functions (implementation).
    3435 */
    35 #ifndef VUK_KBDCONFIG_H_
    36 #define VUK_KBDCONFIG_H_
     36#include <stdio.h>
     37#include <str_error.h>
     38#include <errno.h>
     39#include <assert.h>
     40#include <bool.h>
     41#include <usb/host.h>
     42#include <usb/descriptor.h>
     43#include <devman.h>
    3744
    38 #include <usb/descriptor.h>
    39 #include "report.h"
    40 #include "descriptor.h"
     45/** Get host controller handle by its class index.
     46 *
     47 * @param class_index Class index for the host controller.
     48 * @param hc_handle Where to store the HC handle
     49 *      (can be NULL for existence test only).
     50 * @return Error code.
     51 */
     52int usb_ddf_get_hc_handle_by_class(size_t class_index,
     53    devman_handle_t *hc_handle)
     54{
     55        char *class_index_str;
     56        devman_handle_t hc_handle_tmp;
     57        int rc;
    4158
    42 extern usb_standard_device_descriptor_t std_device_descriptor;
     59        rc = asprintf(&class_index_str, "%zu", class_index);
     60        if (rc < 0) {
     61                return ENOMEM;
     62        }
     63        rc = devman_device_get_handle_by_class("usbhc", class_index_str,
     64            &hc_handle_tmp, 0);
     65        free(class_index_str);
     66        if (rc != EOK) {
     67                return rc;
     68        }
    4369
    44 extern usb_standard_configuration_descriptor_t std_configuration_descriptor;
     70        if (hc_handle != NULL) {
     71                *hc_handle = hc_handle_tmp;
     72        }
    4573
    46 extern usb_standard_interface_descriptor_t std_interface_descriptor;
     74        return EOK;
     75}
    4776
    48 extern usb_standard_endpoint_descriptor_t endpoint_descriptor;
    49 
    50 
    51 extern hid_descriptor_t hid_descriptor;
    52 
    53 extern report_descriptor_data_t report_descriptor;
    54 extern size_t report_descriptor_size;
    55 
    56 
    57 #endif
    58 /**
    59  * @}
     77/** @}
    6078 */
  • uspace/lib/usbvirt/Makefile

    rbd2394b rcc5908e  
    3333
    3434SOURCES = \
    35         src/ipc.c \
    3635        src/ctrltransfer.c \
     36        src/device.c \
     37        src/ipc_dev.c \
     38        src/ipc_hc.c \
    3739        src/stdreq.c \
    3840        src/transfer.c
  • uspace/lib/usbvirt/include/usbvirt/device.h

    rbd2394b rcc5908e  
    3131 */
    3232/** @file
    33  * @brief Virtual USB device.
     33 * Virtual USB device.
    3434 */
    3535#ifndef LIBUSBVIRT_DEVICE_H_
     
    3939#include <usb/request.h>
    4040
     41/** Maximum number of endpoints supported by virtual USB. */
    4142#define USBVIRT_ENDPOINT_MAX 16
    4243
    4344typedef struct usbvirt_device usbvirt_device_t;
    4445
    45 typedef int (*usbvirt_on_data_to_device_t)(usbvirt_device_t *, usb_endpoint_t,
    46     usb_transfer_type_t, void *, size_t);
    47 typedef int (*usbvirt_on_data_from_device_t)(usbvirt_device_t *, usb_endpoint_t,
    48     usb_transfer_type_t, void *, size_t, size_t *);
    49 typedef int (*usbvirt_on_control_t)(usbvirt_device_t *,
    50     const usb_device_request_setup_packet_t *, uint8_t *, size_t *);
    51 
    52 typedef struct {
     46/** Callback for data to device (OUT transaction).
     47 *
     48 * @param dev Virtual device to which the transaction belongs.
     49 * @param endpoint Target endpoint number.
     50 * @param transfer_type Transfer type.
     51 * @param buffer Data buffer.
     52 * @param buffer_size Size of the buffer in bytes.
     53 * @return Error code.
     54 */
     55typedef int (*usbvirt_on_data_to_device_t)(usbvirt_device_t *dev,
     56    usb_endpoint_t endpoint, usb_transfer_type_t transfer_type,
     57    void *buffer, size_t buffer_size);
     58
     59/** Callback for data from device (IN transaction).
     60 *
     61 * @param dev Virtual device to which the transaction belongs.
     62 * @param endpoint Target endpoint number.
     63 * @param transfer_type Transfer type.
     64 * @param buffer Data buffer to write answer to.
     65 * @param buffer_size Size of the buffer in bytes.
     66 * @param act_buffer_size Write here how many bytes were actually written.
     67 * @return Error code.
     68 */
     69typedef int (*usbvirt_on_data_from_device_t)(usbvirt_device_t *dev,
     70    usb_endpoint_t endpoint, usb_transfer_type_t transfer_type,
     71    void *buffer, size_t buffer_size, size_t *act_buffer_size);
     72
     73/** Callback for control transfer on endpoint zero.
     74 *
     75 * Notice that size of the data buffer is expected to be read from the
     76 * setup packet.
     77 *
     78 * @param dev Virtual device to which the transaction belongs.
     79 * @param setup_packet Standard setup packet.
     80 * @param data Data (might be NULL).
     81 * @param act_data_size Size of returned data in bytes.
     82 * @return Error code.
     83 */
     84typedef int (*usbvirt_on_control_t)(usbvirt_device_t *dev,
     85    const usb_device_request_setup_packet_t *setup_packet,
     86    uint8_t *data, size_t *act_data_size);
     87
     88/** Callback for control request on a virtual USB device.
     89 *
     90 * See usbvirt_control_reply_helper() for simple way of answering
     91 * control read requests.
     92 */
     93typedef struct {
     94        /** Request direction (in or out). */
    5395        usb_direction_t req_direction;
     96        /** Request recipient (device, interface or endpoint). */
    5497        usb_request_recipient_t req_recipient;
     98        /** Request type (standard, class or vendor). */
    5599        usb_request_type_t req_type;
     100        /** Actual request code. */
    56101        uint8_t request;
     102        /** Request handler name for debugging purposes. */
    57103        const char *name;
     104        /** Callback to be executed on matching request. */
    58105        usbvirt_on_control_t callback;
    59106} usbvirt_control_request_handler_t;
     
    77124} usbvirt_device_configuration_t;
    78125
    79 /** Standard USB descriptors. */
     126/** Standard USB descriptors for virtual device. */
    80127typedef struct {
    81128        /** Standard device descriptor.
     
    102149} usbvirt_device_state_t;
    103150
    104 typedef struct {
     151/** Ops structure for virtual USB device. */
     152typedef struct {
     153        /** Callbacks for data to device.
     154         * Index zero is ignored.
     155         */
    105156        usbvirt_on_data_to_device_t data_out[USBVIRT_ENDPOINT_MAX];
     157        /** Callbacks for data from device.
     158         * Index zero is ignored.
     159         */
    106160        usbvirt_on_data_from_device_t data_in[USBVIRT_ENDPOINT_MAX];
     161        /** Array of control handlers.
     162         * Last handler is expected to have the @c callback field set to NULL
     163         */
    107164        usbvirt_control_request_handler_t *control;
     165        /** Callback when device changes state.
     166         *
     167         * The value of @c state attribute of @p dev device is not
     168         * defined during call of this function.
     169         *
     170         * @param dev The virtual USB device.
     171         * @param old_state Old device state.
     172         * @param new_state New device state.
     173         */
    108174        void (*state_changed)(usbvirt_device_t *dev,
    109175            usbvirt_device_state_t old_state, usbvirt_device_state_t new_state);
    110176} usbvirt_device_ops_t;
    111177
     178/** Virtual USB device. */
    112179struct usbvirt_device {
     180        /** Name for debugging purposes. */
    113181        const char *name;
     182        /** Custom device data. */
    114183        void *device_data;
     184        /** Device ops. */
    115185        usbvirt_device_ops_t *ops;
     186        /** Device descriptors. */
    116187        usbvirt_descriptors_t *descriptors;
     188        /** Current device address.
     189         * You shall treat this field as read only in your code.
     190         */
    117191        usb_address_t address;
     192        /** Current device state.
     193         * You shall treat this field as read only in your code.
     194         */
    118195        usbvirt_device_state_t state;
     196        /** Phone to the host controller.
     197         * You shall treat this field as read only in your code.
     198         */
     199        int vhc_phone;
    119200};
    120201
    121202int usbvirt_device_plug(usbvirt_device_t *, const char *);
     203void usbvirt_device_unplug(usbvirt_device_t *);
    122204
    123205void usbvirt_control_reply_helper(const usb_device_request_setup_packet_t *,
  • uspace/lib/usbvirt/include/usbvirt/ipc.h

    rbd2394b rcc5908e  
    11/*
    2  * Copyright (c) 2010 Vojtech Horky
     2 * Copyright (c) 2011 Vojtech Horky
    33 * All rights reserved.
    44 *
     
    3131 */
    3232/** @file
    33  * @brief Virtual USB device.
     33 * IPC wrappers for virtual USB.
    3434 */
    3535#ifndef LIBUSBVIRT_IPC_H_
     
    4040#include <bool.h>
    4141
     42/** IPC methods communication between host controller and virtual device. */
    4243typedef enum {
    4344        IPC_M_USBVIRT_GET_NAME = IPC_FIRST_USER_METHOD + 80,
     
    4546        IPC_M_USBVIRT_CONTROL_WRITE,
    4647        IPC_M_USBVIRT_INTERRUPT_IN,
    47         IPC_M_USBVIRT_INTERRUPT_OUT
    48 } usbvirt_ipc_t;
     48        IPC_M_USBVIRT_INTERRUPT_OUT,
     49        IPC_M_USBVIRT_BULK_IN,
     50        IPC_M_USBVIRT_BULK_OUT
     51} usbvirt_hc_to_device_method_t;
    4952
    50 int usbvirt_ipc_send_control_read(int, usb_endpoint_t, void *, size_t,
     53int usbvirt_ipc_send_control_read(int, void *, size_t,
    5154    void *, size_t, size_t *);
    52 int usbvirt_ipc_send_control_write(int, usb_endpoint_t, void *, size_t,
     55int usbvirt_ipc_send_control_write(int, void *, size_t,
    5356    void *, size_t);
    5457int usbvirt_ipc_send_data_in(int, usb_endpoint_t, usb_transfer_type_t,
  • uspace/lib/usbvirt/src/ctrltransfer.c

    rbd2394b rcc5908e  
     1/*
     2 * Copyright (c) 2011 Vojtech Horky
     3 * All rights reserved.
     4 *
     5 * Redistribution and use in source and binary forms, with or without
     6 * modification, are permitted provided that the following conditions
     7 * are met:
     8 *
     9 * - Redistributions of source code must retain the above copyright
     10 *   notice, this list of conditions and the following disclaimer.
     11 * - Redistributions in binary form must reproduce the above copyright
     12 *   notice, this list of conditions and the following disclaimer in the
     13 *   documentation and/or other materials provided with the distribution.
     14 * - The name of the author may not be used to endorse or promote products
     15 *   derived from this software without specific prior written permission.
     16 *
     17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27 */
     28
     29/** @addtogroup libusbvirt
     30 * @{
     31 */
     32/** @file
     33 * Control transfer handling.
     34 */
    135#include "private.h"
    236#include <usb/request.h>
     
    539#include <errno.h>
    640
     41/** Find and execute control transfer handler for virtual USB device.
     42 *
     43 * @param dev Target virtual device.
     44 * @param control_handlers Array of control request handlers.
     45 * @param setup Setup packet.
     46 * @param data Extra data.
     47 * @param data_sent_size Size of extra data in bytes.
     48 * @return Error code.
     49 * @retval EFORWARD No suitable handler found.
     50 */
    751int process_control_transfer(usbvirt_device_t *dev,
    852    usbvirt_control_request_handler_t *control_handlers,
     
    5296        return EFORWARD;
    5397}
     98
     99
     100/**
     101 * @}
     102 */
  • uspace/lib/usbvirt/src/private.h

    rbd2394b rcc5908e  
     1/*
     2 * Copyright (c) 2011 Vojtech Horky
     3 * All rights reserved.
     4 *
     5 * Redistribution and use in source and binary forms, with or without
     6 * modification, are permitted provided that the following conditions
     7 * are met:
     8 *
     9 * - Redistributions of source code must retain the above copyright
     10 *   notice, this list of conditions and the following disclaimer.
     11 * - Redistributions in binary form must reproduce the above copyright
     12 *   notice, this list of conditions and the following disclaimer in the
     13 *   documentation and/or other materials provided with the distribution.
     14 * - The name of the author may not be used to endorse or promote products
     15 *   derived from this software without specific prior written permission.
     16 *
     17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27 */
     28
     29/** @addtogroup libusbvirt
     30 * @{
     31 */
     32/** @file
     33 * Private definitions.
     34 */
     35#ifndef USBVIRT_PRIVATE_H_
     36#define USBVIRT_PRIVATE_H_
     37
    138#include <usbvirt/device.h>
    239
     
    744
    845extern usbvirt_control_request_handler_t library_handlers[];
     46
     47#endif
     48/**
     49 * @}
     50 */
  • uspace/lib/usbvirt/src/stdreq.c

    rbd2394b rcc5908e  
     1/*
     2 * Copyright (c) 2011 Vojtech Horky
     3 * All rights reserved.
     4 *
     5 * Redistribution and use in source and binary forms, with or without
     6 * modification, are permitted provided that the following conditions
     7 * are met:
     8 *
     9 * - Redistributions of source code must retain the above copyright
     10 *   notice, this list of conditions and the following disclaimer.
     11 * - Redistributions in binary form must reproduce the above copyright
     12 *   notice, this list of conditions and the following disclaimer in the
     13 *   documentation and/or other materials provided with the distribution.
     14 * - The name of the author may not be used to endorse or promote products
     15 *   derived from this software without specific prior written permission.
     16 *
     17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27 */
     28
     29/** @addtogroup libusbvirt
     30 * @{
     31 */
     32/** @file
     33 * Standard control request handlers.
     34 */
    135#include "private.h"
    236#include <usb/request.h>
     
    438#include <errno.h>
    539
     40/** Helper for replying to control read transfer from virtual USB device.
     41 *
     42 * This function takes care of copying data to answer buffer taking care
     43 * of buffer sizes properly.
     44 *
     45 * @param setup_packet The setup packet.
     46 * @param data Data buffer to write to.
     47 * @param act_size Where to write actual size of returned data.
     48 * @param actual_data Data to be returned.
     49 * @param actual_data_size Size of answer data (@p actual_data) in bytes.
     50 */
    651void usbvirt_control_reply_helper(const usb_device_request_setup_packet_t *setup_packet,
    752    uint8_t *data, size_t *act_size,
     
    144189}
    145190
     191/** Standard request handlers. */
    146192usbvirt_control_request_handler_t library_handlers[] = {
    147193        {
     
    173219};
    174220
     221/**
     222 * @}
     223 */
  • uspace/lib/usbvirt/src/transfer.c

    rbd2394b rcc5908e  
    3131 */
    3232/** @file
    33  *
     33 * Transfer handling.
    3434 */
    3535#include <usbvirt/device.h>
     
    3939#include "private.h"
    4040
     41/** Process a control transfer to the virtual USB device.
     42 *
     43 * @param dev Target device.
     44 * @param setup Setup packet data.
     45 * @param setup_size Size of setup packet.
     46 * @param data Extra data (DATA stage).
     47 * @param data_size Size of extra data in bytes.
     48 * @param data_size_sent Number of actually send bytes during the transfer
     49 *      (only used for READ transfers).
     50 * @return Error code.
     51 */
    4152static int usbvirt_control_transfer(usbvirt_device_t *dev,
    4253    void *setup, size_t setup_size,
     
    7889}
    7990
     91/** Issue a control write transfer to virtual USB device.
     92 *
     93 * @see usbvirt_control_transfer
     94 *
     95 * @param dev Target virtual device.
     96 * @param setup Setup data.
     97 * @param setup_size Size of setup packet.
     98 * @param data Extra data (DATA stage).
     99 * @param data_size Size of extra data buffer in bytes.
     100 * @return Error code.
     101 */
    80102int usbvirt_control_write(usbvirt_device_t *dev, void *setup, size_t setup_size,
    81103    void *data, size_t data_size)
     
    85107}
    86108
     109/** Issue a control read transfer to virtual USB device.
     110 *
     111 * @see usbvirt_control_transfer
     112 *
     113 * @param dev Target virtual device.
     114 * @param setup Setup data.
     115 * @param setup_size Size of setup packet.
     116 * @param data Extra data (DATA stage).
     117 * @param data_size Size of extra data buffer in bytes.
     118 * @param data_size_sent Number of actually send bytes during the transfer.
     119 * @return Error code.
     120 */
    87121int usbvirt_control_read(usbvirt_device_t *dev, void *setup, size_t setup_size,
    88122    void *data, size_t data_size, size_t *data_size_sent)
     
    92126}
    93127
     128/** Send data to virtual USB device.
     129 *
     130 * @param dev Target virtual device.
     131 * @param transf_type Transfer type (interrupt, bulk).
     132 * @param endpoint Endpoint number.
     133 * @param data Data sent from the driver to the device.
     134 * @param data_size Size of the @p data buffer in bytes.
     135 * @return Error code.
     136 */
    94137int usbvirt_data_out(usbvirt_device_t *dev, usb_transfer_type_t transf_type,
    95138    usb_endpoint_t endpoint, void *data, size_t data_size)
     
    108151}
    109152
     153/** Request data from virtual USB device.
     154 *
     155 * @param dev Target virtual device.
     156 * @param transf_type Transfer type (interrupt, bulk).
     157 * @param endpoint Endpoint number.
     158 * @param data Where to stored data the device returns to the driver.
     159 * @param data_size Size of the @p data buffer in bytes.
     160 * @param data_size_sent Number of actually written bytes.
     161 * @return Error code.
     162 */
    110163int usbvirt_data_in(usbvirt_device_t *dev, usb_transfer_type_t transf_type,
    111164    usb_endpoint_t endpoint, void *data, size_t data_size, size_t *data_size_sent)
  • uspace/srv/devman/main.c

    rbd2394b rcc5908e  
    515515}
    516516
     517/** Find device path by its handle. */
     518static void devman_get_device_path_by_handle(ipc_callid_t iid,
     519    ipc_call_t *icall)
     520{
     521        devman_handle_t handle = IPC_GET_ARG1(*icall);
     522
     523        fun_node_t *fun = find_fun_node(&device_tree, handle);
     524        if (fun == NULL) {
     525                async_answer_0(iid, ENOMEM);
     526                return;
     527        }
     528
     529        ipc_callid_t data_callid;
     530        size_t data_len;
     531        if (!async_data_read_receive(&data_callid, &data_len)) {
     532                async_answer_0(iid, EINVAL);
     533                return;
     534        }
     535
     536        void *buffer = malloc(data_len);
     537        if (buffer == NULL) {
     538                async_answer_0(data_callid, ENOMEM);
     539                async_answer_0(iid, ENOMEM);
     540                return;
     541        }
     542
     543        size_t sent_length = str_size(fun->pathname);
     544        if (sent_length > data_len) {
     545                sent_length = data_len;
     546        }
     547
     548        async_data_read_finalize(data_callid, fun->pathname, sent_length);
     549        async_answer_0(iid, EOK);
     550
     551        free(buffer);
     552}
     553
    517554
    518555/** Function for handling connections from a client to the device manager. */
     
    536573                case DEVMAN_DEVICE_GET_HANDLE_BY_CLASS:
    537574                        devman_function_get_handle_by_class(callid, &call);
     575                        break;
     576                case DEVMAN_DEVICE_GET_DEVICE_PATH:
     577                        devman_get_device_path_by_handle(callid, &call);
    538578                        break;
    539579                default:
Note: See TracChangeset for help on using the changeset viewer.