Changeset a81a1d09 in mainline for uspace/drv


Ignore:
Timestamp:
2011-05-11T16:49:28Z (15 years ago)
Author:
Vojtech Horky <vojtechhorky@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
19387b61
Parents:
e1dbcbc (diff), 9212f8a (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge development/ changes

Location:
uspace/drv
Files:
57 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/ehci-hcd/Makefile

    re1dbcbc ra81a1d09  
    2828
    2929USPACE_PREFIX = ../..
    30 LIBS = $(LIBDRV_PREFIX)/libdrv.a $(LIBUSB_PREFIX)/libusb.a
    31 EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include -I$(LIBUSB_PREFIX)/include -I.
     30
     31LIBS = \
     32        $(LIBUSBHOST_PREFIX)/libusbhost.a \
     33        $(LIBUSB_PREFIX)/libusb.a \
     34        $(LIBDRV_PREFIX)/libdrv.a
     35EXTRA_CFLAGS += \
     36        -I$(LIBUSB_PREFIX)/include \
     37        -I$(LIBUSBHOST_PREFIX)/include \
     38        -I$(LIBDRV_PREFIX)/include
     39
    3240BINARY = ehci-hcd
    3341
  • uspace/drv/ehci-hcd/ehci-hcd.ma

    re1dbcbc ra81a1d09  
    2210 pci/ven=1002&dev=4386
    3310 pci/ven=1002&dev=4396
     410 pci/ven=1002&dev=4373
    4510 pci/ven=1022&dev=7463
    5610 pci/ven=1022&dev=7808
  • uspace/drv/ehci-hcd/hc_iface.c

    re1dbcbc ra81a1d09  
    106106}
    107107
     108/** Find device handle by USB address.
     109 *
     110 * @param[in] fun DDF function that was called.
     111 * @param[in] address Address in question.
     112 * @param[out] handle Where to store device handle if found.
     113 * @return Error code.
     114 */
     115static int find_by_address(ddf_fun_t *fun, usb_address_t address,
     116    devman_handle_t *handle)
     117{
     118        UNSUPPORTED("find_by_address");
     119
     120        return ENOTSUP;
     121}
     122
    108123/** Release previously requested address.
    109124 *
     
    321336        .request_address = request_address,
    322337        .bind_address = bind_address,
     338        .find_by_address = find_by_address,
    323339        .release_address = release_address,
    324340
  • uspace/drv/ehci-hcd/main.c

    re1dbcbc ra81a1d09  
    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/ehci-hcd/pci.c

    re1dbcbc ra81a1d09  
    5454
    5555#define CMD_OFFSET 0x0
    56 #define CONFIGFLAG_OFFSET 0x40
     56#define STS_OFFSET 0x4
     57#define CFG_OFFSET 0x40
    5758
    5859#define USBCMD_RUN 1
     
    186187        CHECK_RET_HANGUP_RETURN(ret, "Failed(%d) to read PCI config space.\n",
    187188            ret);
    188         usb_log_info("Register space BAR at %p:%" PRIxn ".\n", (void *) address, value);
     189        usb_log_info("Register space BAR at %p:%" PRIxn ".\n",
     190            (void *) address, value);
    189191
    190192        /* clear lower byte, it's not part of the BASE address */
     
    263265         * It would prevent pre-OS code from interfering. */
    264266        ret = async_req_3_0(parent_phone, DEV_IFACE_ID(PCI_DEV_IFACE),
    265            IPC_M_CONFIG_SPACE_WRITE_32, eecp + USBLEGCTLSTS_OFFSET, 0);
     267           IPC_M_CONFIG_SPACE_WRITE_32, eecp + USBLEGCTLSTS_OFFSET,
     268           0xe0000000);
    266269        CHECK_RET_HANGUP_RETURN(ret, "Failed(%d) zero USBLEGCTLSTS.\n", ret);
    267         usb_log_debug("Zeroed USBLEGCTLSTS register.\n");
    268270
    269271        /* Read again Legacy Support and Control register */
     
    290292        volatile uint32_t *usbcmd =
    291293            (uint32_t*)((uint8_t*)registers + operation_offset + CMD_OFFSET);
     294        volatile uint32_t *usbsts =
     295            (uint32_t*)((uint8_t*)registers + operation_offset + STS_OFFSET);
    292296        volatile uint32_t *usbconfigured =
    293             (uint32_t*)((uint8_t*)registers + operation_offset
    294             + CONFIGFLAG_OFFSET);
     297            (uint32_t*)((uint8_t*)registers + operation_offset + CFG_OFFSET);
    295298        usb_log_debug("USBCMD value: %x.\n", *usbcmd);
    296299        if (*usbcmd & USBCMD_RUN) {
    297300                *usbcmd = 0;
     301                while (!(*usbsts & (1 << 12))); /*wait until hc is halted */
    298302                *usbconfigured = 0;
    299303                usb_log_info("EHCI turned off.\n");
     
    301305                usb_log_info("EHCI was not running.\n");
    302306        }
     307        usb_log_debug("Registers: %x(0x00080000):%x(0x00001000):%x(0x0).\n",
     308            *usbcmd, *usbsts, *usbconfigured);
    303309
    304310        async_hangup(parent_phone);
  • uspace/drv/ohci/Makefile

    re1dbcbc ra81a1d09  
    2828
    2929USPACE_PREFIX = ../..
    30 LIBS = $(LIBDRV_PREFIX)/libdrv.a $(LIBUSB_PREFIX)/libusb.a
    31 EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include -I$(LIBUSB_PREFIX)/include -I.
     30
     31LIBS = \
     32        $(LIBUSBHOST_PREFIX)/libusbhost.a \
     33        $(LIBUSBDEV_PREFIX)/libusbdev.a \
     34        $(LIBUSB_PREFIX)/libusb.a \
     35        $(LIBDRV_PREFIX)/libdrv.a
     36EXTRA_CFLAGS += \
     37        -I$(LIBUSB_PREFIX)/include \
     38        -I$(LIBUSBDEV_PREFIX)/include \
     39        -I$(LIBUSBHOST_PREFIX)/include \
     40        -I$(LIBDRV_PREFIX)/include
     41
    3242BINARY = ohci
    3343
  • uspace/drv/ohci/hc.c

    re1dbcbc ra81a1d09  
    4040#include <usb/usb.h>
    4141#include <usb/ddfiface.h>
    42 #include <usb/usbdevice.h>
    4342
    4443#include "hc.h"
    4544#include "hcd_endpoint.h"
    4645
     46#define OHCI_USED_INTERRUPTS \
     47    (I_SO | I_WDH | I_UE | I_RHSC)
    4748static int interrupt_emulator(hc_t *instance);
    4849static void hc_gain_control(hc_t *instance);
    49 static void hc_init_hw(hc_t *instance);
    5050static int hc_init_transfer_lists(hc_t *instance);
    5151static int hc_init_memory(hc_t *instance);
     
    9090                usb_log_error("Failed add root hub match-id.\n");
    9191        }
     92        ret = ddf_fun_bind(hub_fun);
    9293        return ret;
    9394}
    9495/*----------------------------------------------------------------------------*/
    95 int hc_init(hc_t *instance, ddf_fun_t *fun, ddf_dev_t *dev,
    96     uintptr_t regs, size_t reg_size, bool interrupts)
     96int hc_init(hc_t *instance, uintptr_t regs, size_t reg_size, bool interrupts)
    9797{
    9898        assert(instance);
     
    109109            ret, str_error(ret));
    110110
     111        list_initialize(&instance->pending_batches);
    111112        usb_device_keeper_init(&instance->manager);
    112113        ret = usb_endpoint_manager_init(&instance->ep_manager,
     
    115116            str_error(ret));
    116117
    117         hc_gain_control(instance);
    118118        ret = hc_init_memory(instance);
    119119        CHECK_RET_RETURN(ret, "Failed to create OHCI memory structures: %s.\n",
    120120            str_error(ret));
    121         hc_init_hw(instance);
     121#undef CHECK_RET_RETURN
     122
     123
     124//      hc_init_hw(instance);
     125        hc_gain_control(instance);
    122126        fibril_mutex_initialize(&instance->guard);
    123127
     
    130134        }
    131135
    132         list_initialize(&instance->pending_batches);
    133 #undef CHECK_RET_RETURN
    134136        return EOK;
    135137}
     
    285287{
    286288        assert(instance);
    287         if ((status & ~IS_SF) == 0) /* ignore sof status */
     289        usb_log_debug("OHCI(%p) interrupt: %x.\n", instance, status);
     290        if ((status & ~I_SF) == 0) /* ignore sof status */
    288291                return;
    289         if (status & IS_RHSC)
     292        if (status & I_RHSC)
    290293                rh_interrupt(&instance->rh);
    291294
    292         usb_log_debug("OHCI interrupt: %x.\n", status);
    293 
    294         if (status & IS_WDH) {
     295
     296        if (status & I_WDH) {
    295297                fibril_mutex_lock(&instance->guard);
    296298                usb_log_debug2("HCCA: %p-%#" PRIx32 " (%p).\n", instance->hcca,
     
    332334{
    333335        assert(instance);
     336        usb_log_debug("Requesting OHCI control.\n");
    334337        /* Turn off legacy emulation */
    335338        volatile uint32_t *ohci_emulation_reg =
    336339            (uint32_t*)((char*)instance->registers + 0x100);
    337340        usb_log_debug("OHCI legacy register %p: %x.\n",
    338                 ohci_emulation_reg, *ohci_emulation_reg);
    339         *ohci_emulation_reg = 0;
     341            ohci_emulation_reg, *ohci_emulation_reg);
     342        /* Do not change A20 state */
     343        *ohci_emulation_reg &= 0x100;
     344        usb_log_debug("OHCI legacy register %p: %x.\n",
     345            ohci_emulation_reg, *ohci_emulation_reg);
    340346
    341347        /* Interrupt routing enabled => smm driver is active */
     
    347353                }
    348354                usb_log_info("SMM driver: Ownership taken.\n");
     355                instance->registers->control &= (C_HCFS_RESET << C_HCFS_SHIFT);
     356                async_usleep(50000);
    349357                return;
    350358        }
     
    372380}
    373381/*----------------------------------------------------------------------------*/
    374 void hc_init_hw(hc_t *instance)
     382void hc_start_hw(hc_t *instance)
    375383{
    376384        /* OHCI guide page 42 */
     
    421429            instance->registers->control);
    422430
    423         /* Disable interrupts */
    424         instance->registers->interrupt_disable = I_SF | I_OC;
    425         usb_log_debug2("Disabling interrupts: %x.\n",
    426             instance->registers->interrupt_disable);
    427         instance->registers->interrupt_disable = I_MI;
     431        /* Enable interrupts */
     432        instance->registers->interrupt_enable = OHCI_USED_INTERRUPTS;
    428433        usb_log_debug2("Enabled interrupts: %x.\n",
    429434            instance->registers->interrupt_enable);
     435        instance->registers->interrupt_enable = I_MI;
    430436
    431437        /* Set periodic start to 90% */
     
    473479{
    474480        assert(instance);
     481
     482        bzero(&instance->rh, sizeof(instance->rh));
    475483        /* Init queues */
    476484        hc_init_transfer_lists(instance);
     
    492500            instance->lists[USB_TRANSFER_INTERRUPT].list_head_pa);
    493501
     502        /* Init interrupt code */
     503        instance->interrupt_code.cmds = instance->interrupt_commands;
     504        {
     505                /* Read status register */
     506                instance->interrupt_commands[0].cmd = CMD_MEM_READ_32;
     507                instance->interrupt_commands[0].dstarg = 1;
     508                instance->interrupt_commands[0].addr =
     509                    (void*)&instance->registers->interrupt_status;
     510
     511                /* Test whether we are the interrupt cause */
     512                instance->interrupt_commands[1].cmd = CMD_BTEST;
     513                instance->interrupt_commands[1].value =
     514                    OHCI_USED_INTERRUPTS;
     515                instance->interrupt_commands[1].srcarg = 1;
     516                instance->interrupt_commands[1].dstarg = 2;
     517
     518                /* Predicate cleaning and accepting */
     519                instance->interrupt_commands[2].cmd = CMD_PREDICATE;
     520                instance->interrupt_commands[2].value = 2;
     521                instance->interrupt_commands[2].srcarg = 2;
     522
     523                /* Write clean status register */
     524                instance->interrupt_commands[3].cmd = CMD_MEM_WRITE_A_32;
     525                instance->interrupt_commands[3].srcarg = 1;
     526                instance->interrupt_commands[3].addr =
     527                    (void*)&instance->registers->interrupt_status;
     528
     529                /* Accept interrupt */
     530                instance->interrupt_commands[4].cmd = CMD_ACCEPT;
     531
     532                instance->interrupt_code.cmdcount = OHCI_NEEDED_IRQ_COMMANDS;
     533        }
     534
    494535        return EOK;
    495536}
  • uspace/drv/ohci/hc.h

    re1dbcbc ra81a1d09  
    5151#include "hw_struct/hcca.h"
    5252
     53#define OHCI_NEEDED_IRQ_COMMANDS 5
     54
    5355typedef struct hc {
    5456        ohci_regs_t *registers;
     
    6567        fid_t interrupt_emulator;
    6668        fibril_mutex_t guard;
     69
     70        /** Code to be executed in kernel interrupt handler */
     71        irq_code_t interrupt_code;
     72
     73        /** Commands that form interrupt code */
     74        irq_cmd_t interrupt_commands[OHCI_NEEDED_IRQ_COMMANDS];
    6775} hc_t;
    6876
    6977int hc_register_hub(hc_t *instance, ddf_fun_t *hub_fun);
    7078
    71 int hc_init(hc_t *instance, ddf_fun_t *fun, ddf_dev_t *dev,
    72      uintptr_t regs, size_t reg_size, bool interrupts);
     79int hc_init(hc_t *instance, uintptr_t regs, size_t reg_size, bool interrupts);
     80
     81void hc_start_hw(hc_t *instance);
    7382
    7483/** Safely dispose host controller internal structures
  • uspace/drv/ohci/hw_struct/endpoint_descriptor.h

    re1dbcbc ra81a1d09  
    4040#include <usb/host/endpoint.h>
    4141
    42 #include "utils/malloc32.h"
     42#include "../utils/malloc32.h"
    4343#include "transfer_descriptor.h"
    4444
  • uspace/drv/ohci/hw_struct/transfer_descriptor.c

    re1dbcbc ra81a1d09  
    3333 */
    3434#include <usb/usb.h>
    35 #include "utils/malloc32.h"
    36 
    3735#include "transfer_descriptor.h"
    3836
  • uspace/drv/ohci/hw_struct/transfer_descriptor.h

    re1dbcbc ra81a1d09  
    3737#include <bool.h>
    3838#include <stdint.h>
    39 #include "utils/malloc32.h"
     39#include "../utils/malloc32.h"
    4040
    4141#include "completion_codes.h"
  • uspace/drv/ohci/iface.c

    re1dbcbc ra81a1d09  
    122122        return EOK;
    123123}
     124
     125
     126/** Find device handle by address interface function.
     127 *
     128 * @param[in] fun DDF function that was called.
     129 * @param[in] address Address in question.
     130 * @param[out] handle Where to store device handle if found.
     131 * @return Error code.
     132 */
     133static int find_by_address(ddf_fun_t *fun, usb_address_t address,
     134    devman_handle_t *handle)
     135{
     136        assert(fun);
     137        hc_t *hc = fun_to_hc(fun);
     138        assert(hc);
     139        bool found =
     140            usb_device_keeper_find_by_address(&hc->manager, address, handle);
     141        return found ? EOK : ENOENT;
     142}
     143
    124144/*----------------------------------------------------------------------------*/
    125145/** Release address interface function
     
    402422        .request_address = request_address,
    403423        .bind_address = bind_address,
     424        .find_by_address = find_by_address,
    404425        .release_address = release_address,
    405426
  • uspace/drv/ohci/main.c

    re1dbcbc ra81a1d09  
    4343#define NAME "ohci"
    4444
    45 static int ohci_add_device(ddf_dev_t *device);
     45/** Initializes a new ddf driver instance of OHCI hcd.
     46 *
     47 * @param[in] device DDF instance of the device to initialize.
     48 * @return Error code.
     49 */
     50static int ohci_add_device(ddf_dev_t *device)
     51{
     52        usb_log_debug("ohci_add_device() called\n");
     53        assert(device);
     54
     55        int ret = device_setup_ohci(device);
     56        if (ret != EOK) {
     57                usb_log_error("Failed to initialize OHCI driver: %s.\n",
     58                    str_error(ret));
     59                return ret;
     60        }
     61        usb_log_info("Controlling new OHCI device '%s'.\n", device->name);
     62
     63        return EOK;
     64}
    4665/*----------------------------------------------------------------------------*/
    4766static driver_ops_t ohci_driver_ops = {
     
    5372        .driver_ops = &ohci_driver_ops
    5473};
    55 /*----------------------------------------------------------------------------*/
    56 /** Initializes a new ddf driver instance of OHCI hcd.
    57  *
    58  * @param[in] device DDF instance of the device to initialize.
    59  * @return Error code.
    60  */
    61 int ohci_add_device(ddf_dev_t *device)
    62 {
    63         usb_log_debug("ohci_add_device() called\n");
    64         assert(device);
    65         ohci_t *ohci = malloc(sizeof(ohci_t));
    66         if (ohci == NULL) {
    67                 usb_log_error("Failed to allocate OHCI driver.\n");
    68                 return ENOMEM;
    69         }
    70 
    71         int ret = ohci_init(ohci, device);
    72         if (ret != EOK) {
    73                 usb_log_error("Failed to initialize OHCI driver: %s.\n",
    74                     str_error(ret));
    75                 return ret;
    76         }
    77         device->driver_data = ohci;
    78 
    79         usb_log_info("Controlling new OHCI device `%s'.\n", device->name);
    80 
    81         return EOK;
    82 }
    8374/*----------------------------------------------------------------------------*/
    8475/** Initializes global driver structures (NONE).
     
    9384{
    9485        usb_log_enable(USB_LOG_LEVEL_DEFAULT, NAME);
    95         sleep(5);
    9686        return ddf_driver_main(&ohci_driver);
    9787}
  • uspace/drv/ohci/ohci.c

    re1dbcbc ra81a1d09  
    4444#include "iface.h"
    4545#include "pci.h"
     46#include "hc.h"
     47#include "root_hub.h"
     48
     49typedef struct ohci {
     50        ddf_fun_t *hc_fun;
     51        ddf_fun_t *rh_fun;
     52
     53        hc_t hc;
     54        rh_t rh;
     55} ohci_t;
     56
     57static inline ohci_t * dev_to_ohci(ddf_dev_t *dev)
     58{
     59        assert(dev);
     60        assert(dev->driver_data);
     61        return dev->driver_data;
     62}
    4663
    4764/** IRQ handling callback, identifies device
     
    5370static void irq_handler(ddf_dev_t *dev, ipc_callid_t iid, ipc_call_t *call)
    5471{
    55         assert(dev);
    56         hc_t *hc = &((ohci_t*)dev->driver_data)->hc;
    57         uint16_t status = IPC_GET_ARG1(*call);
     72        hc_t *hc = &dev_to_ohci(dev)->hc;
    5873        assert(hc);
     74        const uint16_t status = IPC_GET_ARG1(*call);
    5975        hc_interrupt(hc, status);
    6076}
     
    7086{
    7187        assert(fun);
    72         usb_device_keeper_t *manager = &((ohci_t*)fun->dev->driver_data)->hc.manager;
     88        usb_device_keeper_t *manager = &dev_to_ohci(fun->dev)->hc.manager;
    7389
    7490        usb_address_t addr = usb_device_keeper_find(manager, handle);
     
    93109    ddf_fun_t *fun, devman_handle_t *handle)
    94110{
    95         assert(handle);
    96         ddf_fun_t *hc_fun = ((ohci_t*)fun->dev->driver_data)->hc_fun;
    97         assert(hc_fun != NULL);
    98 
    99         *handle = hc_fun->handle;
     111        assert(fun);
     112        ddf_fun_t *hc_fun = dev_to_ohci(fun->dev)->hc_fun;
     113        assert(hc_fun);
     114
     115        if (handle != NULL)
     116                *handle = hc_fun->handle;
    100117        return EOK;
    101118}
    102119/*----------------------------------------------------------------------------*/
    103 /** This iface is generic for both RH and HC. */
     120/** Root hub USB interface */
    104121static usb_iface_t usb_iface = {
    105122        .get_hc_handle = usb_iface_get_hc_handle,
     
    107124};
    108125/*----------------------------------------------------------------------------*/
     126/** Standard USB HC options (HC interface) */
    109127static ddf_dev_ops_t hc_ops = {
    110128        .interfaces[USBHC_DEV_IFACE] = &hc_iface, /* see iface.h/c */
    111129};
    112130/*----------------------------------------------------------------------------*/
     131/** Standard USB RH options (RH interface) */
    113132static ddf_dev_ops_t rh_ops = {
    114133        .interfaces[USB_DEV_IFACE] = &usb_iface,
     
    117136/** Initialize hc and rh ddf structures and their respective drivers.
    118137 *
     138 * @param[in] device DDF instance of the device to use.
    119139 * @param[in] instance OHCI structure to use.
    120  * @param[in] device DDF instance of the device to use.
    121140 *
    122141 * This function does all the preparatory work for hc and rh drivers:
     
    126145 *  - registers interrupt handler
    127146 */
    128 int ohci_init(ohci_t *instance, ddf_dev_t *device)
    129 {
    130         assert(instance);
    131         instance->hc_fun = NULL;
     147int device_setup_ohci(ddf_dev_t *device)
     148{
     149        ohci_t *instance = malloc(sizeof(ohci_t));
     150        if (instance == NULL) {
     151                usb_log_error("Failed to allocate OHCI driver.\n");
     152                return ENOMEM;
     153        }
     154
     155#define CHECK_RET_DEST_FREE_RETURN(ret, message...) \
     156if (ret != EOK) { \
     157        if (instance->hc_fun) { \
     158                instance->hc_fun->ops = NULL; \
     159                instance->hc_fun->driver_data = NULL; \
     160                ddf_fun_destroy(instance->hc_fun); \
     161        } \
     162        if (instance->rh_fun) { \
     163                instance->rh_fun->ops = NULL; \
     164                instance->rh_fun->driver_data = NULL; \
     165                ddf_fun_destroy(instance->rh_fun); \
     166        } \
     167        free(instance); \
     168        usb_log_error(message); \
     169        return ret; \
     170} else (void)0
     171
    132172        instance->rh_fun = NULL;
    133 #define CHECK_RET_DEST_FUN_RETURN(ret, message...) \
    134 if (ret != EOK) { \
    135         usb_log_error(message); \
    136         if (instance->hc_fun) \
    137                 ddf_fun_destroy(instance->hc_fun); \
    138         if (instance->rh_fun) \
    139                 ddf_fun_destroy(instance->rh_fun); \
    140         return ret; \
    141 }
    142 
    143         uintptr_t mem_reg_base = 0;
    144         size_t mem_reg_size = 0;
     173        instance->hc_fun = ddf_fun_create(device, fun_exposed, "ohci-hc");
     174        int ret = instance->hc_fun ? EOK : ENOMEM;
     175        CHECK_RET_DEST_FREE_RETURN(ret, "Failed to create OHCI HC function.\n");
     176        instance->hc_fun->ops = &hc_ops;
     177        instance->hc_fun->driver_data = &instance->hc;
     178
     179        instance->rh_fun = ddf_fun_create(device, fun_inner, "ohci-rh");
     180        ret = instance->rh_fun ? EOK : ENOMEM;
     181        CHECK_RET_DEST_FREE_RETURN(ret, "Failed to create OHCI RH function.\n");
     182        instance->rh_fun->ops = &rh_ops;
     183
     184        uintptr_t reg_base = 0;
     185        size_t reg_size = 0;
    145186        int irq = 0;
    146187
    147         int ret =
    148             pci_get_my_registers(device, &mem_reg_base, &mem_reg_size, &irq);
    149         CHECK_RET_DEST_FUN_RETURN(ret,
     188        ret = pci_get_my_registers(device, &reg_base, &reg_size, &irq);
     189        CHECK_RET_DEST_FREE_RETURN(ret,
    150190            "Failed to get memory addresses for %" PRIun ": %s.\n",
    151191            device->handle, str_error(ret));
    152192        usb_log_debug("Memory mapped regs at %p (size %zu), IRQ %d.\n",
    153             (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));
     193            (void *) reg_base, reg_size, irq);
    158194
    159195        bool interrupts = false;
    160196#ifdef CONFIG_USBHC_NO_INTERRUPTS
    161         usb_log_warning("Interrupts disabled in OS config, " \
     197        usb_log_warning("Interrupts disabled in OS config, "
    162198            "falling back to polling.\n");
    163199#else
     
    166202                usb_log_warning("Failed to enable interrupts: %s.\n",
    167203                    str_error(ret));
    168                 usb_log_info("HW interrupts not available, " \
     204                usb_log_info("HW interrupts not available, "
    169205                    "falling back to polling.\n");
    170206        } else {
     
    174210#endif
    175211
    176         instance->hc_fun = ddf_fun_create(device, fun_exposed, "ohci-hc");
    177         ret = (instance->hc_fun == NULL) ? ENOMEM : EOK;
    178         CHECK_RET_DEST_FUN_RETURN(ret,
    179             "Failed(%d) to create HC function.\n", ret);
    180 
    181         ret = hc_init(&instance->hc, instance->hc_fun, device,
    182             mem_reg_base, mem_reg_size, interrupts);
    183         CHECK_RET_DEST_FUN_RETURN(ret, "Failed(%d) to init ohci-hcd.\n", ret);
    184         instance->hc_fun->ops = &hc_ops;
    185         instance->hc_fun->driver_data = &instance->hc;
     212        ret = hc_init(&instance->hc, reg_base, reg_size, interrupts);
     213        CHECK_RET_DEST_FREE_RETURN(ret, "Failed(%d) to init ohci-hcd.\n", ret);
     214
     215#define CHECK_RET_FINI_RETURN(ret, message...) \
     216if (ret != EOK) { \
     217        hc_fini(&instance->hc); \
     218        CHECK_RET_DEST_FREE_RETURN(ret, message); \
     219} else (void)0
     220
     221        /* It does no harm if we register this on polling */
     222        ret = register_interrupt_handler(device, irq, irq_handler,
     223            &instance->hc.interrupt_code);
     224        CHECK_RET_FINI_RETURN(ret,
     225            "Failed(%d) to register interrupt handler.\n", ret);
     226
    186227        ret = ddf_fun_bind(instance->hc_fun);
    187         CHECK_RET_DEST_FUN_RETURN(ret,
     228        CHECK_RET_FINI_RETURN(ret,
    188229            "Failed(%d) to bind OHCI device function: %s.\n",
    189230            ret, str_error(ret));
    190 #undef CHECK_RET_HC_RETURN
    191 
    192 #define CHECK_RET_FINI_RETURN(ret, message...) \
    193 if (ret != EOK) { \
    194         usb_log_error(message); \
    195         if (instance->hc_fun) \
    196                 ddf_fun_destroy(instance->hc_fun); \
    197         if (instance->rh_fun) \
    198                 ddf_fun_destroy(instance->rh_fun); \
    199         hc_fini(&instance->hc); \
    200         return ret; \
    201 }
    202 
    203         /* It does no harm if we register this on polling */
    204         ret = register_interrupt_handler(device, irq, irq_handler, NULL);
     231
     232        ret = ddf_fun_add_to_class(instance->hc_fun, USB_HC_DDF_CLASS_NAME);
    205233        CHECK_RET_FINI_RETURN(ret,
    206             "Failed(%d) to register interrupt handler.\n", ret);
    207 
    208         instance->rh_fun = ddf_fun_create(device, fun_inner, "ohci-rh");
    209         ret = (instance->rh_fun == NULL) ? ENOMEM : EOK;
    210         CHECK_RET_FINI_RETURN(ret,
    211             "Failed(%d) to create root hub function.\n", ret);
    212 
     234            "Failed to add OHCI to HC class: %s.\n", str_error(ret));
     235
     236        device->driver_data = instance;
     237
     238        hc_start_hw(&instance->hc);
    213239        hc_register_hub(&instance->hc, instance->rh_fun);
    214 
    215         instance->rh_fun->ops = &rh_ops;
    216         instance->rh_fun->driver_data = NULL;
    217         ret = ddf_fun_bind(instance->rh_fun);
    218         CHECK_RET_FINI_RETURN(ret,
    219             "Failed(%d) to register OHCI root hub.\n", ret);
    220 
    221240        return EOK;
     241
     242#undef CHECK_RET_DEST_FUN_RETURN
    222243#undef CHECK_RET_FINI_RETURN
    223244}
  • uspace/drv/ohci/ohci.h

    re1dbcbc ra81a1d09  
    3838#include <ddf/driver.h>
    3939
    40 #include "hc.h"
    41 #include "root_hub.h"
    42 
    43 typedef struct ohci {
    44         ddf_fun_t *hc_fun;
    45         ddf_fun_t *rh_fun;
    46 
    47         hc_t hc;
    48         rh_t rh;
    49 } ohci_t;
    50 
    51 int ohci_init(ohci_t *instance, ddf_dev_t *device);
     40int device_setup_ohci(ddf_dev_t *device);
    5241
    5342#endif
  • uspace/drv/ohci/ohci.ma

    re1dbcbc ra81a1d09  
    1110 pci/ven=106b&dev=003f
    2210 pci/ven=10de&dev=0aa5
    3 10 pci/ven=10de&dev=0aa5
     3
     410 pci/ven=1002&dev=4374
     510 pci/ven=1002&dev=4375
     6
     710 pci/ven=1002&dev=4387
     810 pci/ven=1002&dev=4388
     910 pci/ven=1002&dev=4389
     1010 pci/ven=1002&dev=438a
     1110 pci/ven=1002&dev=438b
  • uspace/drv/ohci/ohci_regs.h

    re1dbcbc ra81a1d09  
    7272#define CS_SOC_SHIFT (16)
    7373
     74        /** Interupt enable/disable/status,
     75         * reads give the same value,
     76         * writing causes enable/disable,
     77         * status is write-clean (writing 1 clears the bit*/
    7478        volatile uint32_t interrupt_status;
    75 #define IS_SO   (1 << 0)  /* Scheduling overrun */
    76 #define IS_WDH  (1 << 1)  /* Write-back done head */
    77 #define IS_SF   (1 << 2)  /* Start of frame */
    78 #define IS_RD   (1 << 3)  /* Resume detected */
    79 #define IS_UE   (1 << 4)  /* Unrecoverable error */
    80 #define IS_FNO  (1 << 5)  /* Frame number overflow */
    81 #define IS_RHSC (1 << 6)  /* Root hub status change */
    82 #define IS_OC   (1 << 30) /* Ownership change */
    83 
    84         /** Interupt enable/disable, reads give the same value, writing causes
    85          * enable/disable */
    8679        volatile uint32_t interrupt_enable;
    8780        volatile uint32_t interrupt_disable;
  • uspace/drv/ohci/pci.c

    re1dbcbc ra81a1d09  
    4747#include "pci.h"
    4848
    49 #define PAGE_SIZE_MASK 0xfffff000
    50 
    51 #define HCC_PARAMS_OFFSET 0x8
    52 #define HCC_PARAMS_EECP_MASK 0xff
    53 #define HCC_PARAMS_EECP_OFFSET 8
    54 
    55 #define CMD_OFFSET 0x0
    56 #define CONFIGFLAG_OFFSET 0x40
    57 
    58 #define USBCMD_RUN 1
    59 
    60 #define USBLEGSUP_OFFSET 0
    61 #define USBLEGSUP_BIOS_CONTROL (1 << 16)
    62 #define USBLEGSUP_OS_CONTROL (1 << 24)
    63 #define USBLEGCTLSTS_OFFSET 4
    64 
    65 #define DEFAULT_WAIT 10000
    66 #define WAIT_STEP 10
    67 
    6849/** Get address of registers and IRQ for given device.
    6950 *
     
    7758    uintptr_t *mem_reg_address, size_t *mem_reg_size, int *irq_no)
    7859{
    79         assert(dev != NULL);
     60        assert(dev);
     61        assert(mem_reg_address);
     62        assert(mem_reg_size);
     63        assert(irq_no);
    8064
    8165        int parent_phone = devman_parent_device_connect(dev->handle,
     
    146130int pci_enable_interrupts(ddf_dev_t *device)
    147131{
    148         return ENOTSUP;
    149132        int parent_phone =
    150133            devman_parent_device_connect(device->handle, IPC_FLAG_BLOCKING);
     
    156139        return enabled ? EOK : EIO;
    157140}
    158 /*----------------------------------------------------------------------------*/
    159 /** Implements BIOS handoff routine as decribed in OHCI spec
    160  *
    161  * @param[in] device Device asking for interrupts
    162  * @return Error code.
    163  */
    164 int pci_disable_legacy(ddf_dev_t *device)
    165 {
    166         /* TODO: implement */
    167         return EOK;
    168 }
    169 /*----------------------------------------------------------------------------*/
    170141/**
    171142 * @}
  • uspace/drv/ohci/root_hub.c

    re1dbcbc ra81a1d09  
    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 %zu 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

    re1dbcbc ra81a1d09  
    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/Makefile

    re1dbcbc ra81a1d09  
    2828
    2929USPACE_PREFIX = ../..
    30 LIBS = $(LIBDRV_PREFIX)/libdrv.a $(LIBUSB_PREFIX)/libusb.a
    31 EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include -I$(LIBUSB_PREFIX)/include -I.
     30
     31LIBS = \
     32        $(LIBUSBHOST_PREFIX)/libusbhost.a \
     33        $(LIBUSB_PREFIX)/libusb.a \
     34        $(LIBDRV_PREFIX)/libdrv.a
     35EXTRA_CFLAGS += \
     36        -I$(LIBUSB_PREFIX)/include \
     37        -I$(LIBUSBHOST_PREFIX)/include \
     38        -I$(LIBDRV_PREFIX)/include
     39
    3240BINARY = uhci-hcd
    3341
  • uspace/drv/uhci-hcd/hc.c

    re1dbcbc ra81a1d09  
    6060 *
    6161 * @param[in] instance Memory place to initialize.
    62  * @param[in] fun DDF function.
    6362 * @param[in] regs Address of I/O control registers.
    6463 * @param[in] size Size of I/O control registers.
     
    6968 * interrupt fibrils.
    7069 */
    71 int hc_init(hc_t *instance, ddf_fun_t *fun,
    72     void *regs, size_t reg_size, bool interrupts)
     70int hc_init(hc_t *instance, void *regs, size_t reg_size, bool interrupts)
    7371{
    7472        assert(reg_size >= sizeof(regs_t));
  • uspace/drv/uhci-hcd/hc.h

    re1dbcbc ra81a1d09  
    136136} hc_t;
    137137
    138 int hc_init(hc_t *instance, ddf_fun_t *fun,
    139     void *regs, size_t reg_size, bool interupts);
     138int hc_init(hc_t *instance, void *regs, size_t reg_size, bool interupts);
    140139
    141140int hc_schedule(hc_t *instance, usb_transfer_batch_t *batch);
  • uspace/drv/uhci-hcd/hw_struct/queue_head.h

    re1dbcbc ra81a1d09  
    3838#include "link_pointer.h"
    3939#include "transfer_descriptor.h"
    40 #include "utils/malloc32.h"
     40#include "../utils/malloc32.h"
    4141
    4242/** This structure is defined in UHCI design guide p. 31 */
  • uspace/drv/uhci-hcd/hw_struct/transfer_descriptor.c

    re1dbcbc ra81a1d09  
    3636
    3737#include "transfer_descriptor.h"
    38 #include "utils/malloc32.h"
     38#include "../utils/malloc32.h"
    3939
    4040/** Initialize Transfer Descriptor
  • uspace/drv/uhci-hcd/iface.c

    re1dbcbc ra81a1d09  
    122122        return EOK;
    123123}
     124
     125/** Find device handle by address interface function.
     126 *
     127 * @param[in] fun DDF function that was called.
     128 * @param[in] address Address in question.
     129 * @param[out] handle Where to store device handle if found.
     130 * @return Error code.
     131 */
     132static int find_by_address(ddf_fun_t *fun, usb_address_t address,
     133    devman_handle_t *handle)
     134{
     135        assert(fun);
     136        hc_t *hc = fun_to_hc(fun);
     137        assert(hc);
     138        bool found =
     139            usb_device_keeper_find_by_address(&hc->manager, address, handle);
     140        return found ? EOK : ENOENT;
     141}
     142
    124143/*----------------------------------------------------------------------------*/
    125144/** Release address interface function
     
    352371        .request_address = request_address,
    353372        .bind_address = bind_address,
     373        .find_by_address = find_by_address,
    354374        .release_address = release_address,
    355375
  • uspace/drv/uhci-hcd/main.c

    re1dbcbc ra81a1d09  
    6464        assert(device);
    6565
    66         uhci_t *uhci = malloc(sizeof(uhci_t));
    67         if (uhci == NULL) {
    68                 usb_log_error("Failed to allocate UHCI driver.\n");
    69                 return ENOMEM;
    70         }
    71 
    72         int ret = uhci_init(uhci, device);
     66        int ret = device_setup_uhci(device);
    7367        if (ret != EOK) {
    7468                usb_log_error("Failed to initialize UHCI driver: %s.\n",
     
    7670                return ret;
    7771        }
    78         device->driver_data = uhci;
    79 
    8072        usb_log_info("Controlling new UHCI device '%s'.\n", device->name);
    8173
  • uspace/drv/uhci-hcd/uhci.c

    re1dbcbc ra81a1d09  
    4444#include "pci.h"
    4545
     46#include "hc.h"
     47#include "root_hub.h"
     48
     49/** Structure representing both functions of UHCI hc, USB host controller
     50 * and USB root hub */
     51typedef struct uhci {
     52        /** Pointer to DDF represenation of UHCI host controller */
     53        ddf_fun_t *hc_fun;
     54        /** Pointer to DDF represenation of UHCI root hub */
     55        ddf_fun_t *rh_fun;
     56
     57        /** Internal driver's represenation of UHCI host controller */
     58        hc_t hc;
     59        /** Internal driver's represenation of UHCI root hub */
     60        rh_t rh;
     61} uhci_t;
     62
     63static inline uhci_t * dev_to_uhci(ddf_dev_t *dev)
     64{
     65        assert(dev);
     66        assert(dev->driver_data);
     67        return dev->driver_data;
     68}
     69/*----------------------------------------------------------------------------*/
    4670/** IRQ handling callback, forward status from call to diver structure.
    4771 *
     
    6993{
    7094        assert(fun);
    71         usb_device_keeper_t *manager =
    72             &((uhci_t*)fun->dev->driver_data)->hc.manager;
    73 
     95        usb_device_keeper_t *manager = &dev_to_uhci(fun->dev)->hc.manager;
    7496        usb_address_t addr = usb_device_keeper_find(manager, handle);
     97
    7598        if (addr < 0) {
    7699                return addr;
     
    93116    ddf_fun_t *fun, devman_handle_t *handle)
    94117{
    95         assert(handle);
    96         ddf_fun_t *hc_fun = ((uhci_t*)fun->dev->driver_data)->hc_fun;
    97         assert(hc_fun != NULL);
    98 
    99         *handle = hc_fun->handle;
     118        assert(fun);
     119        ddf_fun_t *hc_fun = dev_to_uhci(fun->dev)->hc_fun;
     120        assert(hc_fun);
     121
     122        if (handle != NULL)
     123                *handle = hc_fun->handle;
    100124        return EOK;
    101125}
     
    126150static hw_res_ops_t hw_res_iface = {
    127151        .get_resource_list = get_resource_list,
    128         .enable_interrupt = NULL
     152        .enable_interrupt = NULL,
    129153};
    130154/*----------------------------------------------------------------------------*/
     
    146170 *  - registers interrupt handler
    147171 */
    148 int uhci_init(uhci_t *instance, ddf_dev_t *device)
    149 {
    150         assert(instance);
    151         instance->hc_fun = NULL;
     172int device_setup_uhci(ddf_dev_t *device)
     173{
     174        assert(device);
     175        uhci_t *instance = malloc(sizeof(uhci_t));
     176        if (instance == NULL) {
     177                usb_log_error("Failed to allocate OHCI driver.\n");
     178                return ENOMEM;
     179        }
     180
     181#define CHECK_RET_DEST_FREE_RETURN(ret, message...) \
     182if (ret != EOK) { \
     183        if (instance->hc_fun) \
     184                instance->hc_fun->ops = NULL; \
     185                instance->hc_fun->driver_data = NULL; \
     186                ddf_fun_destroy(instance->hc_fun); \
     187        if (instance->rh_fun) {\
     188                instance->rh_fun->ops = NULL; \
     189                instance->rh_fun->driver_data = NULL; \
     190                ddf_fun_destroy(instance->rh_fun); \
     191        } \
     192        free(instance); \
     193        usb_log_error(message); \
     194        return ret; \
     195} else (void)0
     196
    152197        instance->rh_fun = NULL;
    153 #define CHECK_RET_DEST_FUN_RETURN(ret, message...) \
    154 if (ret != EOK) { \
    155         usb_log_error(message); \
    156         if (instance->hc_fun) \
    157                 ddf_fun_destroy(instance->hc_fun); \
    158         if (instance->rh_fun) \
    159                 ddf_fun_destroy(instance->rh_fun); \
    160         return ret; \
    161 }
    162 
    163         uintptr_t io_reg_base = 0;
    164         size_t io_reg_size = 0;
     198        instance->hc_fun = ddf_fun_create(device, fun_exposed, "uhci-hc");
     199        int ret = (instance->hc_fun == NULL) ? ENOMEM : EOK;
     200        CHECK_RET_DEST_FREE_RETURN(ret, "Failed to create UHCI HC function.\n");
     201        instance->hc_fun->ops = &hc_ops;
     202        instance->hc_fun->driver_data = &instance->hc;
     203
     204        instance->rh_fun = ddf_fun_create(device, fun_inner, "uhci-rh");
     205        ret = (instance->rh_fun == NULL) ? ENOMEM : EOK;
     206        CHECK_RET_DEST_FREE_RETURN(ret, "Failed to create UHCI RH function.\n");
     207        instance->rh_fun->ops = &rh_ops;
     208        instance->rh_fun->driver_data = &instance->rh;
     209
     210        uintptr_t reg_base = 0;
     211        size_t reg_size = 0;
    165212        int irq = 0;
    166213
    167         int ret =
    168             pci_get_my_registers(device, &io_reg_base, &io_reg_size, &irq);
    169         CHECK_RET_DEST_FUN_RETURN(ret,
     214        ret = pci_get_my_registers(device, &reg_base, &reg_size, &irq);
     215        CHECK_RET_DEST_FREE_RETURN(ret,
    170216            "Failed to get I/O addresses for %" PRIun ": %s.\n",
    171217            device->handle, str_error(ret));
    172218        usb_log_debug("I/O regs at 0x%p (size %zu), IRQ %d.\n",
    173             (void *) io_reg_base, io_reg_size, irq);
     219            (void *) reg_base, reg_size, irq);
    174220
    175221        ret = pci_disable_legacy(device);
    176         CHECK_RET_DEST_FUN_RETURN(ret,
     222        CHECK_RET_DEST_FREE_RETURN(ret,
    177223            "Failed(%d) to disable legacy USB: %s.\n", ret, str_error(ret));
    178224
     
    194240#endif
    195241
    196         instance->hc_fun = ddf_fun_create(device, fun_exposed, "uhci-hc");
    197         ret = (instance->hc_fun == NULL) ? ENOMEM : EOK;
    198         CHECK_RET_DEST_FUN_RETURN(ret,
    199             "Failed(%d) to create HC function: %s.\n", ret, str_error(ret));
    200 
    201         ret = hc_init(&instance->hc, instance->hc_fun,
    202             (void*)io_reg_base, io_reg_size, interrupts);
    203         CHECK_RET_DEST_FUN_RETURN(ret,
     242
     243        ret = hc_init(&instance->hc, (void*)reg_base, reg_size, interrupts);
     244        CHECK_RET_DEST_FREE_RETURN(ret,
    204245            "Failed(%d) to init uhci-hcd: %s.\n", ret, str_error(ret));
    205 
    206         instance->hc_fun->ops = &hc_ops;
    207         instance->hc_fun->driver_data = &instance->hc;
    208         ret = ddf_fun_bind(instance->hc_fun);
    209         CHECK_RET_DEST_FUN_RETURN(ret,
    210             "Failed(%d) to bind UHCI device function: %s.\n",
    211             ret, str_error(ret));
    212 #undef CHECK_RET_HC_RETURN
    213246
    214247#define CHECK_RET_FINI_RETURN(ret, message...) \
    215248if (ret != EOK) { \
    216         usb_log_error(message); \
    217         if (instance->hc_fun) \
    218                 ddf_fun_destroy(instance->hc_fun); \
    219         if (instance->rh_fun) \
    220                 ddf_fun_destroy(instance->rh_fun); \
    221249        hc_fini(&instance->hc); \
     250        CHECK_RET_DEST_FREE_RETURN(ret, message); \
    222251        return ret; \
    223 }
     252} else (void)0
    224253
    225254        /* It does no harm if we register this on polling */
     
    230259            ret, str_error(ret));
    231260
    232         instance->rh_fun = ddf_fun_create(device, fun_inner, "uhci-rh");
    233         ret = (instance->rh_fun == NULL) ? ENOMEM : EOK;
    234         CHECK_RET_FINI_RETURN(ret,
    235             "Failed(%d) to create root hub function: %s.\n",
     261        ret = ddf_fun_bind(instance->hc_fun);
     262        CHECK_RET_FINI_RETURN(ret,
     263            "Failed(%d) to bind UHCI device function: %s.\n",
    236264            ret, str_error(ret));
     265
     266        ret = ddf_fun_add_to_class(instance->hc_fun, USB_HC_DDF_CLASS_NAME);
     267        CHECK_RET_FINI_RETURN(ret,
     268            "Failed to add UHCI to HC class: %s.\n", str_error(ret));
    237269
    238270        ret = rh_init(&instance->rh, instance->rh_fun,
     
    241273            "Failed(%d) to setup UHCI root hub: %s.\n", ret, str_error(ret));
    242274
    243         instance->rh_fun->ops = &rh_ops;
    244         instance->rh_fun->driver_data = &instance->rh;
    245275        ret = ddf_fun_bind(instance->rh_fun);
    246276        CHECK_RET_FINI_RETURN(ret,
    247277            "Failed(%d) to register UHCI root hub: %s.\n", ret, str_error(ret));
    248278
     279        device->driver_data = instance;
    249280        return EOK;
    250281#undef CHECK_RET_FINI_RETURN
  • uspace/drv/uhci-hcd/uhci.h

    re1dbcbc ra81a1d09  
    3838#include <ddf/driver.h>
    3939
    40 #include "hc.h"
    41 #include "root_hub.h"
    42 
    43 /** Structure representing both functions of UHCI hc, USB host controller
    44  * and USB root hub */
    45 typedef struct uhci {
    46         /** Pointer to DDF represenation of UHCI host controller */
    47         ddf_fun_t *hc_fun;
    48         /** Pointer to DDF represenation of UHCI root hub */
    49         ddf_fun_t *rh_fun;
    50 
    51         /** Internal driver's represenation of UHCI host controller */
    52         hc_t hc;
    53         /** Internal driver's represenation of UHCI root hub */
    54         rh_t rh;
    55 } uhci_t;
    56 
    57 int uhci_init(uhci_t *instance, ddf_dev_t *device);
     40int device_setup_uhci(ddf_dev_t *device);
    5841#endif
    5942/**
  • uspace/drv/uhci-rhd/Makefile

    re1dbcbc ra81a1d09  
    2828
    2929USPACE_PREFIX = ../..
    30 LIBS = $(LIBDRV_PREFIX)/libdrv.a $(LIBUSB_PREFIX)/libusb.a
    31 EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include -I$(LIBUSB_PREFIX)/include -I.
     30
     31LIBS = \
     32        $(LIBUSBDEV_PREFIX)/libusbdev.a \
     33        $(LIBUSB_PREFIX)/libusb.a \
     34        $(LIBDRV_PREFIX)/libdrv.a
     35EXTRA_CFLAGS += \
     36        -I$(LIBUSB_PREFIX)/include \
     37        -I$(LIBUSBDEV_PREFIX)/include \
     38        -I$(LIBDRV_PREFIX)/include
     39
    3240BINARY = uhci-rhd
    3341
  • uspace/drv/uhci-rhd/port.c

    re1dbcbc ra81a1d09  
    3232 * @brief UHCI root hub port routines
    3333 */
    34 #include <libarch/ddi.h> /* pio_read and pio_write */
     34#include <libarch/ddi.h>  /* pio_read and pio_write */
     35#include <fibril_synch.h> /* async_usleep */
    3536#include <errno.h>
    3637#include <str_error.h>
    37 #include <fibril_synch.h>
    3838
    3939#include <usb/usb.h>    /* usb_address_t */
    40 #include <usb/hub.h>
     40#include <usb/hub.h>    /* usb_hc_new_device_wrapper */
    4141#include <usb/debug.h>
    4242
     
    212212
    213213        /*
    214          * The host then waits for at least 100 ms to allow completion of
    215          * an insertion process and for power at the device to become stable.
    216          */
    217         async_usleep(100000);
    218 
    219         /*
    220          * Resets from root ports should be nominally 50ms
     214         * Resets from root ports should be nominally 50ms (USB spec 7.1.7.3)
    221215         */
    222216        {
     
    229223                port_status &= ~STATUS_IN_RESET;
    230224                uhci_port_write_status(port, port_status);
    231                 usb_log_debug("%s: Reset Signal stop.\n", port->id_string);
    232         }
    233 
    234         /* the reset recovery time 10ms */
    235         async_usleep(10000);
    236 
     225                while (uhci_port_read_status(port) & STATUS_IN_RESET);
     226                // TODO: find a better way to waste time (it should be less than
     227                // 10ms, if we reschedule it takes too much time (random
     228                // interrupts can be solved by multiple attempts).
     229                usb_log_debug2("%s: Reset Signal stop.\n", port->id_string);
     230        }
    237231        /* Enable the port. */
    238232        uhci_port_set_enabled(port, true);
     233
     234        /* Reset recovery period,
     235         * devices do not have to respond during this period
     236         */
     237        async_usleep(10000);
    239238        return EOK;
    240239}
     
    255254        usb_log_debug("%s: Detected new device.\n", port->id_string);
    256255
     256        int ret, count = 0;
    257257        usb_address_t dev_addr;
    258         int ret = usb_hc_new_device_wrapper(port->rh, &port->hc_connection,
    259             speed, uhci_port_reset_enable, port->number, port,
    260             &dev_addr, &port->attached_device, NULL, NULL, NULL);
     258        do {
     259                ret = usb_hc_new_device_wrapper(port->rh, &port->hc_connection,
     260                    speed, uhci_port_reset_enable, port->number, port,
     261                    &dev_addr, &port->attached_device, NULL, NULL, NULL);
     262        } while (ret != EOK && ++count < 4);
    261263
    262264        if (ret != EOK) {
     
    313315        /* Wait for port to become enabled */
    314316        do {
    315                 async_usleep(1000);
    316317                port_status = uhci_port_read_status(port);
    317318        } while ((port_status & STATUS_CONNECTED) &&
  • uspace/drv/usbflbk/Makefile

    re1dbcbc ra81a1d09  
    2828
    2929USPACE_PREFIX = ../..
    30 LIBS = $(LIBDRV_PREFIX)/libdrv.a $(LIBUSB_PREFIX)/libusb.a
    31 EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include -I$(LIBUSB_PREFIX)/include
     30
     31LIBS = \
     32        $(LIBUSBDEV_PREFIX)/libusbdev.a \
     33        $(LIBUSB_PREFIX)/libusb.a \
     34        $(LIBDRV_PREFIX)/libdrv.a
     35EXTRA_CFLAGS += \
     36        -I$(LIBUSB_PREFIX)/include \
     37        -I$(LIBUSBDEV_PREFIX)/include \
     38        -I$(LIBDRV_PREFIX)/include
     39
    3240BINARY = usbflbk
    3341
  • uspace/drv/usbhid/Makefile

    re1dbcbc ra81a1d09  
    2828
    2929USPACE_PREFIX = ../..
    30 LIBS = $(LIBDRV_PREFIX)/libdrv.a $(LIBUSB_PREFIX)/libusb.a
    31 EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include -I$(LIBUSB_PREFIX)/include -I.
     30
     31LIBS = \
     32        $(LIBUSBHID_PREFIX)/libusbhid.a \
     33        $(LIBUSBDEV_PREFIX)/libusbdev.a \
     34        $(LIBUSB_PREFIX)/libusb.a \
     35        $(LIBDRV_PREFIX)/libdrv.a
     36EXTRA_CFLAGS += \
     37        -I. \
     38        -I$(LIBUSB_PREFIX)/include \
     39        -I$(LIBUSBDEV_PREFIX)/include \
     40        -I$(LIBUSBHID_PREFIX)/include \
     41        -I$(LIBDRV_PREFIX)/include
     42
    3243BINARY = usbhid
    3344
  • uspace/drv/usbhid/generic/hiddev.c

    re1dbcbc ra81a1d09  
    3737#include <usb/debug.h>
    3838#include <usb/classes/classes.h>
     39#include <errno.h>
     40#include <str_error.h>
     41#include <bool.h>
     42
     43#include <usbhid_iface.h>
    3944
    4045#include "hiddev.h"
     
    5560/*----------------------------------------------------------------------------*/
    5661
     62static size_t usb_generic_hid_get_event_length(ddf_fun_t *fun);
     63
     64static int usb_generic_hid_get_event(ddf_fun_t *fun, int32_t *buffer,
     65    size_t size, size_t *act_size, unsigned int flags);
     66
     67static int usb_generic_hid_client_connected(ddf_fun_t *fun);
     68
     69/*----------------------------------------------------------------------------*/
     70
     71static usbhid_iface_t usb_generic_iface = {
     72        .get_event = usb_generic_hid_get_event,
     73        .get_event_length = usb_generic_hid_get_event_length
     74};
     75
     76static ddf_dev_ops_t usb_generic_hid_ops = {
     77        .interfaces[USBHID_DEV_IFACE] = &usb_generic_iface,
     78        .open = usb_generic_hid_client_connected
     79};
     80
     81/*----------------------------------------------------------------------------*/
     82
     83static size_t usb_generic_hid_get_event_length(ddf_fun_t *fun)
     84{
     85        if (fun == NULL || fun->driver_data) {
     86                return 0;
     87        }
     88
     89        usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)fun->driver_data;
     90       
     91        return hid_dev->input_report_size;
     92}
     93
     94/*----------------------------------------------------------------------------*/
     95
     96static int usb_generic_hid_get_event(ddf_fun_t *fun, int32_t *buffer,
     97    size_t size, size_t *act_size, unsigned int flags)
     98{
     99        if (fun == NULL || fun->driver_data) {
     100                return EINVAL;
     101        }
     102
     103        usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)fun->driver_data;
     104       
     105        if (hid_dev->input_report_size > size) {
     106                return EINVAL;  // TODO: other error code
     107        }
     108       
     109        /*! @todo This should probably be atomic. */
     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        }
     116       
     117        // clear the buffer so that it will not be received twice
     118        //memset(hid_dev->input_report, 0, hid_dev->input_report_size);
     119       
     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();
     131        return EOK;
     132}
     133
     134/*----------------------------------------------------------------------------*/
     135
     136static int usb_generic_hid_create_function(usb_hid_dev_t *hid_dev)
     137{       
     138        /* Create the function exposed under /dev/devices. */
     139        /** @todo Generate numbers for the devices? */
     140        usb_log_debug("Creating DDF function %s...\n", HID_GENERIC_FUN_NAME);
     141        ddf_fun_t *fun = ddf_fun_create(hid_dev->usb_dev->ddf_dev, fun_exposed,
     142            HID_GENERIC_FUN_NAME);
     143        if (fun == NULL) {
     144                usb_log_error("Could not create DDF function node.\n");
     145                return ENOMEM;
     146        }
     147
     148        int rc = ddf_fun_bind(fun);
     149        if (rc != EOK) {
     150                usb_log_error("Could not bind DDF function: %s.\n",
     151                    str_error(rc));
     152                ddf_fun_destroy(fun);
     153                return rc;
     154        }
     155       
     156        fun->ops = &usb_generic_hid_ops;
     157        fun->driver_data = hid_dev;
     158       
     159        return EOK;
     160}
     161
     162/*----------------------------------------------------------------------------*/
     163
     164int usb_generic_hid_init(usb_hid_dev_t *hid_dev)
     165{
     166        if (hid_dev == NULL) {
     167                return EINVAL;
     168        }
     169       
     170        return usb_generic_hid_create_function(hid_dev);
     171}
     172
     173/*----------------------------------------------------------------------------*/
     174
    57175bool usb_generic_hid_polling_callback(usb_hid_dev_t *hid_dev,
    58176    uint8_t *buffer, size_t buffer_size)
  • uspace/drv/usbhid/generic/hiddev.h

    re1dbcbc ra81a1d09  
    4646const char *HID_GENERIC_CLASS_NAME;
    4747
     48/*----------------------------------------------------------------------------*/
     49
     50int usb_generic_hid_init(struct usb_hid_dev *hid_dev);
     51
    4852bool usb_generic_hid_polling_callback(struct usb_hid_dev *hid_dev,
    4953    uint8_t *buffer, size_t buffer_size);
  • uspace/drv/usbhid/kbd/kbddev.c

    re1dbcbc ra81a1d09  
    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
     
    766773
    767774/*----------------------------------------------------------------------------*/
     775
     776static int usb_kbd_create_function(usb_hid_dev_t *hid_dev)
     777{
     778        assert(hid_dev != NULL);
     779        assert(hid_dev->usb_dev != NULL);
     780       
     781        /* Create the function exposed under /dev/devices. */
     782        usb_log_debug("Creating DDF function %s...\n", HID_KBD_FUN_NAME);
     783        ddf_fun_t *fun = ddf_fun_create(hid_dev->usb_dev->ddf_dev, fun_exposed,
     784            HID_KBD_FUN_NAME);
     785        if (fun == NULL) {
     786                usb_log_error("Could not create DDF function node.\n");
     787                return ENOMEM;
     788        }
     789       
     790        /*
     791         * Store the initialized HID device and HID ops
     792         * to the DDF function.
     793         */
     794        fun->ops = &hid_dev->ops;
     795        fun->driver_data = hid_dev;   // TODO: maybe change to hid_dev->data
     796
     797        int rc = ddf_fun_bind(fun);
     798        if (rc != EOK) {
     799                usb_log_error("Could not bind DDF function: %s.\n",
     800                    str_error(rc));
     801                ddf_fun_destroy(fun);
     802                return rc;
     803        }
     804       
     805        usb_log_debug("Adding DDF function to class %s...\n",
     806            HID_KBD_CLASS_NAME);
     807        rc = ddf_fun_add_to_class(fun, HID_KBD_CLASS_NAME);
     808        if (rc != EOK) {
     809                usb_log_error(
     810                    "Could not add DDF function to class %s: %s.\n",
     811                    HID_KBD_CLASS_NAME, str_error(rc));
     812                ddf_fun_destroy(fun);
     813                return rc;
     814        }
     815       
     816        return EOK;
     817}
     818
     819/*----------------------------------------------------------------------------*/
    768820/* API functions                                                              */
    769821/*----------------------------------------------------------------------------*/
     
    930982        usb_log_debug("HID/KBD device structure initialized.\n");
    931983       
     984        usb_log_debug("Creating KBD function...\n");
     985        int rc = usb_kbd_create_function(hid_dev);
     986        if (rc != EOK) {
     987                usb_kbd_free(&kbd_dev);
     988                return rc;
     989        }
     990       
    932991        return EOK;
    933992}
     
    9931052        if ((*kbd_dev)->led_data != NULL) {
    9941053                free((*kbd_dev)->led_data);
    995         }
    996         if ((*kbd_dev)->output_buffer != NULL) {
    997                 free((*kbd_dev)->output_buffer);
    9981054        }
    9991055        if ((*kbd_dev)->led_path != NULL) {
  • uspace/drv/usbhid/lgtch-ultrax/keymap.c

    re1dbcbc ra81a1d09  
    5555        [0xc] = KC_F6, /* Just for testing purposes */
    5656       
    57         [0xb5] = 0,  /* Scan Next Track */
    58         [0xb6] = 0,  /* Scan Previous Track */
    59         [0xb7] = 0,  /* Stop */
    60         [0xb8] = 0,  /* Eject */
    61         [0xcd] = KC_F2,  /* Play/Pause */
    62         [0xe2] = KC_F3,  /* Mute */
    63         [0xe9] = KC_F5,  /* Volume Increment */
    64         [0xea] = KC_F4,  /* Volume Decrement */
    65         [0x183] = 0, /* AL Consumer Control Configuration */
    66         [0x18a] = 0, /* AL Email Reader */
    67         [0x192] = 0, /* AL Calculator */
    68         [0x221] = 0, /* AC Search */
    69         [0x223] = 0, /* AC Home */
    70         [0x224] = 0, /* AC Back */
    71         [0x225] = 0, /* AC Forward */
    72         [0x226] = 0, /* AC Stop */
    73         [0x227] = KC_F1, /* AC Refresh */
    74         [0x22a] = KC_F6  /* AC Bookmarks */
     57        [0xb5] = 0,       /* Scan Next Track */
     58        [0xb6] = 0,       /* Scan Previous Track */
     59        [0xb7] = 0,       /* Stop */
     60        [0xb8] = 0,       /* Eject */
     61        [0xcd] = KC_F2,   /* Play/Pause */
     62        [0xe2] = KC_F3,   /* Mute */
     63        [0xe9] = KC_F5,   /* Volume Increment */
     64        [0xea] = KC_F4,   /* Volume Decrement */
     65        [0x183] = 0,      /* AL Consumer Control Configuration */
     66        [0x18a] = 0,      /* AL Email Reader */
     67        [0x192] = 0,      /* AL Calculator */
     68        [0x221] = 0,      /* AC Search */
     69        [0x223] = 0,      /* AC Home */
     70        [0x224] = 0,      /* AC Back */
     71        [0x225] = 0,      /* AC Forward */
     72        [0x226] = 0,      /* AC Stop */
     73        [0x227] = KC_F1,  /* AC Refresh */
     74        [0x22a] = KC_F6   /* AC Bookmarks */
    7575};
    7676
  • uspace/drv/usbhid/lgtch-ultrax/lgtch-ultrax.c

    re1dbcbc ra81a1d09  
    5858} usb_lgtch_flags;
    5959
     60/*----------------------------------------------------------------------------*/
     61/**
     62 * Logitech UltraX device type.
     63 */
     64typedef struct usb_lgtch_ultrax_t {
     65        /** Previously pressed keys (not translated to key codes). */
     66        int32_t *keys_old;
     67        /** Currently pressed keys (not translated to key codes). */
     68        int32_t *keys;
     69        /** Count of stored keys (i.e. number of keys in the report). */
     70        size_t key_count;
     71       
     72        /** IPC phone to the console device (for sending key events). */
     73        int console_phone;
     74
     75        /** Information for auto-repeat of keys. */
     76//      usb_kbd_repeat_t repeat;
     77       
     78        /** Mutex for accessing the information about auto-repeat. */
     79//      fibril_mutex_t *repeat_mtx;
     80
     81        /** State of the structure (for checking before use).
     82         *
     83         * 0 - not initialized
     84         * 1 - initialized
     85         * -1 - ready for destroying
     86         */
     87        int initialized;
     88} usb_lgtch_ultrax_t;
     89
    6090
    6191/*----------------------------------------------------------------------------*/
     
    208238/*----------------------------------------------------------------------------*/
    209239
    210 int usb_lgtch_init(struct usb_hid_dev *hid_dev)
    211 {
    212         if (hid_dev == NULL || hid_dev->usb_dev == NULL) {
    213                 return EINVAL; /*! @todo Other return code? */
    214         }
    215        
    216         usb_log_debug(NAME " Initializing HID/lgtch_ultrax structure...\n");
    217        
    218         usb_lgtch_ultrax_t *lgtch_dev = (usb_lgtch_ultrax_t *)malloc(
    219             sizeof(usb_lgtch_ultrax_t));
    220         if (lgtch_dev == NULL) {
    221                 return ENOMEM;
    222         }
    223        
    224         lgtch_dev->console_phone = -1;
    225        
    226         usb_hid_report_path_t *path = usb_hid_report_path();
    227         usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_CONSUMER, 0);
    228        
    229         usb_hid_report_path_set_report_id(path, 1);
    230        
    231         lgtch_dev->key_count = usb_hid_report_input_length(
    232             hid_dev->report, path,
    233             USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY);
    234         usb_hid_report_path_free(path);
    235        
    236         usb_log_debug(NAME " Size of the input report: %zu\n",
    237             lgtch_dev->key_count);
    238        
    239         lgtch_dev->keys = (int32_t *)calloc(lgtch_dev->key_count,
    240             sizeof(int32_t));
    241        
    242         if (lgtch_dev->keys == NULL) {
    243                 usb_log_fatal("No memory!\n");
    244                 free(lgtch_dev);
    245                 return ENOMEM;
    246         }
    247        
    248         lgtch_dev->keys_old =
    249                 (int32_t *)calloc(lgtch_dev->key_count, sizeof(int32_t));
    250        
    251         if (lgtch_dev->keys_old == NULL) {
    252                 usb_log_fatal("No memory!\n");
    253                 free(lgtch_dev->keys);
    254                 free(lgtch_dev);
    255                 return ENOMEM;
    256         }
    257        
    258         /*! @todo Autorepeat */
    259        
    260         // save the KBD device structure into the HID device structure
    261         hid_dev->data = lgtch_dev;
    262        
     240static int usb_lgtch_create_function(usb_hid_dev_t *hid_dev)
     241{
    263242        /* Create the function exposed under /dev/devices. */
    264243        ddf_fun_t *fun = ddf_fun_create(hid_dev->usb_dev->ddf_dev, fun_exposed,
     
    269248        }
    270249       
    271         lgtch_dev->initialized = USB_LGTCH_STATUS_INITIALIZED;
    272         usb_log_debug(NAME " HID/lgtch_ultrax device structure initialized.\n");
    273        
    274250        /*
    275251         * Store the initialized HID device and HID ops
     
    279255        fun->driver_data = hid_dev;   // TODO: maybe change to hid_dev->data
    280256       
    281         /*
    282          * 1) subdriver vytvori vlastnu ddf_fun, vlastne ddf_dev_ops, ktore da
    283          *    do nej.
    284          * 2) do tych ops do .interfaces[DEV_IFACE_USBHID (asi)] priradi
    285          *    vyplnenu strukturu usbhid_iface_t.
    286          * 3) klientska aplikacia - musi si rucne vytvorit telefon
    287          *    (devman_device_connect() - cesta k zariadeniu (/hw/pci0/...) az
    288          *    k tej fcii.
    289          *    pouzit usb/classes/hid/iface.h - prvy int je telefon
    290          */
    291 
    292257        int rc = ddf_fun_bind(fun);
    293258        if (rc != EOK) {
     
    296261                // TODO: Can / should I destroy the DDF function?
    297262                ddf_fun_destroy(fun);
    298                 usb_lgtch_free(&lgtch_dev);
    299263                return rc;
    300264        }
     
    307271                // TODO: Can / should I destroy the DDF function?
    308272                ddf_fun_destroy(fun);
     273                return rc;
     274        }
     275       
     276        return EOK;
     277}
     278
     279/*----------------------------------------------------------------------------*/
     280
     281int usb_lgtch_init(struct usb_hid_dev *hid_dev)
     282{
     283        if (hid_dev == NULL || hid_dev->usb_dev == NULL) {
     284                return EINVAL; /*! @todo Other return code? */
     285        }
     286       
     287        usb_log_debug(NAME " Initializing HID/lgtch_ultrax structure...\n");
     288       
     289        usb_lgtch_ultrax_t *lgtch_dev = (usb_lgtch_ultrax_t *)malloc(
     290            sizeof(usb_lgtch_ultrax_t));
     291        if (lgtch_dev == NULL) {
     292                return ENOMEM;
     293        }
     294       
     295        lgtch_dev->console_phone = -1;
     296       
     297        usb_hid_report_path_t *path = usb_hid_report_path();
     298        usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_CONSUMER, 0);
     299       
     300        usb_hid_report_path_set_report_id(path, 1);
     301       
     302        lgtch_dev->key_count = usb_hid_report_input_length(
     303            hid_dev->report, path,
     304            USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY);
     305        usb_hid_report_path_free(path);
     306       
     307        usb_log_debug(NAME " Size of the input report: %zu\n",
     308            lgtch_dev->key_count);
     309       
     310        lgtch_dev->keys = (int32_t *)calloc(lgtch_dev->key_count,
     311            sizeof(int32_t));
     312       
     313        if (lgtch_dev->keys == NULL) {
     314                usb_log_fatal("No memory!\n");
     315                free(lgtch_dev);
     316                return ENOMEM;
     317        }
     318       
     319        lgtch_dev->keys_old =
     320                (int32_t *)calloc(lgtch_dev->key_count, sizeof(int32_t));
     321       
     322        if (lgtch_dev->keys_old == NULL) {
     323                usb_log_fatal("No memory!\n");
     324                free(lgtch_dev->keys);
     325                free(lgtch_dev);
     326                return ENOMEM;
     327        }
     328       
     329        /*! @todo Autorepeat */
     330       
     331        // save the KBD device structure into the HID device structure
     332        hid_dev->data = lgtch_dev;
     333       
     334        lgtch_dev->initialized = USB_LGTCH_STATUS_INITIALIZED;
     335        usb_log_debug(NAME " HID/lgtch_ultrax device structure initialized.\n");
     336       
     337        int rc = usb_lgtch_create_function(hid_dev);
     338        if (rc != EOK) {
    309339                usb_lgtch_free(&lgtch_dev);
    310340                return rc;
     
    356386        int rc = usb_hid_parse_report(hid_dev->report, buffer, buffer_size,
    357387            &report_id);
     388       
     389        if (rc != EOK) {
     390                usb_log_warning(NAME "Error in usb_hid_parse_report(): %s\n",
     391                    str_error(rc));
     392                return true;
     393        }
     394       
    358395        usb_hid_report_path_set_report_id(path, report_id);
    359396
     
    383420        usb_hid_report_path_free(path);
    384421       
    385         if (rc != EOK) {
    386                 usb_log_warning(NAME "Error in usb_hid_boot_keyboard_input_report():"
    387                     "%s\n", str_error(rc));
    388         }
    389        
    390422        return true;
    391423}
  • uspace/drv/usbhid/lgtch-ultrax/lgtch-ultrax.h

    re1dbcbc ra81a1d09  
    4242
    4343/*----------------------------------------------------------------------------*/
    44 /**
    45  * USB/HID keyboard device type.
    46  *
    47  * Holds a reference to generic USB/HID device structure and keyboard-specific
    48  * data, such as currently pressed keys, modifiers and lock keys.
    49  *
    50  * Also holds a IPC phone to the console (since there is now no other way to
    51  * communicate with it).
    52  *
    53  * @note Storing active lock keys in this structure results in their setting
    54  *       being device-specific.
    55  */
    56 typedef struct usb_lgtch_ultrax_t {
    57         /** Previously pressed keys (not translated to key codes). */
    58         int32_t *keys_old;
    59         /** Currently pressed keys (not translated to key codes). */
    60         int32_t *keys;
    61         /** Count of stored keys (i.e. number of keys in the report). */
    62         size_t key_count;
    63        
    64         /** IPC phone to the console device (for sending key events). */
    65         int console_phone;
    66 
    67         /** Information for auto-repeat of keys. */
    68 //      usb_kbd_repeat_t repeat;
    69        
    70         /** Mutex for accessing the information about auto-repeat. */
    71 //      fibril_mutex_t *repeat_mtx;
    72 
    73         /** State of the structure (for checking before use).
    74          *
    75          * 0 - not initialized
    76          * 1 - initialized
    77          * -1 - ready for destroying
    78          */
    79         int initialized;
    80 } usb_lgtch_ultrax_t;
    81 
    82 /*----------------------------------------------------------------------------*/
    8344
    8445int usb_lgtch_init(struct usb_hid_dev *hid_dev);
  • uspace/drv/usbhid/main.c

    re1dbcbc ra81a1d09  
    9999        usb_log_debug("USB/HID device structure initialized.\n");
    100100       
    101         /* Create the function exposed under /dev/devices. */
    102         ddf_fun_t *hid_fun = ddf_fun_create(dev->ddf_dev, fun_exposed,
    103             usb_hid_get_function_name(hid_dev));
    104         if (hid_fun == NULL) {
    105                 usb_log_error("Could not create DDF function node.\n");
    106                 usb_hid_free(&hid_dev);
    107                 return ENOMEM;
    108         }
    109        
    110         /*
    111          * Store the initialized HID device and HID ops
    112          * to the DDF function.
    113          */
    114         hid_fun->ops = &hid_dev->ops;
    115         hid_fun->driver_data = hid_dev;   // TODO: maybe change to hid_dev->data
    116        
    117101        /*
    118102         * 1) subdriver vytvori vlastnu ddf_fun, vlastne ddf_dev_ops, ktore da
     
    125109         *    pouzit usb/classes/hid/iface.h - prvy int je telefon
    126110         */
    127 
    128         rc = ddf_fun_bind(hid_fun);
    129         if (rc != EOK) {
    130                 usb_log_error("Could not bind DDF function: %s.\n",
    131                     str_error(rc));
    132                 // TODO: Can / should I destroy the DDF function?
    133                 ddf_fun_destroy(hid_fun);
    134                 usb_hid_free(&hid_dev);
    135                 return rc;
    136         }
    137        
    138         rc = ddf_fun_add_to_class(hid_fun, usb_hid_get_class_name(hid_dev));
    139         if (rc != EOK) {
    140                 usb_log_error(
    141                     "Could not add DDF function to class 'hid': %s.\n",
    142                     str_error(rc));
    143                 // TODO: Can / should I destroy the DDF function?
    144                 ddf_fun_destroy(hid_fun);
    145                 usb_hid_free(&hid_dev);
    146                 return rc;
    147         }
    148111       
    149112        /* Start automated polling function.
  • uspace/drv/usbhid/mouse/mousedev.c

    re1dbcbc ra81a1d09  
    3939#include <usb/classes/hid.h>
    4040#include <usb/classes/hidreq.h>
     41#include <usb/classes/hidut.h>
    4142#include <errno.h>
    4243#include <str_error.h>
    4344#include <ipc/mouse.h>
     45#include <io/console.h>
     46
     47#include <ipc/kbd.h>
     48#include <io/keycode.h>
    4449
    4550#include "mousedev.h"
    4651#include "../usbhid.h"
     52
     53#define NAME "mouse"
    4754
    4855/*----------------------------------------------------------------------------*/
     
    5865
    5966const char *HID_MOUSE_FUN_NAME = "mouse";
     67const char *HID_MOUSE_WHEEL_FUN_NAME = "mouse-wheel";
    6068const char *HID_MOUSE_CLASS_NAME = "mouse";
     69const char *HID_MOUSE_WHEEL_CLASS_NAME = "keyboard";
    6170
    6271/** Default idle rate for mouses. */
    6372static const uint8_t IDLE_RATE = 0;
     73static const size_t USB_MOUSE_BUTTON_COUNT = 3;
    6474
    6575/*----------------------------------------------------------------------------*/
     
    115125       
    116126        if (hid_dev == NULL || hid_dev->data == NULL) {
     127                usb_log_debug("default_connection_handler: Missing "
     128                    "parameters.\n");
    117129                async_answer_0(icallid, EINVAL);
    118130                return;
     
    123135        usb_mouse_t *mouse_dev = (usb_mouse_t *)hid_dev->data;
    124136       
     137        int *phone = (str_cmp(fun->name, HID_MOUSE_FUN_NAME) == 0)
     138                     ? &mouse_dev->mouse_phone : &mouse_dev->wheel_phone;
     139       
    125140        if (method == IPC_M_CONNECT_TO_ME) {
    126141                int callback = IPC_GET_ARG5(*icall);
    127142
    128                 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");
    129146                        async_answer_0(icallid, ELIMIT);
     147                        //async_answer_0(icallid, EOK);
    130148                        return;
    131149                }
    132150
    133                 mouse_dev->console_phone = callback;
     151                *phone = callback;
    134152                usb_log_debug("Console phone to mouse set ok (%d).\n", callback);
    135153                async_answer_0(icallid, EOK);
     
    137155        }
    138156
     157        usb_log_debug("default_connection_handler: Invalid function.\n");
    139158        async_answer_0(icallid, EINVAL);
    140159}
     
    148167                return NULL;
    149168        }
    150         mouse->console_phone = -1;
     169        mouse->mouse_phone = -1;
     170        mouse->wheel_phone = -1;
    151171       
    152172        return mouse;
     
    160180       
    161181        // hangup phone to the console
    162         if ((*mouse_dev)->console_phone >= 0) {
    163                 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);
    164188        }
    165189       
     
    170194/*----------------------------------------------------------------------------*/
    171195
    172 static bool usb_mouse_process_boot_report(usb_mouse_t *mouse_dev,
    173     uint8_t *buffer, size_t buffer_size)
    174 {
     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)
     228{
     229        usb_mouse_t *mouse_dev = (usb_mouse_t *)hid_dev->data;
     230       
    175231        usb_log_debug2("got buffer: %s.\n",
    176232            usb_debug_str_buffer(buffer, buffer_size, 0));
    177 
    178         uint8_t butt = buffer[0];
    179         char str_buttons[4] = {
    180                 butt & 1 ? '#' : '.',
    181                 butt & 2 ? '#' : '.',
    182                 butt & 4 ? '#' : '.',
    183                 0
    184         };
    185 
    186         int shift_x = ((int) buffer[1]) - 127;
    187         int shift_y = ((int) buffer[2]) - 127;
    188         int wheel = ((int) buffer[3]) - 127;
    189 
    190         if (buffer[1] == 0) {
    191                 shift_x = 0;
    192         }
    193         if (buffer[2] == 0) {
    194                 shift_y = 0;
    195         }
    196         if (buffer[3] == 0) {
    197                 wheel = 0;
    198         }
    199        
    200         if (mouse_dev->console_phone >= 0) {
    201                 usb_log_debug("Console phone: %d\n", mouse_dev->console_phone);
    202                 if ((shift_x != 0) || (shift_y != 0)) {
    203                         /* FIXME: guessed for QEMU */
    204                         async_req_2_0(mouse_dev->console_phone,
    205                             MEVENT_MOVE,
    206                             - shift_x / 10,  - shift_y / 10);
    207                 } else {
    208                         usb_log_error("No move reported\n");
    209                 }
    210                 if (butt) {
    211                         /* FIXME: proper button clicking. */
    212                         async_req_2_0(mouse_dev->console_phone,
    213                             MEVENT_BUTTON, 1, 1);
    214                         async_req_2_0(mouse_dev->console_phone,
    215                             MEVENT_BUTTON, 1, 0);
    216                 }
    217         } else {
    218                 usb_log_error("No console phone in mouse!!\n");
    219         }
    220 
    221         usb_log_debug("buttons=%s  dX=%+3d  dY=%+3d  wheel=%+3d\n",
    222             str_buttons, shift_x, shift_y, wheel);
    223 
    224         /* Guess. */
    225         //async_usleep(1000);
    226         // no sleep right now
     233       
     234        if (mouse_dev->mouse_phone < 0) {
     235                usb_log_error(NAME " No console phone.\n");
     236                return false;   // ??
     237        }
     238
     239        /*
     240         * parse the input report
     241         */
     242       
     243        usb_log_debug(NAME " Calling usb_hid_parse_report() with "
     244            "buffer %s\n", usb_debug_str_buffer(buffer, buffer_size, 0));
     245       
     246        uint8_t report_id;
     247       
     248        int rc = usb_hid_parse_report(hid_dev->report, buffer, buffer_size,
     249            &report_id);
     250       
     251        if (rc != EOK) {
     252                usb_log_warning(NAME "Error in usb_hid_parse_report(): %s\n",
     253                    str_error(rc));
     254                return true;
     255        }
     256       
     257        /*
     258         * X
     259         */
     260        int shift_x = 0;
     261       
     262        usb_hid_report_path_t *path = usb_hid_report_path();
     263        usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_GENERIC_DESKTOP,
     264            USB_HIDUT_USAGE_GENERIC_DESKTOP_X);
     265
     266        usb_hid_report_path_set_report_id(path, report_id);
     267
     268        usb_hid_report_field_t *field = usb_hid_report_get_sibling(
     269            hid_dev->report, NULL, path, USB_HID_PATH_COMPARE_END,
     270            USB_HID_REPORT_TYPE_INPUT);
     271
     272        if (field != NULL) {
     273                usb_log_debug(NAME " VALUE(%X) USAGE(%X)\n", field->value,
     274                    field->usage);
     275                shift_x = field->value;
     276        }
     277
     278        usb_hid_report_path_free(path);
     279       
     280        /*
     281         * Y
     282         */
     283        int shift_y = 0;
     284       
     285        path = usb_hid_report_path();
     286        usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_GENERIC_DESKTOP,
     287            USB_HIDUT_USAGE_GENERIC_DESKTOP_Y);
     288
     289        usb_hid_report_path_set_report_id(path, report_id);
     290
     291        field = usb_hid_report_get_sibling(
     292            hid_dev->report, NULL, path, USB_HID_PATH_COMPARE_END,
     293            USB_HID_REPORT_TYPE_INPUT);
     294
     295        if (field != NULL) {
     296                usb_log_debug(NAME " VALUE(%X) USAGE(%X)\n", field->value,
     297                    field->usage);
     298                shift_y = field->value;
     299        }
     300
     301        usb_hid_report_path_free(path);
     302       
     303        if ((shift_x != 0) || (shift_y != 0)) {
     304                async_req_2_0(mouse_dev->mouse_phone,
     305                    MEVENT_MOVE, shift_x, shift_y);
     306        }
     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       
     335       
     336        /*
     337         * Buttons
     338         */
     339        path = usb_hid_report_path();
     340        usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_BUTTON, 0);
     341        usb_hid_report_path_set_report_id(path, report_id);
     342       
     343        field = usb_hid_report_get_sibling(
     344            hid_dev->report, NULL, path, USB_HID_PATH_COMPARE_END
     345            | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY,
     346            USB_HID_REPORT_TYPE_INPUT);
     347
     348        while (field != NULL) {
     349                usb_log_debug(NAME " VALUE(%X) USAGE(%X)\n", field->value,
     350                    field->usage);
     351               
     352                if (mouse_dev->buttons[field->usage - field->usage_minimum] == 0
     353                    && field->value != 0) {
     354                        async_req_2_0(mouse_dev->mouse_phone,
     355                            MEVENT_BUTTON, field->usage, 1);
     356                        mouse_dev->buttons[field->usage - field->usage_minimum]
     357                            = field->value;
     358                } else if (
     359                    mouse_dev->buttons[field->usage - field->usage_minimum] != 0
     360                    && field->value == 0) {
     361                       async_req_2_0(mouse_dev->mouse_phone,
     362                           MEVENT_BUTTON, field->usage, 0);
     363                       mouse_dev->buttons[field->usage - field->usage_minimum]
     364                           = field->value;
     365               }
     366               
     367                field = usb_hid_report_get_sibling(
     368                    hid_dev->report, field, path, USB_HID_PATH_COMPARE_END
     369                    | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY,
     370                    USB_HID_REPORT_TYPE_INPUT);
     371        }
     372       
     373        usb_hid_report_path_free(path);
    227374
    228375        return true;
     376}
     377
     378/*----------------------------------------------------------------------------*/
     379
     380static int usb_mouse_create_function(usb_hid_dev_t *hid_dev)
     381{
     382        /* Create the function exposed under /dev/devices. */
     383        usb_log_debug("Creating DDF function %s...\n", HID_MOUSE_FUN_NAME);
     384        ddf_fun_t *fun = ddf_fun_create(hid_dev->usb_dev->ddf_dev, fun_exposed,
     385            HID_MOUSE_FUN_NAME);
     386        if (fun == NULL) {
     387                usb_log_error("Could not create DDF function node.\n");
     388                return ENOMEM;
     389        }
     390       
     391        /*
     392         * Store the initialized HID device and HID ops
     393         * to the DDF function.
     394         */
     395        fun->ops = &hid_dev->ops;
     396        fun->driver_data = hid_dev;   // TODO: maybe change to hid_dev->data
     397
     398        int rc = ddf_fun_bind(fun);
     399        if (rc != EOK) {
     400                usb_log_error("Could not bind DDF function: %s.\n",
     401                    str_error(rc));
     402                ddf_fun_destroy(fun);
     403                return rc;
     404        }
     405       
     406        usb_log_debug("Adding DDF function to class %s...\n",
     407            HID_MOUSE_CLASS_NAME);
     408        rc = ddf_fun_add_to_class(fun, HID_MOUSE_CLASS_NAME);
     409        if (rc != EOK) {
     410                usb_log_error(
     411                    "Could not add DDF function to class %s: %s.\n",
     412                    HID_MOUSE_CLASS_NAME, str_error(rc));
     413                ddf_fun_destroy(fun);
     414                return rc;
     415        }
     416       
     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       
     455        return EOK;
    229456}
    230457
     
    248475        }
    249476       
     477        mouse_dev->buttons = (int32_t *)calloc(USB_MOUSE_BUTTON_COUNT,
     478            sizeof(int32_t));
     479       
     480        if (mouse_dev->buttons == NULL) {
     481                usb_log_fatal("No memory!\n");
     482                free(mouse_dev);
     483                return ENOMEM;
     484        }
     485       
    250486        // save the Mouse device structure into the HID device structure
    251487        hid_dev->data = mouse_dev;
     
    255491       
    256492        // TODO: how to know if the device supports the request???
    257         usbhid_req_set_idle(&hid_dev->usb_dev->ctrl_pipe,
    258             hid_dev->usb_dev->interface_no, IDLE_RATE);
     493//      usbhid_req_set_idle(&hid_dev->usb_dev->ctrl_pipe,
     494//          hid_dev->usb_dev->interface_no, IDLE_RATE);
     495       
     496        int rc = usb_mouse_create_function(hid_dev);
     497        if (rc != EOK) {
     498                usb_mouse_free(&mouse_dev);
     499                return rc;
     500        }
    259501       
    260502        return EOK;
     
    280522                return false;
    281523        }
    282         usb_mouse_t *mouse_dev = (usb_mouse_t *)hid_dev->data;
    283        
    284         return usb_mouse_process_boot_report(mouse_dev, buffer, buffer_size);
     524       
     525        return usb_mouse_process_report(hid_dev, buffer, buffer_size);
    285526}
    286527
  • uspace/drv/usbhid/mouse/mousedev.h

    re1dbcbc ra81a1d09  
    4848        //suseconds_t poll_interval_us;
    4949        /** IPC phone to console (consumer). */
    50         int console_phone;
     50        int mouse_phone;
     51        int wheel_phone;
     52       
     53        int32_t *buttons;
    5154} usb_mouse_t;
    5255
  • uspace/drv/usbhid/subdrivers.c

    re1dbcbc ra81a1d09  
    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

    re1dbcbc ra81a1d09  
    6363static const int USB_HID_MAX_SUBDRIVERS = 10;
    6464
     65static fibril_local bool report_received;
     66
    6567/*----------------------------------------------------------------------------*/
    6668
     
    136138       
    137139        // set the init callback
    138         hid_dev->subdrivers[0].init = NULL;
     140        hid_dev->subdrivers[0].init = usb_generic_hid_init;
    139141       
    140142        // set the polling callback
     
    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) {
     
    490490        usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)arg;
    491491       
     492        int allocated = (hid_dev->input_report != NULL);
     493       
     494        if (!allocated
     495            || hid_dev->input_report_size < buffer_size) {
     496                uint8_t *input_old = hid_dev->input_report;
     497                uint8_t *input_new = (uint8_t *)malloc(buffer_size);
     498               
     499                if (input_new == NULL) {
     500                        usb_log_error("Failed to allocate space for input "
     501                            "buffer. This event may not be reported\n");
     502                        memset(hid_dev->input_report, 0,
     503                            hid_dev->input_report_size);
     504                } else {
     505                        memcpy(input_new, input_old,
     506                            hid_dev->input_report_size);
     507                        hid_dev->input_report = input_new;
     508                        if (allocated) {
     509                                free(input_old);
     510                        }
     511                        usb_hid_new_report();
     512                }
     513        }
     514       
     515        /*! @todo This should probably be atomic. */
     516        memcpy(hid_dev->input_report, buffer, buffer_size);
     517        hid_dev->input_report_size = buffer_size;
     518       
    492519        bool cont = false;
    493520       
     
    528555/*----------------------------------------------------------------------------*/
    529556
    530 const char *usb_hid_get_function_name(const usb_hid_dev_t *hid_dev)
    531 {
    532         switch (hid_dev->poll_pipe_index) {
    533         case USB_HID_KBD_POLL_EP_NO:
    534                 return HID_KBD_FUN_NAME;
    535                 break;
    536         case USB_HID_MOUSE_POLL_EP_NO:
    537                 return HID_MOUSE_FUN_NAME;
    538                 break;
    539         default:
    540                 return HID_GENERIC_FUN_NAME;
    541         }
    542 }
    543 
    544 /*----------------------------------------------------------------------------*/
    545 
    546 const char *usb_hid_get_class_name(const usb_hid_dev_t *hid_dev)
    547 {
    548         // this means that only boot protocol keyboards will be connected
    549         // to the console; there is probably no better way to do this
    550        
    551         switch (hid_dev->poll_pipe_index) {
    552         case USB_HID_KBD_POLL_EP_NO:
    553                 return HID_KBD_CLASS_NAME;
    554                 break;
    555         case USB_HID_MOUSE_POLL_EP_NO:
    556                 return HID_MOUSE_CLASS_NAME;
    557                 break;
    558         default:
    559                 return HID_GENERIC_CLASS_NAME;
    560         }
     557//const char *usb_hid_get_function_name(const usb_hid_dev_t *hid_dev)
     558//{
     559//      switch (hid_dev->poll_pipe_index) {
     560//      case USB_HID_KBD_POLL_EP_NO:
     561//              return HID_KBD_FUN_NAME;
     562//              break;
     563//      case USB_HID_MOUSE_POLL_EP_NO:
     564//              return HID_MOUSE_FUN_NAME;
     565//              break;
     566//      default:
     567//              return HID_GENERIC_FUN_NAME;
     568//      }
     569//}
     570
     571/*----------------------------------------------------------------------------*/
     572
     573//const char *usb_hid_get_class_name(const usb_hid_dev_t *hid_dev)
     574//{
     575//      // this means that only boot protocol keyboards will be connected
     576//      // to the console; there is probably no better way to do this
     577       
     578//      switch (hid_dev->poll_pipe_index) {
     579//      case USB_HID_KBD_POLL_EP_NO:
     580//              return HID_KBD_CLASS_NAME;
     581//              break;
     582//      case USB_HID_MOUSE_POLL_EP_NO:
     583//              return HID_MOUSE_CLASS_NAME;
     584//              break;
     585//      default:
     586//              return HID_GENERIC_CLASS_NAME;
     587//      }
     588//}
     589
     590/*----------------------------------------------------------------------------*/
     591
     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;
    561609}
    562610
  • uspace/drv/usbhid/usbhid.h

    re1dbcbc ra81a1d09  
    4444#include <usb/devdrv.h>
    4545#include <usb/classes/hid.h>
     46#include <bool.h>
    4647
    4748struct usb_hid_dev;
     
    9394        usb_hid_report_t *report;
    9495       
     96        uint8_t *input_report;
     97       
     98        size_t input_report_size;
     99       
    95100        /** Arbitrary data (e.g. a special structure for handling keyboard). */
    96101        void *data;
     
    120125     void *arg);
    121126
    122 const char *usb_hid_get_function_name(const usb_hid_dev_t *hid_dev);
     127//const char *usb_hid_get_function_name(const usb_hid_dev_t *hid_dev);
    123128
    124 const char *usb_hid_get_class_name(const usb_hid_dev_t *hid_dev);
     129//const char *usb_hid_get_class_name(const usb_hid_dev_t *hid_dev);
     130
     131void usb_hid_new_report(void);
     132
     133void usb_hid_report_received(void);
     134
     135bool usb_hid_report_ready(void);
    125136
    126137void usb_hid_free(usb_hid_dev_t **hid_dev);
  • uspace/drv/usbhub/Makefile

    re1dbcbc ra81a1d09  
    2828
    2929USPACE_PREFIX = ../..
    30 LIBS = $(LIBDRV_PREFIX)/libdrv.a $(LIBUSB_PREFIX)/libusb.a
    31 EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include -I$(LIBUSB_PREFIX)/include
     30
     31LIBS = \
     32        $(LIBUSBDEV_PREFIX)/libusbdev.a \
     33        $(LIBUSB_PREFIX)/libusb.a \
     34        $(LIBDRV_PREFIX)/libdrv.a
     35EXTRA_CFLAGS += \
     36        -I$(LIBUSB_PREFIX)/include \
     37        -I$(LIBUSBDEV_PREFIX)/include \
     38        -I$(LIBDRV_PREFIX)/include
     39
    3240BINARY = usbhub
    3341
  • uspace/drv/usbhub/ports.c

    re1dbcbc ra81a1d09  
    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/usbhub/usbhub.c

    re1dbcbc ra81a1d09  
    411411static int usb_process_hub_power_change(usb_hub_info_t * hub_info,
    412412    usb_hub_status_t status) {
    413         int opResult;
     413        int opResult = EOK;
    414414        if (!usb_hub_is_status(status,USB_HUB_FEATURE_HUB_LOCAL_POWER)) {
    415415                //restart power on hub
     
    431431                        }
    432432                }
    433                 opResult = usb_hub_clear_feature(hub_info->control_pipe,
    434                     USB_HUB_FEATURE_C_HUB_LOCAL_POWER);
     433        }
     434        if(opResult!=EOK){
     435                return opResult;//no feature clearing
     436        }
     437        opResult = usb_hub_clear_feature(hub_info->control_pipe,
     438            USB_HUB_FEATURE_C_HUB_LOCAL_POWER);
    435439                if (opResult != EOK) {
    436                         usb_log_error("cannnot clear hub power change flag: "
    437                             "%d\n",
    438                             opResult);
    439                 }
     440                usb_log_error("cannnot clear hub power change flag: "
     441                    "%d\n",
     442                    opResult);
    440443        }
    441444        return opResult;
  • uspace/drv/usbkbd/Makefile

    re1dbcbc ra81a1d09  
    2828
    2929USPACE_PREFIX = ../..
    30 LIBS = $(LIBDRV_PREFIX)/libdrv.a $(LIBUSB_PREFIX)/libusb.a
    31 EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include -I$(LIBUSB_PREFIX)/include -I.
     30
     31LIBS = \
     32        $(LIBUSBHID_PREFIX)/libusbhid.a \
     33        $(LIBUSBDEV_PREFIX)/libusbdev.a \
     34        $(LIBUSB_PREFIX)/libusb.a \
     35        $(LIBDRV_PREFIX)/libdrv.a
     36EXTRA_CFLAGS += \
     37        -I. \
     38        -I$(LIBUSB_PREFIX)/include \
     39        -I$(LIBUSBDEV_PREFIX)/include \
     40        -I$(LIBUSBHID_PREFIX)/include \
     41        -I$(LIBDRV_PREFIX)/include
     42
    3243BINARY = usbkbd
    3344
  • uspace/drv/usbkbd/kbddev.c

    re1dbcbc ra81a1d09  
    294294        usb_log_debug("Creating output report.\n");
    295295
    296         usb_hid_report_output_set_data(kbd_dev->parser, kbd_dev->led_path,
    297                                        USB_HID_PATH_COMPARE_END , kbd_dev->led_data,
    298                                        kbd_dev->led_output_size);
     296        //usb_hid_report_output_set_data(kbd_dev->parser, kbd_dev->led_path,
     297        //                               USB_HID_PATH_COMPARE_END , kbd_dev->led_data,
     298        //                               kbd_dev->led_output_size);
    299299        int rc = usb_hid_report_output_translate(kbd_dev->parser, 0,
    300300            kbd_dev->output_buffer, kbd_dev->output_size);
  • uspace/drv/usbmast/Makefile

    re1dbcbc ra81a1d09  
    2828
    2929USPACE_PREFIX = ../..
    30 LIBS = $(LIBDRV_PREFIX)/libdrv.a $(LIBUSB_PREFIX)/libusb.a
    31 EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include -I$(LIBUSB_PREFIX)/include
     30
     31LIBS = \
     32        $(LIBUSBDEV_PREFIX)/libusbdev.a \
     33        $(LIBUSB_PREFIX)/libusb.a \
     34        $(LIBDRV_PREFIX)/libdrv.a
     35EXTRA_CFLAGS += \
     36        -I$(LIBUSB_PREFIX)/include \
     37        -I$(LIBUSBDEV_PREFIX)/include \
     38        -I$(LIBDRV_PREFIX)/include
     39
    3240BINARY = usbmast
    3341
  • uspace/drv/usbmid/Makefile

    re1dbcbc ra81a1d09  
    2828
    2929USPACE_PREFIX = ../..
    30 LIBS = $(LIBDRV_PREFIX)/libdrv.a $(LIBUSB_PREFIX)/libusb.a
    31 EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include -I$(LIBUSB_PREFIX)/include
     30
     31LIBS = \
     32        $(LIBUSBDEV_PREFIX)/libusbdev.a \
     33        $(LIBUSB_PREFIX)/libusb.a \
     34        $(LIBDRV_PREFIX)/libdrv.a
     35EXTRA_CFLAGS += \
     36        -I$(LIBUSB_PREFIX)/include \
     37        -I$(LIBUSBDEV_PREFIX)/include \
     38        -I$(LIBDRV_PREFIX)/include
     39       
    3240BINARY = usbmid
    3341
  • uspace/drv/usbmouse/Makefile

    re1dbcbc ra81a1d09  
    2828
    2929USPACE_PREFIX = ../..
    30 LIBS = $(LIBDRV_PREFIX)/libdrv.a $(LIBUSB_PREFIX)/libusb.a
    31 EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include -I$(LIBUSB_PREFIX)/include -I.
     30
     31LIBS = \
     32        $(LIBUSBHID_PREFIX)/libusbhid.a \
     33        $(LIBUSBDEV_PREFIX)/libusbdev.a \
     34        $(LIBUSB_PREFIX)/libusb.a \
     35        $(LIBDRV_PREFIX)/libdrv.a
     36EXTRA_CFLAGS += \
     37        -I$(LIBUSB_PREFIX)/include \
     38        -I$(LIBUSBDEV_PREFIX)/include \
     39        -I$(LIBUSBHID_PREFIX)/include \
     40        -I$(LIBDRV_PREFIX)/include
    3241
    3342BINARY = usbmouse
  • uspace/drv/vhc/Makefile

    re1dbcbc ra81a1d09  
    2929USPACE_PREFIX = ../..
    3030LIBS = \
     31        $(LIBUSBDEV_PREFIX)/libusbdev.a \
     32        $(LIBUSBHOST_PREFIX)/libusbhost.a \
    3133        $(LIBUSB_PREFIX)/libusb.a \
    3234        $(LIBUSBVIRT_PREFIX)/libusbvirt.a \
     
    3436EXTRA_CFLAGS += \
    3537        -I$(LIBUSBVIRT_PREFIX)/include \
     38        -I$(LIBUSBDEV_PREFIX)/include \
     39        -I$(LIBUSBHOST_PREFIX)/include \
    3640        -I$(LIBUSB_PREFIX)/include \
    3741        -I$(LIBDRV_PREFIX)/include
  • uspace/drv/vhc/connhost.c

    re1dbcbc ra81a1d09  
    9494}
    9595
     96/** Find device handle by address interface function.
     97 *
     98 * @param[in] fun DDF function that was called.
     99 * @param[in] address Address in question.
     100 * @param[out] handle Where to store device handle if found.
     101 * @return Error code.
     102 */
     103static int find_by_address(ddf_fun_t *fun, usb_address_t address,
     104    devman_handle_t *handle)
     105{
     106        VHC_DATA(vhc, fun);
     107        bool found =
     108            usb_device_keeper_find_by_address(&vhc->dev_keeper, address, handle);
     109        return found ? EOK : ENOENT;
     110}
     111
    96112/** Release previously requested address.
    97113 *
     
    444460        .request_address = request_address,
    445461        .bind_address = bind_address,
     462        .find_by_address = find_by_address,
    446463        .release_address = release_address,
    447464
  • uspace/drv/vhc/main.c

    re1dbcbc ra81a1d09  
    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

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