Changeset 1866945 in mainline


Ignore:
Timestamp:
2011-05-07T13:47:48Z (13 years ago)
Author:
Matus Dekanek <smekideki@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
4d20ef7
Parents:
95285378 (diff), 6fb003e (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

merge with usb/development

Files:
3 added
10 deleted
32 edited
2 moved

Legend:

Unmodified
Added
Removed
  • boot/Makefile.common

    r95285378 r1866945  
    140140        $(USPACE_PATH)/app/stats/stats \
    141141        $(USPACE_PATH)/app/sysinfo/sysinfo \
    142         $(USPACE_PATH)/app/tasks/tasks \
    143142        $(USPACE_PATH)/app/top/top \
    144143        $(USPACE_PATH)/app/usbinfo/usbinfo \
    145         $(USPACE_PATH)/app/virtusbkbd/vuk \
    146144        $(USPACE_PATH)/app/vuhid/vuh \
    147145        $(USPACE_PATH)/app/websrv/websrv
  • uspace/Makefile

    r95285378 r1866945  
    5151        app/top \
    5252        app/usbinfo \
    53         app/virtusbkbd \
    5453        app/vuhid \
    5554        app/netecho \
  • uspace/app/vuhid/device.c

    r95285378 r1866945  
    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

    r95285378 r1866945  
    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

    r95285378 r1866945  
    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

    r95285378 r1866945  
    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/drv/ohci/hc.c

    r95285378 r1866945  
    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

    r95285378 r1866945  
    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

    r95285378 r1866945  
    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

    r95285378 r1866945  
    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;
     
    212209            "Failed(%d) to create root hub function.\n", ret);
    213210
    214         hc_register_hub(&instance->hc, instance->rh_fun);
    215211
    216212        instance->rh_fun->ops = &rh_ops;
    217213        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 
     214       
     215        device->driver_data = instance;
     216
     217        hc_start_hw(&instance->hc);
    222218        return EOK;
    223219#undef CHECK_RET_FINI_RETURN
  • uspace/drv/ohci/pci.c

    r95285378 r1866945  
    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/usbhid/generic/hiddev.c

    r95285378 r1866945  
    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

    r95285378 r1866945  
    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

    r95285378 r1866945  
    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

    r95285378 r1866945  
    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

    r95285378 r1866945  
    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

    r95285378 r1866945  
    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

    r95285378 r1866945  
    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/vhc/transfer.c

    r95285378 r1866945  
    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/usb/include/usb/classes/hiddescriptor.h

    r95285378 r1866945  
    7878uint32_t usb_hid_report_tag_data_uint32(const uint8_t *data, size_t size);
    7979
     80usb_hid_report_path_t *usb_hid_report_path_try_insert(usb_hid_report_t *report, usb_hid_report_path_t *cmp_path);
    8081#endif
    8182/**
  • uspace/lib/usb/include/usb/classes/hidpath.h

    r95285378 r1866945  
    4343 * Description of path of usage pages and usages in report descriptor
    4444 */
    45 #define USB_HID_PATH_COMPARE_STRICT                             0
    46 #define USB_HID_PATH_COMPARE_END                                1
    47 #define USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY    4
    48 #define USB_HID_PATH_COMPARE_COLLECTION_ONLY    2 /* porovnava jenom cestu z Kolekci */
     45/** Wanted usage path must be exactly the same as the searched one */
     46#define USB_HID_PATH_COMPARE_STRICT             0
     47/** Wanted usage path must be the suffix in the searched one */
     48#define USB_HID_PATH_COMPARE_END                1
     49/** */
     50#define USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY    2
     51/** Searched usage page must be prefix of the other one */
     52#define USB_HID_PATH_COMPARE_BEGIN              4
     53/** Searched couple of usage page and usage can be anywhere in usage path */
     54#define USB_HID_PATH_COMPARE_ANYWHERE           8
    4955
    5056
  • uspace/lib/usb/include/usb/classes/hidtypes.h

    r95285378 r1866945  
    165165        /** */ 
    166166        link_t link;
     167
     168        int in_delimiter;
    167169} usb_hid_report_item_t;
    168170
  • uspace/lib/usb/src/hiddescriptor.c

    r95285378 r1866945  
    4141#include <assert.h>
    4242
     43
     44#define OUTSIDE_DELIMITER_SET   0
     45#define START_DELIMITER_SET     1
     46#define INSIDE_DELIMITER_SET    2
     47       
    4348/** The new report item flag. Used to determine when the item is completly
    4449 * configured and should be added to the report structure
     
    5661#define USB_HID_UNKNOWN_TAG             -99
    5762
    58 
    59 /**
    60  * Initialize the report descriptor parser structure
    61  *
    62  * @param parser Report descriptor parser structure
    63  * @return Error code
    64  */
    65 int usb_hid_report_init(usb_hid_report_t *report)
    66 {
    67         if(report == NULL) {
    68                 return EINVAL;
    69         }
    70 
    71         memset(report, 0, sizeof(usb_hid_report_t));
    72         list_initialize(&report->reports);
    73         list_initialize(&report->collection_paths);
    74 
    75         report->use_report_ids = 0;
    76     return EOK;   
    77 }
    78 
    79 int usb_hid_report_append_fields(usb_hid_report_t *report, usb_hid_report_item_t *report_item)
    80 {
    81         usb_hid_report_field_t *field;
    82         int i;
    83 
    84 
     63usb_hid_report_path_t *usb_hid_report_path_try_insert(usb_hid_report_t *report, usb_hid_report_path_t *cmp_path)
     64{
    8565        /* find or append current collection path to the list */
    8666        link_t *path_it = report->collection_paths.next;
     
    8969                path = list_get_instance(path_it, usb_hid_report_path_t, link);
    9070               
    91                 if(usb_hid_report_compare_usage_path(path, report_item->usage_path, USB_HID_PATH_COMPARE_STRICT) == EOK){
     71                if(usb_hid_report_compare_usage_path(path, cmp_path, USB_HID_PATH_COMPARE_STRICT) == EOK){
    9272                        break;
    9373                }                       
     
    9575        }
    9676        if(path_it == &report->collection_paths) {
    97                 path = usb_hid_report_path_clone(report_item->usage_path);                     
     77                path = usb_hid_report_path_clone(cmp_path);                     
    9878                list_append(&path->link, &report->collection_paths);                                   
    9979                report->collection_paths_count++;
    100         }
     80
     81                return path;
     82        }
     83        else {
     84                return list_get_instance(path_it, usb_hid_report_path_t, link);
     85        }
     86}
     87
     88/**
     89 * Initialize the report descriptor parser structure
     90 *
     91 * @param parser Report descriptor parser structure
     92 * @return Error code
     93 */
     94int usb_hid_report_init(usb_hid_report_t *report)
     95{
     96        if(report == NULL) {
     97                return EINVAL;
     98        }
     99
     100        memset(report, 0, sizeof(usb_hid_report_t));
     101        list_initialize(&report->reports);
     102        list_initialize(&report->collection_paths);
     103
     104        report->use_report_ids = 0;
     105    return EOK;   
     106}
     107
     108
     109/*
     110 *
     111 *
     112 */
     113int usb_hid_report_append_fields(usb_hid_report_t *report, usb_hid_report_item_t *report_item)
     114{
     115        usb_hid_report_field_t *field;
     116        int i;
    101117
    102118        for(i=0; i<report_item->usages_count; i++){
     
    104120        }
    105121
    106        
     122        usb_hid_report_path_t *path = report_item->usage_path; 
    107123        for(i=0; i<report_item->count; i++){
    108124
     
    112128
    113129                /* fill the attributes */               
    114                 field->collection_path = path;
    115130                field->logical_minimum = report_item->logical_minimum;
    116131                field->logical_maximum = report_item->logical_maximum;
     
    129144                if(report_item->usages_count > 0 && ((report_item->usage_minimum == 0) && (report_item->usage_maximum == 0))) {
    130145                        uint32_t usage;
    131                         if(report_item->type != USB_HID_REPORT_TYPE_OUTPUT) {
    132                                 if(i < report_item->usages_count){
    133                                         usage = report_item->usages[i];
    134                                 }
    135                                 else {
    136                                         usage = report_item->usages[report_item->usages_count - 1];
    137                                 }
     146                        if(i < report_item->usages_count){
     147                                usage = report_item->usages[i];
    138148                        }
    139149                        else {
    140                                 if((report_item->count - i - 1) < report_item->usages_count){
    141                                         usage = report_item->usages[(report_item->count - i - 1)];
    142                                 }
    143                                 else {
    144                                         usage = report_item->usages[report_item->usages_count - 1];
    145                                 }
     150                                usage = report_item->usages[report_item->usages_count - 1];
    146151                        }
    147152
     
    159164
    160165                if((USB_HID_ITEM_FLAG_VARIABLE(report_item->item_flags) != 0) && (!((report_item->usage_minimum == 0) && (report_item->usage_maximum == 0)))) {
    161                         if(report_item->type == USB_HID_REPORT_TYPE_INPUT) {
    162                                 field->usage = report_item->usage_maximum - i;
    163                         }
    164                         else {
    165                                 field->usage = report_item->usage_minimum + i;                                 
    166                         }
    167 
    168                 }
    169                
     166                        field->usage = report_item->usage_minimum + i;                                 
     167                }
     168               
     169                usb_hid_report_set_last_item(path, USB_HID_TAG_CLASS_GLOBAL, field->usage_page);
     170                usb_hid_report_set_last_item(path, USB_HID_TAG_CLASS_LOCAL, field->usage);
     171
     172                field->collection_path = usb_hid_report_path_try_insert(report, path);
     173
    170174                field->size = report_item->size;
    171                 field->offset = report_item->offset + (i * report_item->size);
     175               
     176                size_t offset_byte = (report_item->offset + (i * report_item->size)) / 8;
     177                size_t offset_bit = 8 - ((report_item->offset + (i * report_item->size)) % 8) - report_item->size;
     178
     179                field->offset = 8 * offset_byte + offset_bit;
    172180                if(report_item->id != 0) {
    173181                        field->offset += 8;
     
    264272                return ENOMEM;
    265273        }
     274        usb_hid_report_path_append_item(usage_path, 0, 0);     
    266275       
    267276        while(i<size){ 
     
    349358                                        tmp_usage_path = list_get_instance(report_item->usage_path->link.prev, usb_hid_report_usage_path_t, link);
    350359                                       
    351                                         usb_hid_report_set_last_item(usage_path, tmp_usage_path->usage_page, tmp_usage_path->usage);
     360                                        usb_hid_report_set_last_item(usage_path, USB_HID_TAG_CLASS_GLOBAL, tmp_usage_path->usage_page);
     361                                        usb_hid_report_set_last_item(usage_path, USB_HID_TAG_CLASS_LOCAL, tmp_usage_path->usage);
    352362
    353363                                        usb_hid_report_path_free(report_item->usage_path);
     
    427437int usb_hid_report_parse_main_tag(uint8_t tag, const uint8_t *data, size_t item_size,
    428438                             usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path)
    429 {               
     439{
     440        usb_hid_report_usage_path_t *path_item;
     441       
    430442        switch(tag)
    431443        {
     
    438450                       
    439451                case USB_HID_REPORT_TAG_COLLECTION:
    440                         // TODO usage_path->flags = *data;
    441                         usb_hid_report_path_append_item(usage_path, report_item->usage_page, report_item->usages[report_item->usages_count-1]);                                         
     452                        // store collection atributes
     453                        path_item = list_get_instance(usage_path->head.prev, usb_hid_report_usage_path_t, link);
     454                        path_item->flags = *data;       
     455                       
     456                        // set last item
     457                        usb_hid_report_set_last_item(usage_path, USB_HID_TAG_CLASS_GLOBAL, report_item->usage_page);
     458                        usb_hid_report_set_last_item(usage_path, USB_HID_TAG_CLASS_LOCAL, report_item->usages[report_item->usages_count-1]);
     459                       
     460                        // append the new one which will be set by common
     461                        // usage/usage page
     462                        usb_hid_report_path_append_item(usage_path, report_item->usage_page, report_item->usages[report_item->usages_count-1]);
    442463                        usb_hid_report_reset_local_items (report_item);
    443464                        return USB_HID_NO_ACTION;
     
    530551                             usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path)
    531552{
    532         switch(tag)
    533         {
     553        switch(tag) {
    534554                case USB_HID_REPORT_TAG_USAGE:
    535                         report_item->usages[report_item->usages_count] = usb_hid_report_tag_data_uint32(data,item_size);
    536                         report_item->usages_count++;
     555                        switch(report_item->in_delimiter) {
     556                                case INSIDE_DELIMITER_SET:
     557                                        // nothing to do
     558                                        break;
     559                                case START_DELIMITER_SET:
     560                                        report_item->in_delimiter = INSIDE_DELIMITER_SET;
     561                                case OUTSIDE_DELIMITER_SET:
     562                                        report_item->usages[report_item->usages_count] = usb_hid_report_tag_data_uint32(data,item_size);
     563                                        report_item->usages_count++;
     564                                        break;
     565                        }
    537566                        break;
    538567                case USB_HID_REPORT_TAG_USAGE_MINIMUM:
     
    575604                        break;                 
    576605                case USB_HID_REPORT_TAG_DELIMITER:
    577                         //report_item->delimiter = usb_hid_report_tag_data_uint32(data,item_size);
    578                         //TODO:
    579                         //      DELIMITER STUFF
    580                         break;
    581                
     606                        report_item->in_delimiter = usb_hid_report_tag_data_uint32(data,item_size);
     607                        break;
     608
    582609                default:
    583610                        return USB_HID_NO_ACTION;
    584611        }
    585        
     612
    586613        return EOK;
    587614}
     
    629656
    630657                usb_log_debug("\t\tOFFSET: %X\n", report_item->offset);
    631                 usb_log_debug("\t\tSIZE: %zu\n", report_item->size);
     658                usb_log_debug("\t\tSIZE: %zu\n", report_item->size);                           
    632659                usb_log_debug("\t\tLOGMIN: %d\n", report_item->logical_minimum);
    633660                usb_log_debug("\t\tLOGMAX: %d\n", report_item->logical_maximum);               
     
    640667                usb_log_debug("\t\ttUSAGE: %X\n", report_item->usage);
    641668                usb_log_debug("\t\tUSAGE PAGE: %X\n", report_item->usage_page);
    642                                                
    643 //              usb_log_debug("\n");           
     669               
     670                //usb_hid_print_usage_path(report_item->collection_path);
     671
     672                usb_log_debug("\n");           
    644673
    645674        }
     
    666695                usb_log_debug("Report ID: %d\n", report_des->report_id);
    667696                usb_log_debug("\tType: %d\n", report_des->type);
    668                 usb_log_debug("\tLength: %zu\n", report_des->bit_length);
    669                 usb_log_debug("\tItems: %zu\n", report_des->item_length);
     697                usb_log_debug("\tLength: %zu\n", report_des->bit_length);               
     698                usb_log_debug("\tItems: %zu\n", report_des->item_length);               
    670699
    671700                usb_hid_descriptor_print_list(&report_des->report_items);
  • uspace/lib/usb/src/hidparser.c

    r95285378 r1866945  
    405405                                }
    406406
    407                                 size_t shift = offset%8;
     407                                size_t shift = 8 - offset%8 - length;
    408408
    409409                                value = value << shift;                                                 
  • uspace/lib/usb/src/hidpath.c

    r95285378 r1866945  
    149149                usb_log_debug("\tFLAGS: %d\n", path_item->flags);               
    150150               
    151                 item = item->next;
     151                item = item->next;
    152152        }
    153153}
     
    156156 * Compares two usage paths structures
    157157 *
    158  * If USB_HID_PATH_COMPARE_COLLECTION_ONLY flag is given, the last item in report_path structure is forgotten
    159  *
    160  * @param report_path usage path structure to compare
     158 *
     159 * @param report_path usage path structure to compare with @path
    161160 * @param path usage patrh structure to compare
    162161 * @param flags Flags determining the mode of comparison
     
    179178        }
    180179
     180        // Empty path match all others
    181181        if(path->depth == 0){
    182182                return EOK;
     
    189189       
    190190        switch(flags){
    191                 /* path must be completly identical */
     191                /* path is somewhere in report_path */
     192                case USB_HID_PATH_COMPARE_ANYWHERE:
     193                        if(path->depth != 1){
     194                                return 1;
     195                        }
     196
     197                        // projit skrz cestu a kdyz nekde sedi tak vratim EOK
     198                        // dojduli az za konec tak nnesedi
     199                        report_link = report_path->head.next;
     200                        path_link = path->head.next;
     201                        path_item = list_get_instance(path_link, usb_hid_report_usage_path_t, link);
     202
     203                        while(report_link != &report_path->head) {
     204                                report_item = list_get_instance(report_link, usb_hid_report_usage_path_t, link);
     205                                if(report_item->usage_page == path_item->usage_page){
     206                                        if(only_page == 0){
     207                                                if(report_item->usage == path_item->usage) {
     208                                                        return EOK;
     209                                                }
     210                                        }
     211                                        else {
     212                                                return EOK;
     213                                        }
     214                                }
     215
     216                                report_link = report_link->next;
     217                        }
     218
     219                        return 1;
     220                        break;
     221                /* the paths must be identical */
    192222                case USB_HID_PATH_COMPARE_STRICT:
    193223                                if(report_path->depth != path->depth){
    194224                                        return 1;
    195225                                }
    196 
     226               
     227                /* path is prefix of the report_path */
     228                case USB_HID_PATH_COMPARE_BEGIN:
     229       
    197230                                report_link = report_path->head.next;
    198231                                path_link = path->head.next;
     
    221254                                }
    222255
    223                                 if(((report_link == &report_path->head) && (path_link == &path->head)) ||
    224                                    (((flags & USB_HID_PATH_COMPARE_COLLECTION_ONLY) != 0) &&
    225                                     (path_link = &path->head) &&
    226                                     (report_link == report_path->head.prev))) {
     256                                if((((flags & USB_HID_PATH_COMPARE_BEGIN) != 0) && (path_link == &path->head)) ||
     257                                   ((report_link == &report_path->head) && (path_link == &path->head))) {
    227258                                        return EOK;
    228259                                }
     
    232263                        break;
    233264
    234                 /* compare with only the end of path*/
     265                /* path is suffix of report_path */
    235266                case USB_HID_PATH_COMPARE_END:
    236267
    237                                 if((flags & USB_HID_PATH_COMPARE_COLLECTION_ONLY) != 0) {
    238                                         report_link = report_path->head.prev->prev;
    239                                 }
    240                                 else {
    241                                         report_link = report_path->head.prev;
    242                                 }
     268                                report_link = report_path->head.prev;
    243269                                path_link = path->head.prev;
    244270
  • uspace/lib/usbvirt/Makefile

    r95285378 r1866945  
    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

    r95285378 r1866945  
    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

    r95285378 r1866945  
    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

    r95285378 r1866945  
     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

    r95285378 r1866945  
     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

    r95285378 r1866945  
     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

    r95285378 r1866945  
    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)
Note: See TracChangeset for help on using the changeset viewer.