Changeset 8c877b2 in mainline


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

merge with \usb\development

Files:
16 added
1 deleted
57 edited
2 moved

Legend:

Unmodified
Added
Removed
  • .bzrignore

    rdff940f8 r8c877b2  
    8989./uspace/drv/usbhid/usbhid
    9090./uspace/drv/usbmid/usbmid
     91./uspace/drv/usbmouse/usbmouse
    9192./uspace/drv/vhc/vhc
    9293./uspace/srv/bd/ata_bd/ata_bd
  • Makefile

    rdff940f8 r8c877b2  
    4242CONFIG_HEADER = config.h
    4343
    44 .PHONY: all precheck cscope autotool config_auto config_default config distclean clean check
     44.PHONY: all precheck cscope autotool config_auto config_default config distclean clean check distfile dist
    4545
    4646all: $(COMMON_MAKEFILE) $(COMMON_HEADER) $(CONFIG_MAKEFILE) $(CONFIG_HEADER)
     
    6464endif
    6565
     66# Autotool (detects compiler features)
     67
    6668$(COMMON_MAKEFILE): autotool
    6769$(COMMON_HEADER): autotool
     
    7072        $(AUTOTOOL)
    7173        -[ -f $(COMMON_HEADER_PREV) ] && diff -q $(COMMON_HEADER_PREV) $(COMMON_HEADER) && mv -f $(COMMON_HEADER_PREV) $(COMMON_HEADER)
     74
     75# Build-time configuration
    7276
    7377$(CONFIG_MAKEFILE): config_default
     
    8488        $(CONFIG) $<
    8589
     90# Distribution files
     91
     92distfile: all
     93        $(MAKE) -C dist distfile
     94
     95dist:
     96        $(MAKE) -C dist dist
     97
     98# Cleaning
     99
    86100distclean: clean
    87         rm -f $(CSCOPE).out $(COMMON_MAKEFILE) $(COMMON_HEADER) $(COMMON_HEADER_PREV) $(CONFIG_MAKEFILE) $(CONFIG_HEADER) tools/*.pyc tools/checkers/*.pyc
     101        rm -f $(CSCOPE).out $(COMMON_MAKEFILE) $(COMMON_HEADER) $(COMMON_HEADER_PREV) $(CONFIG_MAKEFILE) $(CONFIG_HEADER) tools/*.pyc tools/checkers/*.pyc dist/HelenOS-*
    88102
    89103clean:
  • boot/arch/amd64/Makefile.inc

    rdff940f8 r8c877b2  
    4848        usbhid \
    4949        usbmid \
     50        usbmouse \
    5051        vhc
    5152
  • boot/arch/sparc64/include/arch.h

    rdff940f8 r8c877b2  
    4141#define STACK_BIAS                   2047
    4242#define STACK_WINDOW_SAVE_AREA_SIZE  (16 * 8)
     43#define STACK_ARG_SAVE_AREA_SIZE     (6 * 8)
    4344
    4445#define NWINDOWS  8
  • boot/arch/sparc64/src/asm.S

    rdff940f8 r8c877b2  
    152152.global ofw
    153153ofw:
    154         save %sp, -STACK_WINDOW_SAVE_AREA_SIZE, %sp
     154        save %sp, -(STACK_WINDOW_SAVE_AREA_SIZE + STACK_ARG_SAVE_AREA_SIZE), %sp
    155155        set ofw_cif, %l0
    156156        ldx [%l0], %l0
  • boot/arch/sparc64/src/main.c

    rdff940f8 r8c877b2  
    190190        bootinfo.memmap.zones[0].start += OBP_BIAS;
    191191        bootinfo.memmap.zones[0].size -= OBP_BIAS;
     192        bootinfo.memmap.total -= OBP_BIAS;
    192193}
    193194
     
    204205        bootinfo.physmem_start = ofw_get_physmem_start();
    205206        ofw_memmap(&bootinfo.memmap);
     207
     208        if (arch == ARCH_SUN4V)
     209                sun4v_fixups();
    206210       
    207211        void *bootinfo_pa = ofw_translate(&bootinfo);
     
    253257               
    254258                /*
    255                  * At this point, we claim the physical memory that we are
    256                  * going to use. We should be safe in case of the virtual
     259                 * At this point, we claim and map the physical memory that we
     260                 * are going to use. We should be safe in case of the virtual
    257261                 * address space because the OpenFirmware, according to its
    258                  * SPARC binding, should restrict its use of virtual memory
    259                  * to addresses from [0xffd00000; 0xffefffff] and
    260                  * [0xfe000000; 0xfeffffff].
    261                  *
    262                  * We don't map this piece of memory. We simply rely on
    263                  * SILO to have it done for us already in this case.
    264                  *
    265                  * XXX SILO only maps 8 MB for us here. We should improve
    266                  *     this code to be totally independent on the behavior
    267                  *     of SILO.
    268                  *
     262                 * SPARC binding, should restrict its use of virtual memory to
     263                 * addresses from [0xffd00000; 0xffefffff] and [0xfe000000;
     264                 * 0xfeffffff].
    269265                 */
    270266                ofw_claim_phys(bootinfo.physmem_start + dest[i - 1],
    271267                    ALIGN_UP(components[i - 1].inflated, PAGE_SIZE));
     268               
     269                ofw_map(bootinfo.physmem_start + dest[i - 1], dest[i - 1],
     270                    ALIGN_UP(components[i - 1].inflated, PAGE_SIZE), -1);
    272271               
    273272                int err = inflate(components[i - 1].start, components[i - 1].size,
     
    304303                sun4u_smp();
    305304       
    306         if (arch == ARCH_SUN4V)
    307                 sun4v_fixups();
    308        
    309305        printf("Booting the kernel ...\n");
    310306        jump_to_kernel(bootinfo.physmem_start | BSP_PROCESSOR, &bootinfo, subarch,
  • boot/generic/src/balloc.c

    rdff940f8 r8c877b2  
    6565void *balloc_rebase(void *ptr)
    6666{
    67         return (void *) ((uintptr_t) ptr - phys_base + ballocs->base);
     67        return (void *) (((uintptr_t) ptr - phys_base) + ballocs->base);
    6868}
  • kernel/arch/sparc64/src/sun4v/asm.S

    rdff940f8 r8c877b2  
    4141.global switch_to_userspace
    4242switch_to_userspace:
    43         wrpr PSTATE_PRIV_BIT, %pstate
    44         save %o1, -STACK_WINDOW_SAVE_AREA_SIZE, %sp
     43        save %o1, -(STACK_WINDOW_SAVE_AREA_SIZE + STACK_ARG_SAVE_AREA_SIZE), %sp
    4544        flushw
    4645        wrpr %g0, 0, %cleanwin          ! avoid information leak
  • tools/toolchain.sh

    rdff940f8 r8c877b2  
    2828# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    2929#
     30
     31GMP_MAIN=<<EOF
     32#define GCC_GMP_VERSION_NUM(a, b, c) \
     33        (((a) << 16L) | ((b) << 8) | (c))
     34
     35#define GCC_GMP_VERSION \
     36        GCC_GMP_VERSION_NUM(__GNU_MP_VERSION, __GNU_MP_VERSION_MINOR, __GNU_MP_VERSION_PATCHLEVEL)
     37
     38#if GCC_GMP_VERSION < GCC_GMP_VERSION_NUM(4,3,2)
     39        choke me
     40#endif
     41EOF
     42
     43MPFR_MAIN=<<EOF
     44#if MPFR_VERSION < MPFR_VERSION_NUM(2, 4, 2)
     45choke me
     46        #endif
     47EOF
     48
     49MPC_MAIN=<<EOF
     50#if MPC_VERSION < MPC_VERSION_NUM(0, 8, 1)
     51        choke me
     52#endif
     53EOF
     54
     55#
     56# Check if the library described in the argument
     57# exists and has acceptable version.
     58#
     59check_dependency() {
     60        DEPENDENCY="$1"
     61        HEADER="$2"
     62        BODY="$3"
     63       
     64        FNAME="/tmp/conftest-$$"
     65       
     66        echo "#include ${HEADER}" > "${FNAME}.c"
     67        echo >> "${FNAME}.c"
     68        echo "int main()" >> "${FNAME}.c"
     69        echo "{" >> "${FNAME}.c"
     70        echo "${BODY}" >> "${FNAME}.c"
     71        echo "  return 0;" >> "${FNAME}.c"
     72        echo "}" >> "${FNAME}.c"
     73       
     74        cc -c -o "${FNAME}.o" "${FNAME}.c" 2> "${FNAME}.log"
     75        RC="$?"
     76       
     77        if [ "$RC" -ne "0" ] ; then
     78                echo " ${DEPENDENCY} not found, too old or compiler error."
     79                echo " Please recheck manually the source file \"${FNAME}.c\"."
     80                echo " The compilation of the toolchain is probably going to fail,"
     81                echo " you have been warned."
     82                echo
     83                echo " ===== Compiler output ====="
     84                cat "${FNAME}.log"
     85                echo " ==========================="
     86                echo
     87        else
     88                echo " ${DEPENDENCY} found"
     89                rm -f "${FNAME}.log" "${FNAME}.o" "${FNAME}.c"
     90        fi
     91}
     92
     93check_dependecies() {
     94        echo ">>> Basic dependency check"
     95        check_dependency "GMP" "<gmp.h>" "${GMP_MAIN}"
     96        check_dependency "MPFR" "<mpfr.h>" "${MPFR_MAIN}"
     97        check_dependency "MPC" "<mpc.h>" "${MPC_MAIN}"
     98        echo
     99}
    30100
    31101check_error() {
     
    69139        echo " sparc64    SPARC V9"
    70140        echo " all        build all targets"
     141        echo
     142        echo "The toolchain will be installed to the directory specified by"
     143        echo "the CROSS_PREFIX environment variable. If the variable is not"
     144        echo "defined, /usr/local will be used by default."
    71145        echo
    72146       
     
    118192        echo " - native C library with headers"
    119193        echo
    120        
    121         show_countdown 10
    122194}
    123195
     
    281353
    282354show_dependencies
     355check_dependecies
     356show_countdown 10
    283357
    284358case "$1" in
  • uspace/Makefile

    rdff940f8 r8c877b2  
    122122                drv/usbhub \
    123123                drv/usbmid \
     124                drv/usbmouse \
    124125                drv/vhc
    125126endif
     
    138139                drv/usbhub \
    139140                drv/usbmid \
     141                drv/usbmouse \
    140142                drv/vhc
    141143endif
  • uspace/app/bdsh/cmds/modules/mount/mount.c

    rdff940f8 r8c877b2  
    3131#include <vfs/vfs.h>
    3232#include <errno.h>
     33#include <getopt.h>
    3334#include "config.h"
    3435#include "util.h"
     
    4041static const char *cmdname = "mount";
    4142
    42 /* Dispays help for mount in various levels */
     43static struct option const long_options[] = {
     44        { "help", no_argument, 0, 'h' },
     45        { 0, 0, 0, 0 }
     46};
     47
     48
     49/* Displays help for mount in various levels */
    4350void help_cmd_mount(unsigned int level)
    4451{
     
    5966        unsigned int argc;
    6067        const char *mopts = "";
    61         int rc;
     68        int rc, c, opt_ind;
    6269
    6370        argc = cli_count_args(argv);
    6471
     72        for (c = 0, optind = 0, opt_ind = 0; c != -1;) {
     73                c = getopt_long(argc, argv, "h", long_options, &opt_ind);
     74                switch (c) {
     75                case 'h':
     76                        help_cmd_mount(HELP_LONG);
     77                        return CMD_SUCCESS;
     78                }
     79        }
     80
    6581        if ((argc < 4) || (argc > 5)) {
    66                 printf("%s: invalid number of arguments.\n",
     82                printf("%s: invalid number of arguments. Try `mount --help'\n",
    6783                    cmdname);
    6884                return CMD_FAILURE;
  • uspace/doc/doxygroups.h

    rdff940f8 r8c877b2  
    245245
    246246        /**
     247         * @defgroup drvusbmouse USB mouse driver
     248         * @ingroup usb
     249         * @brief USB driver for mouse with boot protocol.
     250         */
     251
     252        /**
    247253         * @defgroup drvusbuhci UHCI driver
    248254         * @ingroup usb
  • uspace/drv/pciintel/pci.c

    rdff940f8 r8c877b2  
    5959#include <ddi.h>
    6060#include <libarch/ddi.h>
     61#include <pci_dev_iface.h>
    6162
    6263#include "pci.h"
     
    9394  sysarg_t apic;
    9495  sysarg_t i8259;
     96
    9597        int irc_phone = -1;
    9698        int irc_service = 0;
     
    102104        }
    103105
    104   if (irc_service) {
    105     while (irc_phone < 0)
    106       irc_phone = service_connect_blocking(irc_service, 0, 0);
    107   } else {
     106  if (irc_service == 0)
    108107                return false;
    109         }
     108
     109        irc_phone = service_connect_blocking(irc_service, 0, 0);
     110        if (irc_phone < 0)
     111                return false;
    110112
    111113        size_t i;
     
    113115                if (dev_data->hw_resources.resources[i].type == INTERRUPT) {
    114116                        int irq = dev_data->hw_resources.resources[i].res.interrupt.irq;
    115                         async_msg_1(irc_phone, IRC_ENABLE_INTERRUPT, irq);
     117                        int rc = async_req_1_0(irc_phone, IRC_ENABLE_INTERRUPT, irq);
     118                        if (rc != EOK) {
     119                                async_hangup(irc_phone);
     120                                return false;
     121                        }
    116122                }
    117123        }
     
    120126        return true;
    121127}
     128
     129static int pci_config_space_write_16(ddf_fun_t *fun, uint32_t address, uint16_t data)
     130{
     131        if (address > 254)
     132                return EINVAL;
     133        pci_conf_write_16(PCI_FUN(fun), address, data);
     134        return EOK;
     135}
     136
    122137
    123138static hw_res_ops_t pciintel_hw_res_ops = {
     
    126141};
    127142
    128 static ddf_dev_ops_t pci_fun_ops;
     143static pci_dev_iface_t pci_dev_ops = {
     144        .config_space_read_8 = NULL,
     145        .config_space_read_16 = NULL,
     146        .config_space_read_32 = NULL,
     147        .config_space_write_8 = NULL,
     148        .config_space_write_16 = &pci_config_space_write_16,
     149        .config_space_write_32 = NULL
     150};
     151
     152static ddf_dev_ops_t pci_fun_ops = {
     153        .interfaces[HW_RES_DEV_IFACE] = &pciintel_hw_res_ops,
     154        .interfaces[PCI_DEV_IFACE] = &pci_dev_ops
     155};
    129156
    130157static int pci_add_device(ddf_dev_t *);
     
    320347        /* Get the value of the BAR. */
    321348        val = pci_conf_read_32(fun, addr);
     349
     350#define IO_MASK  (~0x3)
     351#define MEM_MASK (~0xf)
    322352       
    323353        io = (bool) (val & 1);
    324354        if (io) {
    325355                addrw64 = false;
     356                mask = IO_MASK;
    326357        } else {
     358                mask = MEM_MASK;
    327359                switch ((val >> 1) & 3) {
    328360                case 0:
     
    340372        /* Get the address mask. */
    341373        pci_conf_write_32(fun, addr, 0xffffffff);
    342         mask = pci_conf_read_32(fun, addr);
     374        mask &= pci_conf_read_32(fun, addr);
    343375       
    344376        /* Restore the original value. */
     
    588620{
    589621        pci_fun_ops.interfaces[HW_RES_DEV_IFACE] = &pciintel_hw_res_ops;
     622        pci_fun_ops.interfaces[PCI_DEV_IFACE] = &pci_dev_ops;
    590623}
    591624
     
    659692size_t pci_bar_mask_to_size(uint32_t mask)
    660693{
    661         return ((mask & 0xfffffff0) ^ 0xffffffff) + 1;
     694        size_t size = mask & ~(mask - 1);
     695        return size;
    662696}
    663697
  • uspace/drv/uhci-hcd/Makefile

    rdff940f8 r8c877b2  
    3939        uhci.c \
    4040        uhci_struct/transfer_descriptor.c \
     41        utils/device_keeper.c \
    4142        pci.c \
    4243        batch.c
  • uspace/drv/uhci-hcd/batch.c

    rdff940f8 r8c877b2  
    3333 */
    3434#include <errno.h>
    35 
     35#include <str_error.h>
     36
     37#include <usb/usb.h>
    3638#include <usb/debug.h>
    3739
     
    4547static int batch_schedule(batch_t *instance);
    4648
     49static void batch_control(
     50    batch_t *instance, int data_stage, int status_stage);
    4751static void batch_call_in(batch_t *instance);
    4852static void batch_call_out(batch_t *instance);
     
    5357batch_t * batch_get(ddf_fun_t *fun, usb_target_t target,
    5458    usb_transfer_type_t transfer_type, size_t max_packet_size,
    55     dev_speed_t speed, char *buffer, size_t size,
     59    usb_speed_t speed, char *buffer, size_t size,
    5660    char* setup_buffer, size_t setup_size,
    5761    usbhc_iface_transfer_in_callback_t func_in,
     
    9296        instance->transport_buffer =
    9397           (size > 0) ? malloc32(transport_size) : NULL;
     98
    9499        if ((size > 0) && (instance->transport_buffer == NULL)) {
    95100                usb_log_error("Failed to allocate device accessible buffer.\n");
     
    133138
    134139        queue_head_element_td(instance->qh, addr_to_phys(instance->tds));
     140        usb_log_debug("Batch(%p) %d:%d memory structures ready.\n",
     141            instance, target.address, target.endpoint);
    135142        return instance;
    136143}
     
    139146{
    140147        assert(instance);
    141         usb_log_debug("Checking(%p) %d packet for completion.\n",
     148        usb_log_debug2("Batch(%p) checking %d packet(s) for completion.\n",
    142149            instance, instance->packets);
    143150        instance->transfered_size = 0;
     
    151158                        if (i > 0)
    152159                                instance->transfered_size -= instance->setup_size;
     160                        usb_log_debug("Batch(%p) found error TD(%d):%x.\n",
     161                          instance, i, instance->tds[i].status);
    153162                        return true;
    154163                }
     
    156165                    transfer_descriptor_actual_size(&instance->tds[i]);
    157166        }
    158         /* This is just an ugly trick to support the old API */
    159167        instance->transfered_size -= instance->setup_size;
    160168        return true;
     
    164172{
    165173        assert(instance);
    166 
    167174        /* we are data out, we are supposed to provide data */
    168175        memcpy(instance->transport_buffer, instance->buffer, instance->buffer_size);
    169 
    170         int toggle = 0;
    171         /* setup stage */
    172         transfer_descriptor_init(instance->tds, DEFAULT_ERROR_COUNT,
    173             instance->setup_size, toggle, false, instance->target,
    174             USB_PID_SETUP, instance->setup_buffer, &instance->tds[1]);
    175 
    176         /* data stage */
    177         size_t i = 1;
    178         for (;i < instance->packets - 1; ++i) {
    179                 char *data =
    180                     instance->transport_buffer + ((i - 1) * instance->max_packet_size);
    181                 toggle = 1 - toggle;
    182 
    183                 transfer_descriptor_init(&instance->tds[i], DEFAULT_ERROR_COUNT,
    184                     instance->max_packet_size, toggle++, false, instance->target,
    185                     USB_PID_OUT, data, &instance->tds[i + 1]);
    186         }
    187 
    188         /* status stage */
    189         i = instance->packets - 1;
    190         transfer_descriptor_init(&instance->tds[i], DEFAULT_ERROR_COUNT,
    191             0, 1, false, instance->target, USB_PID_IN, NULL, NULL);
    192 
    193         instance->tds[i].status |= TD_STATUS_COMPLETE_INTERRUPT_FLAG;
    194 
     176        batch_control(instance, USB_PID_OUT, USB_PID_IN);
    195177        instance->next_step = batch_call_out_and_dispose;
     178        usb_log_debug("Batch(%p) CONTROL WRITE initialized.\n", instance);
    196179        batch_schedule(instance);
    197180}
     
    200183{
    201184        assert(instance);
    202 
    203         int toggle = 0;
    204         /* setup stage */
    205         transfer_descriptor_init(instance->tds, DEFAULT_ERROR_COUNT,
    206             instance->setup_size, toggle, false, instance->target,
    207             USB_PID_SETUP, instance->setup_buffer, &instance->tds[1]);
    208 
    209         /* data stage */
    210         size_t i = 1;
    211         for (;i < instance->packets - 1; ++i) {
    212                 char *data =
    213                     instance->transport_buffer + ((i - 1) * instance->max_packet_size);
    214                 toggle = 1 - toggle;
    215 
    216                 transfer_descriptor_init(&instance->tds[i], DEFAULT_ERROR_COUNT,
    217                     instance->max_packet_size, toggle, false, instance->target,
    218                     USB_PID_IN, data, &instance->tds[i + 1]);
    219         }
    220 
    221         /* status stage */
    222         i = instance->packets - 1;
    223         transfer_descriptor_init(&instance->tds[i], DEFAULT_ERROR_COUNT,
    224             0, 1, false, instance->target, USB_PID_OUT, NULL, NULL);
    225 
    226         instance->tds[i].status |= TD_STATUS_COMPLETE_INTERRUPT_FLAG;
    227 
     185        batch_control(instance, USB_PID_IN, USB_PID_OUT);
    228186        instance->next_step = batch_call_in_and_dispose;
     187        usb_log_debug("Batch(%p) CONTROL READ initialized.\n", instance);
    229188        batch_schedule(instance);
    230189}
     
    234193        assert(instance);
    235194
     195        const bool low_speed = instance->speed == USB_SPEED_LOW;
    236196        int toggle = 1;
    237197        size_t i = 0;
     
    244204
    245205                transfer_descriptor_init(&instance->tds[i], DEFAULT_ERROR_COUNT,
    246                     instance->max_packet_size, toggle, false, instance->target,
    247                     USB_PID_IN, data, next);
     206                    instance->max_packet_size, toggle, false, low_speed,
     207                    instance->target, USB_PID_IN, data, next);
    248208        }
    249209
     
    251211
    252212        instance->next_step = batch_call_in_and_dispose;
     213        usb_log_debug("Batch(%p) INTERRUPT IN initialized.\n", instance);
    253214        batch_schedule(instance);
    254215}
     
    257218{
    258219        assert(instance);
    259 
    260220        memcpy(instance->transport_buffer, instance->buffer, instance->buffer_size);
    261221
     222        const bool low_speed = instance->speed == USB_SPEED_LOW;
    262223        int toggle = 1;
    263224        size_t i = 0;
     
    270231
    271232                transfer_descriptor_init(&instance->tds[i], DEFAULT_ERROR_COUNT,
    272                     instance->max_packet_size, toggle++, false, instance->target,
    273                     USB_PID_OUT, data, next);
     233                    instance->max_packet_size, toggle++, false, low_speed,
     234                    instance->target, USB_PID_OUT, data, next);
    274235        }
    275236
     
    277238
    278239        instance->next_step = batch_call_out_and_dispose;
     240        usb_log_debug("Batch(%p) INTERRUPT OUT initialized.\n", instance);
    279241        batch_schedule(instance);
    280242}
    281243/*----------------------------------------------------------------------------*/
     244static void batch_control(
     245    batch_t *instance, int data_stage, int status_stage)
     246{
     247        assert(instance);
     248
     249        const bool low_speed = instance->speed == USB_SPEED_LOW;
     250        int toggle = 0;
     251        /* setup stage */
     252        transfer_descriptor_init(instance->tds, DEFAULT_ERROR_COUNT,
     253            instance->setup_size, toggle, false, low_speed, instance->target,
     254            USB_PID_SETUP, instance->setup_buffer, &instance->tds[1]);
     255
     256        /* data stage */
     257        size_t packet = 1;
     258        size_t remain_size = instance->buffer_size;
     259        while (remain_size > 0) {
     260                char *data =
     261                    instance->transport_buffer + instance->buffer_size
     262                    - remain_size;
     263
     264                toggle = 1 - toggle;
     265
     266                const size_t packet_size =
     267                    (instance->max_packet_size > remain_size) ?
     268                    remain_size : instance->max_packet_size;
     269
     270                transfer_descriptor_init(&instance->tds[packet],
     271                    DEFAULT_ERROR_COUNT, packet_size, toggle, false, low_speed,
     272                    instance->target, data_stage, data,
     273                    &instance->tds[packet + 1]);
     274
     275                ++packet;
     276                assert(packet < instance->packets);
     277                assert(packet_size <= remain_size);
     278                remain_size -= packet_size;
     279        }
     280
     281        /* status stage */
     282        assert(packet == instance->packets - 1);
     283        transfer_descriptor_init(&instance->tds[packet], DEFAULT_ERROR_COUNT,
     284            0, 1, false, low_speed, instance->target, status_stage, NULL, NULL);
     285
     286
     287        instance->tds[packet].status |= TD_STATUS_COMPLETE_INTERRUPT_FLAG;
     288        usb_log_debug2("Control last TD status: %x.\n",
     289            instance->tds[packet].status);
     290}
     291/*----------------------------------------------------------------------------*/
    282292void batch_call_in(batch_t *instance)
    283293{
     
    288298
    289299        int err = instance->error;
    290         usb_log_info("Callback IN(%d): %d, %zu.\n", instance->transfer_type,
    291             err, instance->transfered_size);
     300        usb_log_debug("Batch(%p) callback IN(type:%d): %s(%d), %zu.\n",
     301            instance, instance->transfer_type, str_error(err), err,
     302            instance->transfered_size);
    292303
    293304        instance->callback_in(instance->fun,
     
    302313
    303314        int err = instance->error;
    304         usb_log_info("Callback OUT(%d): %d.\n", instance->transfer_type, err);
     315        usb_log_debug("Batch(%p) callback OUT(type:%d): %s(%d).\n",
     316            instance, instance->transfer_type, str_error(err), err);
    305317        instance->callback_out(instance->fun,
    306318            err, instance->arg);
     
    311323        assert(instance);
    312324        batch_call_in(instance);
    313         usb_log_debug("Disposing batch: %p.\n", instance);
     325        usb_log_debug("Batch(%p) disposing.\n", instance);
    314326        free32(instance->tds);
    315327        free32(instance->qh);
     
    323335        assert(instance);
    324336        batch_call_out(instance);
    325         usb_log_debug("Disposing batch: %p.\n", instance);
     337        usb_log_debug("Batch(%p) disposing.\n", instance);
    326338        free32(instance->tds);
    327339        free32(instance->qh);
     
    338350        return uhci_schedule(hc, instance);
    339351}
    340 /*----------------------------------------------------------------------------*/
    341 /* DEPRECATED FUNCTIONS NEEDED BY THE OLD API */
    342 void batch_control_setup_old(batch_t *instance)
    343 {
    344         assert(instance);
    345         instance->packets = 1;
    346 
    347         /* setup stage */
    348         transfer_descriptor_init(instance->tds, DEFAULT_ERROR_COUNT,
    349             instance->setup_size, 0, false, instance->target,
    350             USB_PID_SETUP, instance->setup_buffer, NULL);
    351 
    352         instance->next_step = batch_call_out_and_dispose;
    353         batch_schedule(instance);
    354 }
    355 /*----------------------------------------------------------------------------*/
    356 void batch_control_write_data_old(batch_t *instance)
    357 {
    358         assert(instance);
    359         instance->packets -= 2;
    360         batch_interrupt_out(instance);
    361 }
    362 /*----------------------------------------------------------------------------*/
    363 void batch_control_read_data_old(batch_t *instance)
    364 {
    365         assert(instance);
    366         instance->packets -= 2;
    367         batch_interrupt_in(instance);
    368 }
    369 /*----------------------------------------------------------------------------*/
    370 void batch_control_write_status_old(batch_t *instance)
    371 {
    372         assert(instance);
    373         instance->packets = 1;
    374         transfer_descriptor_init(instance->tds, DEFAULT_ERROR_COUNT,
    375             0, 1, false, instance->target, USB_PID_IN, NULL, NULL);
    376         instance->next_step = batch_call_in_and_dispose;
    377         batch_schedule(instance);
    378 }
    379 /*----------------------------------------------------------------------------*/
    380 void batch_control_read_status_old(batch_t *instance)
    381 {
    382         assert(instance);
    383         instance->packets = 1;
    384         transfer_descriptor_init(instance->tds, DEFAULT_ERROR_COUNT,
    385             0, 1, false, instance->target, USB_PID_OUT, NULL, NULL);
    386         instance->next_step = batch_call_out_and_dispose;
    387         batch_schedule(instance);
    388 }
    389352/**
    390353 * @}
  • uspace/drv/uhci-hcd/batch.h

    rdff940f8 r8c877b2  
    4343#include "uhci_struct/queue_head.h"
    4444
    45 typedef enum {
    46         LOW_SPEED,
    47         FULL_SPEED,
    48 } dev_speed_t;
    49 
    5045typedef struct batch
    5146{
    5247        link_t link;
    53         dev_speed_t speed;
     48        usb_speed_t speed;
    5449        usb_target_t target;
    5550        usb_transfer_type_t transfer_type;
     
    7671batch_t * batch_get(ddf_fun_t *fun, usb_target_t target,
    7772    usb_transfer_type_t transfer_type, size_t max_packet_size,
    78     dev_speed_t speed, char *buffer, size_t size,
     73    usb_speed_t speed, char *buffer, size_t size,
    7974                char *setup_buffer, size_t setup_size,
    8075    usbhc_iface_transfer_in_callback_t func_in,
  • uspace/drv/uhci-hcd/iface.c

    rdff940f8 r8c877b2  
    4141#include "iface.h"
    4242#include "uhci.h"
     43#include "utils/device_keeper.h"
    4344
    4445/*----------------------------------------------------------------------------*/
     
    4849        uhci_t *hc = fun_to_uhci(fun);
    4950        assert(hc);
    50         usb_address_keeping_reserve_default(&hc->address_manager);
     51        usb_log_debug("Default address request with speed %d.\n", speed);
     52        device_keeper_reserve_default(&hc->device_manager, speed);
    5153        return EOK;
    5254}
     
    5759        uhci_t *hc = fun_to_uhci(fun);
    5860        assert(hc);
    59         usb_address_keeping_release_default(&hc->address_manager);
     61        usb_log_debug("Default address release.\n");
     62        device_keeper_release_default(&hc->device_manager);
    6063        return EOK;
    6164}
     
    6770        uhci_t *hc = fun_to_uhci(fun);
    6871        assert(hc);
    69         *address = usb_address_keeping_request(&hc->address_manager);
     72        assert(address);
     73
     74        usb_log_debug("Address request with speed %d.\n", speed);
     75        *address = device_keeper_request(&hc->device_manager, speed);
     76        usb_log_debug("Address request with result: %d.\n", *address);
    7077        if (*address <= 0)
    7178          return *address;
     
    7986        uhci_t *hc = fun_to_uhci(fun);
    8087        assert(hc);
    81         usb_address_keeping_devman_bind(&hc->address_manager, address, handle);
     88        usb_log_debug("Address bind %d-%d.\n", address, handle);
     89        device_keeper_bind(&hc->device_manager, address, handle);
    8290        return EOK;
    8391}
     
    8896        uhci_t *hc = fun_to_uhci(fun);
    8997        assert(hc);
    90         usb_address_keeping_release_default(&hc->address_manager);
     98        usb_log_debug("Address release %d.\n", address);
     99        device_keeper_release(&hc->device_manager, address);
    91100        return EOK;
    92101}
    93102/*----------------------------------------------------------------------------*/
    94103static int interrupt_out(ddf_fun_t *fun, usb_target_t target,
    95     size_t max_packet_size,
    96     void *data, size_t size,
     104    size_t max_packet_size, void *data, size_t size,
    97105    usbhc_iface_transfer_out_callback_t callback, void *arg)
    98106{
    99         dev_speed_t speed = FULL_SPEED;
     107        assert(fun);
     108        uhci_t *hc = fun_to_uhci(fun);
     109        assert(hc);
     110        usb_speed_t speed = device_keeper_speed(&hc->device_manager, target.address);
     111
     112        usb_log_debug("Interrupt OUT %d:%d %zu(%zu).\n",
     113            target.address, target.endpoint, size, max_packet_size);
    100114
    101115        batch_t *batch = batch_get(fun, target, USB_TRANSFER_INTERRUPT,
     
    108122/*----------------------------------------------------------------------------*/
    109123static int interrupt_in(ddf_fun_t *fun, usb_target_t target,
    110     size_t max_packet_size,
    111     void *data, size_t size,
     124    size_t max_packet_size, void *data, size_t size,
    112125    usbhc_iface_transfer_in_callback_t callback, void *arg)
    113126{
    114         dev_speed_t speed = FULL_SPEED;
     127        assert(fun);
     128        uhci_t *hc = fun_to_uhci(fun);
     129        assert(hc);
     130        usb_speed_t speed = device_keeper_speed(&hc->device_manager, target.address);
     131        usb_log_debug("Interrupt IN %d:%d %zu(%zu).\n",
     132            target.address, target.endpoint, size, max_packet_size);
    115133
    116134        batch_t *batch = batch_get(fun, target, USB_TRANSFER_INTERRUPT,
     
    127145    usbhc_iface_transfer_out_callback_t callback, void *arg)
    128146{
    129         dev_speed_t speed = FULL_SPEED;
     147        assert(fun);
     148        uhci_t *hc = fun_to_uhci(fun);
     149        assert(hc);
     150        usb_speed_t speed = device_keeper_speed(&hc->device_manager, target.address);
     151        usb_log_debug("Control WRITE %d:%d %zu(%zu).\n",
     152            target.address, target.endpoint, size, max_packet_size);
    130153
    131154        batch_t *batch = batch_get(fun, target, USB_TRANSFER_CONTROL,
     
    143166    usbhc_iface_transfer_in_callback_t callback, void *arg)
    144167{
    145         dev_speed_t speed = FULL_SPEED;
    146 
     168        assert(fun);
     169        uhci_t *hc = fun_to_uhci(fun);
     170        assert(hc);
     171        usb_speed_t speed = device_keeper_speed(&hc->device_manager, target.address);
     172
     173        usb_log_debug("Control READ %d:%d %zu(%zu).\n",
     174            target.address, target.endpoint, size, max_packet_size);
    147175        batch_t *batch = batch_get(fun, target, USB_TRANSFER_CONTROL,
    148176            max_packet_size, speed, data, size, setup_data, setup_size, callback,
  • uspace/drv/uhci-hcd/main.c

    rdff940f8 r8c877b2  
    3434#include <ddf/driver.h>
    3535#include <ddf/interrupt.h>
     36#include <device/hw_res.h>
     37#include <errno.h>
     38#include <str_error.h>
     39
    3640#include <usb_iface.h>
    3741#include <usb/ddfiface.h>
    38 #include <device/hw_res.h>
    39 
    40 #include <errno.h>
    41 
    4242#include <usb/debug.h>
    4343
     
    5050
    5151static int uhci_add_device(ddf_dev_t *device);
    52 
    5352/*----------------------------------------------------------------------------*/
    5453static driver_ops_t uhci_driver_ops = {
     
    7069}
    7170/*----------------------------------------------------------------------------*/
    72 #define CHECK_RET_RETURN(ret, message...) \
     71static int uhci_add_device(ddf_dev_t *device)
     72{
     73        assert(device);
     74        uhci_t *hcd = NULL;
     75#define CHECK_RET_FREE_HC_RETURN(ret, message...) \
    7376if (ret != EOK) { \
    7477        usb_log_error(message); \
     78        if (hcd != NULL) \
     79                free(hcd); \
    7580        return ret; \
    7681}
    7782
    78 static int uhci_add_device(ddf_dev_t *device)
    79 {
    80         assert(device);
    81 
    8283        usb_log_info("uhci_add_device() called\n");
    8384
    84 
    85         uintptr_t io_reg_base;
    86         size_t io_reg_size;
    87         int irq;
     85        uintptr_t io_reg_base = 0;
     86        size_t io_reg_size = 0;
     87        int irq = 0;
    8888
    8989        int ret =
    9090            pci_get_my_registers(device, &io_reg_base, &io_reg_size, &irq);
    91 
    92         CHECK_RET_RETURN(ret,
     91        CHECK_RET_FREE_HC_RETURN(ret,
    9392            "Failed(%d) to get I/O addresses:.\n", ret, device->handle);
    9493        usb_log_info("I/O regs at 0x%X (size %zu), IRQ %d.\n",
    9594            io_reg_base, io_reg_size, irq);
    9695
     96        ret = pci_disable_legacy(device);
     97        CHECK_RET_FREE_HC_RETURN(ret,
     98            "Failed(%d) disable legacy USB: %s.\n", ret, str_error(ret));
     99
     100#if 0
    97101        ret = pci_enable_interrupts(device);
    98         CHECK_RET_RETURN(ret, "Failed(%d) to get enable interrupts:\n", ret);
     102        if (ret != EOK) {
     103                usb_log_warning(
     104                    "Failed(%d) to enable interrupts, fall back to polling.\n",
     105                    ret);
     106        }
     107#endif
    99108
    100         uhci_t *uhci_hc = malloc(sizeof(uhci_t));
    101         ret = (uhci_hc != NULL) ? EOK : ENOMEM;
    102         CHECK_RET_RETURN(ret, "Failed to allocate memory for uhci hcd driver.\n");
     109        hcd = malloc(sizeof(uhci_t));
     110        ret = (hcd != NULL) ? EOK : ENOMEM;
     111        CHECK_RET_FREE_HC_RETURN(ret,
     112            "Failed(%d) to allocate memory for uhci hcd.\n", ret);
    103113
    104         ret = uhci_init(uhci_hc, device, (void*)io_reg_base, io_reg_size);
    105         if (ret != EOK) {
    106                 usb_log_error("Failed to init uhci-hcd.\n");
    107                 free(uhci_hc);
    108                 return ret;
    109         }
     114        ret = uhci_init(hcd, device, (void*)io_reg_base, io_reg_size);
     115        CHECK_RET_FREE_HC_RETURN(ret, "Failed(%d) to init uhci-hcd.\n",
     116            ret);
     117#undef CHECK_RET_FREE_HC_RETURN
    110118
    111119        /*
    112          * We might free uhci_hc, but that does not matter since no one
     120         * We might free hcd, but that does not matter since no one
    113121         * else would access driver_data anyway.
    114122         */
    115         device->driver_data = uhci_hc;
     123        device->driver_data = hcd;
    116124
     125        ddf_fun_t *rh = NULL;
     126#define CHECK_RET_FINI_FREE_RETURN(ret, message...) \
     127if (ret != EOK) { \
     128        usb_log_error(message); \
     129        if (hcd != NULL) {\
     130                uhci_fini(hcd); \
     131                free(hcd); \
     132        } \
     133        if (rh != NULL) \
     134                free(rh); \
     135        return ret; \
     136}
     137
     138        /* It does no harm if we register this on polling */
    117139        ret = register_interrupt_handler(device, irq, irq_handler,
    118             &uhci_hc->interrupt_code);
    119         if (ret != EOK) {
    120                 usb_log_error("Failed to register interrupt handler.\n");
    121                 uhci_fini(uhci_hc);
    122                 free(uhci_hc);
    123                 return ret;
    124         }
     140            &hcd->interrupt_code);
     141        CHECK_RET_FINI_FREE_RETURN(ret,
     142            "Failed(%d) to register interrupt handler.\n", ret);
    125143
    126         ddf_fun_t *rh;
    127144        ret = setup_root_hub(&rh, device);
    128         if (ret != EOK) {
    129                 usb_log_error("Failed to setup uhci root hub.\n");
    130                 uhci_fini(uhci_hc);
    131                 free(uhci_hc);
    132                 return ret;
    133         }
    134         rh->driver_data = uhci_hc->ddf_instance;
     145        CHECK_RET_FINI_FREE_RETURN(ret,
     146            "Failed(%d) to setup UHCI root hub.\n", ret);
     147        rh->driver_data = hcd->ddf_instance;
    135148
    136149        ret = ddf_fun_bind(rh);
    137         if (ret != EOK) {
    138                 usb_log_error("Failed to register root hub.\n");
    139                 uhci_fini(uhci_hc);
    140                 free(uhci_hc);
    141                 free(rh);
    142                 return ret;
    143         }
     150        CHECK_RET_FINI_FREE_RETURN(ret,
     151            "Failed(%d) to register UHCI root hub.\n", ret);
    144152
    145153        return EOK;
     154#undef CHECK_RET_FINI_FREE_RETURN
    146155}
    147156/*----------------------------------------------------------------------------*/
     
    149158{
    150159        sleep(3);
    151         usb_log_enable(USB_LOG_LEVEL_INFO, NAME);
     160        usb_log_enable(USB_LOG_LEVEL_DEBUG, NAME);
    152161
    153162        return ddf_driver_main(&uhci_driver);
  • uspace/drv/uhci-hcd/pci.c

    rdff940f8 r8c877b2  
    3838#include <devman.h>
    3939#include <device/hw_res.h>
     40
     41#include <usb/debug.h>
     42#include <pci_dev_iface.h>
    4043
    4144#include "pci.h"
     
    8386                                irq = res->res.interrupt.irq;
    8487                                irq_found = true;
     88                                usb_log_debug2("Found interrupt: %d.\n", irq);
    8589                                break;
    8690                        case IO_RANGE:
    87                                 io_address = (uintptr_t)
    88                                     res->res.io_range.address;
     91                                io_address = res->res.io_range.address;
    8992                                io_size = res->res.io_range.size;
     93                                usb_log_debug2("Found io: %llx %zu.\n",
     94                                    res->res.io_range.address, res->res.io_range.size);
    9095                                io_found = true;
    9196                                break;
     
    105110        }
    106111
    107         if (io_reg_address != NULL) {
    108                 *io_reg_address = io_address;
    109         }
    110         if (io_reg_size != NULL) {
    111                 *io_reg_size = io_size;
    112         }
    113         if (irq_no != NULL) {
    114                 *irq_no = irq;
    115         }
     112        *io_reg_address = io_address;
     113        *io_reg_size = io_size;
     114        *irq_no = irq;
    116115
    117116        rc = EOK;
     
    127126            IPC_FLAG_BLOCKING);
    128127        bool enabled = hw_res_enable_interrupt(parent_phone);
     128        async_hangup(parent_phone);
    129129        return enabled ? EOK : EIO;
    130130}
     131/*----------------------------------------------------------------------------*/
     132int pci_disable_legacy(ddf_dev_t *device)
     133{
     134        assert(device);
     135        int parent_phone = devman_parent_device_connect(device->handle,
     136                IPC_FLAG_BLOCKING);
     137        if (parent_phone < 0) {
     138                return parent_phone;
     139        }
     140
     141        /* See UHCI design guide for these values,
     142         * write all WC bits in USB legacy register */
     143        sysarg_t address = 0xc0;
     144        sysarg_t value = 0x8f00;
     145
     146  int rc = async_req_3_0(parent_phone, DEV_IFACE_ID(PCI_DEV_IFACE),
     147            IPC_M_CONFIG_SPACE_WRITE_16, address, value);
     148        async_hangup(parent_phone);
     149
     150  return rc;
     151}
     152/*----------------------------------------------------------------------------*/
    131153/**
    132154 * @}
  • uspace/drv/uhci-hcd/pci.h

    rdff940f8 r8c877b2  
    4040int pci_get_my_registers(ddf_dev_t *, uintptr_t *, size_t *, int *);
    4141int pci_enable_interrupts(ddf_dev_t *);
     42int pci_disable_legacy(ddf_dev_t *);
    4243
    4344#endif
  • uspace/drv/uhci-hcd/root_hub.c

    rdff940f8 r8c877b2  
    3434#include <assert.h>
    3535#include <errno.h>
     36#include <str_error.h>
    3637#include <stdio.h>
     38#include <ops/hw_res.h>
     39
    3740#include <usb_iface.h>
    3841#include <usb/debug.h>
     
    4144#include "uhci.h"
    4245
     46/*----------------------------------------------------------------------------*/
    4347static int usb_iface_get_hc_handle_rh_impl(ddf_fun_t *root_hub_fun,
    4448    devman_handle_t *handle)
     
    5155        return EOK;
    5256}
    53 
     57/*----------------------------------------------------------------------------*/
    5458static int usb_iface_get_address_rh_impl(ddf_fun_t *fun, devman_handle_t handle,
    5559    usb_address_t *address)
     
    6165        assert(hc);
    6266
    63         usb_address_t addr = usb_address_keeping_find(&hc->address_manager,
     67        usb_address_t addr = device_keeper_find(&hc->device_manager,
    6468            handle);
    6569        if (addr < 0) {
     
    7377        return EOK;
    7478}
    75 
     79/*----------------------------------------------------------------------------*/
    7680usb_iface_t usb_iface_root_hub_fun_impl = {
    7781        .get_hc_handle = usb_iface_get_hc_handle_rh_impl,
    7882        .get_address = usb_iface_get_address_rh_impl
    7983};
     84/*----------------------------------------------------------------------------*/
     85static hw_resource_list_t *get_resource_list(ddf_fun_t *dev)
     86{
     87        assert(dev);
     88        ddf_fun_t *hc_ddf_instance = dev->driver_data;
     89        assert(hc_ddf_instance);
     90        uhci_t *hc = hc_ddf_instance->driver_data;
     91        assert(hc);
    8092
     93        //TODO: fix memory leak
     94        hw_resource_list_t *resource_list = malloc(sizeof(hw_resource_list_t));
     95        assert(resource_list);
     96        resource_list->count = 1;
     97        resource_list->resources = malloc(sizeof(hw_resource_t));
     98        assert(resource_list->resources);
     99        resource_list->resources[0].type = IO_RANGE;
     100        resource_list->resources[0].res.io_range.address =
     101            ((uintptr_t)hc->registers) + 0x10; // see UHCI design guide
     102        resource_list->resources[0].res.io_range.size = 4;
     103        resource_list->resources[0].res.io_range.endianness = LITTLE_ENDIAN;
     104
     105        return resource_list;
     106}
     107/*----------------------------------------------------------------------------*/
     108static hw_res_ops_t hw_res_iface = {
     109        .get_resource_list = get_resource_list,
     110        .enable_interrupt = NULL
     111};
     112/*----------------------------------------------------------------------------*/
    81113static ddf_dev_ops_t root_hub_ops = {
    82         .interfaces[USB_DEV_IFACE] = &usb_iface_root_hub_fun_impl
     114        .interfaces[USB_DEV_IFACE] = &usb_iface_root_hub_fun_impl,
     115        .interfaces[HW_RES_DEV_IFACE] = &hw_res_iface
    83116};
    84 
    85117/*----------------------------------------------------------------------------*/
    86118int setup_root_hub(ddf_fun_t **fun, ddf_dev_t *hc)
    87119{
    88120        assert(fun);
     121        assert(hc);
    89122        int ret;
    90123
     
    105138        ret = ddf_fun_add_match_id(hub, match_str, 100);
    106139        if (ret != EOK) {
    107                 usb_log_error("Failed to add root hub match id.\n");
     140                usb_log_error("Failed(%d) to add root hub match id: %s\n",
     141                    ret, str_error(ret));
    108142                ddf_fun_destroy(hub);
    109                 return ENOMEM;
     143                return ret;
    110144        }
    111145
  • uspace/drv/uhci-hcd/transfer_list.c

    rdff940f8 r8c877b2  
    7070        assert(instance);
    7171        assert(batch);
     72        usb_log_debug2("Adding batch(%p) to queue %s.\n", batch, instance->name);
    7273
    7374        uint32_t pa = (uintptr_t)addr_to_phys(batch->qh);
     
    8384                list_append(&batch->link, &instance->batch_list);
    8485                instance->queue_head->element = pa;
    85                 usb_log_debug2("Added batch(%p) to queue %s first.\n",
     86                usb_log_debug("Batch(%p) added to queue %s first.\n",
    8687                        batch, instance->name);
    8788                fibril_mutex_unlock(&instance->guard);
     
    9697        queue_head_append_qh(last->qh, pa);
    9798        list_append(&batch->link, &instance->batch_list);
    98         usb_log_debug2("Added batch(%p) to queue %s last, first is %p.\n",
     99        usb_log_debug("Batch(%p) added to queue %s last, first is %p.\n",
    99100                batch, instance->name, first );
    100101        fibril_mutex_unlock(&instance->guard);
     
    108109        assert(instance->queue_head);
    109110        assert(batch->qh);
     111        usb_log_debug2("Removing batch(%p) from queue %s.\n", batch, instance->name);
    110112
    111113        /* I'm the first one here */
    112114        if (batch->link.prev == &instance->batch_list) {
    113                 usb_log_debug("Removing batch %p was first, next element %x.\n",
    114                         batch, batch->qh->next_queue);
     115                usb_log_debug("Batch(%p) removed (FIRST) from queue %s, next element %x.\n",
     116                        batch, instance->name, batch->qh->next_queue);
    115117                instance->queue_head->element = batch->qh->next_queue;
    116118        } else {
    117                 usb_log_debug("Removing batch %p was NOT first, next element %x.\n",
    118                         batch, batch->qh->next_queue);
     119                usb_log_debug("Batch(%p) removed (NOT FIRST) from queue, next element %x.\n",
     120                        batch, instance->name, batch->qh->next_queue);
    119121                batch_t *prev = list_get_instance(batch->link.prev, batch_t, link);
    120122                prev->qh->next_queue = batch->qh->next_queue;
     
    123125}
    124126/*----------------------------------------------------------------------------*/
    125 void transfer_list_check(transfer_list_t *instance)
     127void transfer_list_remove_finished(transfer_list_t *instance)
    126128{
    127129        assert(instance);
     130
     131        LIST_INITIALIZE(done);
     132
    128133        fibril_mutex_lock(&instance->guard);
    129134        link_t *current = instance->batch_list.next;
     
    134139                if (batch_is_complete(batch)) {
    135140                        transfer_list_remove_batch(instance, batch);
    136                         batch->next_step(batch);
     141                        list_append(current, &done);
    137142                }
    138143                current = next;
    139144        }
    140145        fibril_mutex_unlock(&instance->guard);
     146
     147        while (!list_empty(&done)) {
     148                link_t *item = done.next;
     149                list_remove(item);
     150                batch_t *batch = list_get_instance(item, batch_t, link);
     151                batch->next_step(batch);
     152        }
    141153}
    142154/**
  • uspace/drv/uhci-hcd/transfer_list.h

    rdff940f8 r8c877b2  
    6060        queue_head_dispose(instance->queue_head);
    6161}
    62 void transfer_list_check(transfer_list_t *instance);
     62void transfer_list_remove_finished(transfer_list_t *instance);
    6363
    6464void transfer_list_add_batch(transfer_list_t *instance, batch_t *batch);
  • uspace/drv/uhci-hcd/uhci-hcd.ma

    rdff940f8 r8c877b2  
    1110 pci/ven=8086&dev=7020
    2210 pci/ven=8086&dev=7112
     3
     410 pci/ven=8086&dev=27c8
     510 pci/ven=8086&dev=27c9
     610 pci/ven=8086&dev=27ca
     710 pci/ven=8086&dev=27cb
     8
     9
     1010 pci/ven=8086&dev=2830
     1110 pci/ven=8086&dev=2831
     1210 pci/ven=8086&dev=2832
     1310 pci/ven=8086&dev=2834
     1410 pci/ven=8086&dev=2835
     15
     1610 pci/ven=8086&dev=2934
     1710 pci/ven=8086&dev=2935
     1810 pci/ven=8086&dev=2936
     1910 pci/ven=8086&dev=2937
     2010 pci/ven=8086&dev=2938
     2110 pci/ven=8086&dev=2939
  • uspace/drv/uhci-hcd/uhci.c

    rdff940f8 r8c877b2  
    4848        {
    4949                .cmd = CMD_PIO_READ_16,
    50                 .addr = (void*)0xc022,
     50                .addr = NULL, /* patched for every instance */
    5151                .dstarg = 1
    5252        },
    5353        {
    5454                .cmd = CMD_PIO_WRITE_16,
    55                 .addr = (void*)0xc022,
     55                .addr = NULL, /* pathed for every instance */
    5656                .value = 0x1f
    5757        },
     
    6868        assert(hc);
    6969
    70         usb_address_t addr = usb_address_keeping_find(&hc->address_manager,
     70        usb_address_t addr = device_keeper_find(&hc->device_manager,
    7171            handle);
    7272        if (addr < 0) {
     
    8080        return EOK;
    8181}
    82 
    83 
     82/*----------------------------------------------------------------------------*/
    8483static usb_iface_t hc_usb_iface = {
    8584        .get_hc_handle = usb_iface_get_hc_handle_hc_impl,
     
    8988static ddf_dev_ops_t uhci_ops = {
    9089        .interfaces[USB_DEV_IFACE] = &hc_usb_iface,
    91         .interfaces[USBHC_DEV_IFACE] = &uhci_iface
     90        .interfaces[USBHC_DEV_IFACE] = &uhci_iface,
    9291};
    93 
     92/*----------------------------------------------------------------------------*/
    9493static int uhci_init_transfer_lists(uhci_t *instance);
    9594static int uhci_init_mem_structures(uhci_t *instance);
     
    102101        bool low_speed, usb_transfer_type_t, size_t size);
    103102
    104 #define CHECK_RET_RETURN(ret, message...) \
     103
     104int uhci_init(uhci_t *instance, ddf_dev_t *dev, void *regs, size_t reg_size)
     105{
     106        assert(reg_size >= sizeof(regs_t));
     107        int ret;
     108
     109#define CHECK_RET_DEST_FUN_RETURN(ret, message...) \
    105110        if (ret != EOK) { \
    106111                usb_log_error(message); \
     112                if (instance->ddf_instance) \
     113                        ddf_fun_destroy(instance->ddf_instance); \
    107114                return ret; \
    108115        } else (void) 0
    109116
    110 int uhci_init(uhci_t *instance, ddf_dev_t *dev, void *regs, size_t reg_size)
    111 {
    112         assert(reg_size >= sizeof(regs_t));
    113         int ret;
    114 
    115         /*
    116          * Create UHCI function.
    117          */
     117        /* Create UHCI function. */
    118118        instance->ddf_instance = ddf_fun_create(dev, fun_exposed, "uhci");
    119         if (instance->ddf_instance == NULL) {
    120                 usb_log_error("Failed to create UHCI device function.\n");
    121                 return ENOMEM;
    122         }
     119        ret = (instance->ddf_instance == NULL) ? ENOMEM : EOK;
     120        CHECK_RET_DEST_FUN_RETURN(ret,
     121            "Failed to create UHCI device function.\n");
     122
    123123        instance->ddf_instance->ops = &uhci_ops;
    124124        instance->ddf_instance->driver_data = instance;
    125125
    126126        ret = ddf_fun_bind(instance->ddf_instance);
    127         CHECK_RET_RETURN(ret, "Failed to bind UHCI device function: %s.\n",
    128             str_error(ret));
     127        CHECK_RET_DEST_FUN_RETURN(ret,
     128            "Failed(%d) to bind UHCI device function: %s.\n",
     129            ret, str_error(ret));
    129130
    130131        /* allow access to hc control registers */
    131132        regs_t *io;
    132133        ret = pio_enable(regs, reg_size, (void**)&io);
    133         CHECK_RET_RETURN(ret, "Failed to gain access to registers at %p.\n", io);
     134        CHECK_RET_DEST_FUN_RETURN(ret,
     135            "Failed(%d) to gain access to registers at %p: %s.\n",
     136            ret, str_error(ret), io);
    134137        instance->registers = io;
    135         usb_log_debug("Device registers accessible.\n");
     138        usb_log_debug("Device registers at %p(%u) accessible.\n",
     139            io, reg_size);
    136140
    137141        ret = uhci_init_mem_structures(instance);
    138         CHECK_RET_RETURN(ret, "Failed to initialize memory structures.\n");
     142        CHECK_RET_DEST_FUN_RETURN(ret,
     143            "Failed to initialize UHCI memory structures.\n");
    139144
    140145        uhci_init_hw(instance);
    141 
    142         instance->cleaner = fibril_create(uhci_interrupt_emulator, instance);
    143 //      fibril_add_ready(instance->cleaner);
     146        instance->cleaner =
     147            fibril_create(uhci_interrupt_emulator, instance);
     148        fibril_add_ready(instance->cleaner);
    144149
    145150        instance->debug_checker = fibril_create(uhci_debug_checker, instance);
    146151        fibril_add_ready(instance->debug_checker);
    147152
    148         return EOK;
     153        usb_log_info("Started UHCI driver.\n");
     154        return EOK;
     155#undef CHECK_RET_DEST_FUN_RETURN
    149156}
    150157/*----------------------------------------------------------------------------*/
    151158void uhci_init_hw(uhci_t *instance)
    152159{
     160        assert(instance);
     161
     162        /* reset everything, who knows what touched it before us */
     163        pio_write_16(&instance->registers->usbcmd, UHCI_CMD_GLOBAL_RESET);
     164        async_usleep(10000); /* 10ms according to USB spec */
     165        pio_write_16(&instance->registers->usbcmd, 0);
     166
     167        /* reset hc, all states and counters */
     168        pio_write_16(&instance->registers->usbcmd, UHCI_CMD_HCRESET);
     169        while ((pio_read_16(&instance->registers->usbcmd) & UHCI_CMD_HCRESET) != 0)
     170                { async_usleep(10); }
    153171
    154172        /* set framelist pointer */
     
    158176        /* enable all interrupts, but resume interrupt */
    159177        pio_write_16(&instance->registers->usbintr,
    160                   UHCI_INTR_CRC | UHCI_INTR_COMPLETE | UHCI_INTR_SHORT_PACKET);
     178            UHCI_INTR_CRC | UHCI_INTR_COMPLETE | UHCI_INTR_SHORT_PACKET);
    161179
    162180        /* Start the hc with large(64B) packet FSBR */
    163181        pio_write_16(&instance->registers->usbcmd,
    164182            UHCI_CMD_RUN_STOP | UHCI_CMD_MAX_PACKET | UHCI_CMD_CONFIGURE);
    165         usb_log_debug("Started UHCI HC.\n");
    166183}
    167184/*----------------------------------------------------------------------------*/
     
    169186{
    170187        assert(instance);
     188#define CHECK_RET_DEST_CMDS_RETURN(ret, message...) \
     189        if (ret != EOK) { \
     190                usb_log_error(message); \
     191                if (instance->interrupt_code.cmds != NULL) \
     192                        free(instance->interrupt_code.cmds); \
     193                return ret; \
     194        } else (void) 0
    171195
    172196        /* init interrupt code */
    173         irq_cmd_t *interrupt_commands = malloc(sizeof(uhci_cmds));
    174         if (interrupt_commands == NULL) {
    175                 return ENOMEM;
    176         }
    177         memcpy(interrupt_commands, uhci_cmds, sizeof(uhci_cmds));
    178         interrupt_commands[0].addr = (void*)&instance->registers->usbsts;
    179         interrupt_commands[1].addr = (void*)&instance->registers->usbsts;
    180         instance->interrupt_code.cmds = interrupt_commands;
    181         instance->interrupt_code.cmdcount =
    182             sizeof(uhci_cmds) / sizeof(irq_cmd_t);
     197        instance->interrupt_code.cmds = malloc(sizeof(uhci_cmds));
     198        int ret = (instance->interrupt_code.cmds == NULL) ? ENOMEM : EOK;
     199        CHECK_RET_DEST_CMDS_RETURN(ret, "Failed to allocate interrupt cmds space.\n");
     200
     201        {
     202                irq_cmd_t *interrupt_commands = instance->interrupt_code.cmds;
     203                memcpy(interrupt_commands, uhci_cmds, sizeof(uhci_cmds));
     204                interrupt_commands[0].addr = (void*)&instance->registers->usbsts;
     205                interrupt_commands[1].addr = (void*)&instance->registers->usbsts;
     206                instance->interrupt_code.cmdcount =
     207                    sizeof(uhci_cmds) / sizeof(irq_cmd_t);
     208        }
    183209
    184210        /* init transfer lists */
    185         int ret = uhci_init_transfer_lists(instance);
    186         CHECK_RET_RETURN(ret, "Failed to initialize transfer lists.\n");
     211        ret = uhci_init_transfer_lists(instance);
     212        CHECK_RET_DEST_CMDS_RETURN(ret, "Failed to initialize transfer lists.\n");
    187213        usb_log_debug("Initialized transfer lists.\n");
    188214
     
    190216        instance->frame_list = get_page();
    191217        ret = instance ? EOK : ENOMEM;
    192         CHECK_RET_RETURN(ret, "Failed to get frame list page.\n");
     218        CHECK_RET_DEST_CMDS_RETURN(ret, "Failed to get frame list page.\n");
    193219        usb_log_debug("Initialized frame list.\n");
    194220
     
    197223          instance->transfers_interrupt.queue_head_pa
    198224          | LINK_POINTER_QUEUE_HEAD_FLAG;
     225
    199226        unsigned i = 0;
    200227        for(; i < UHCI_FRAME_LIST_COUNT; ++i) {
     
    203230
    204231        /* init address keeper(libusb) */
    205         usb_address_keeping_init(&instance->address_manager, USB11_ADDRESS_MAX);
    206         usb_log_debug("Initialized address manager.\n");
    207 
    208         return EOK;
     232        device_keeper_init(&instance->device_manager);
     233        usb_log_debug("Initialized device manager.\n");
     234
     235        return EOK;
     236#undef CHECK_RET_DEST_CMDS_RETURN
    209237}
    210238/*----------------------------------------------------------------------------*/
     
    212240{
    213241        assert(instance);
     242#define CHECK_RET_CLEAR_RETURN(ret, message...) \
     243        if (ret != EOK) { \
     244                usb_log_error(message); \
     245                transfer_list_fini(&instance->transfers_bulk_full); \
     246                transfer_list_fini(&instance->transfers_control_full); \
     247                transfer_list_fini(&instance->transfers_control_slow); \
     248                transfer_list_fini(&instance->transfers_interrupt); \
     249                return ret; \
     250        } else (void) 0
    214251
    215252        /* initialize TODO: check errors */
    216253        int ret;
    217254        ret = transfer_list_init(&instance->transfers_bulk_full, "BULK_FULL");
    218         assert(ret == EOK);
     255        CHECK_RET_CLEAR_RETURN(ret, "Failed to init BULK list.");
     256
    219257        ret = transfer_list_init(&instance->transfers_control_full, "CONTROL_FULL");
    220         assert(ret == EOK);
     258        CHECK_RET_CLEAR_RETURN(ret, "Failed to init CONTROL FULL list.");
     259
    221260        ret = transfer_list_init(&instance->transfers_control_slow, "CONTROL_SLOW");
    222         assert(ret == EOK);
     261        CHECK_RET_CLEAR_RETURN(ret, "Failed to init CONTROL SLOW list.");
     262
    223263        ret = transfer_list_init(&instance->transfers_interrupt, "INTERRUPT");
    224         assert(ret == EOK);
     264        CHECK_RET_CLEAR_RETURN(ret, "Failed to init INTERRUPT list.");
    225265
    226266        transfer_list_set_next(&instance->transfers_control_full,
     
    249289
    250290        return EOK;
     291#undef CHECK_RET_CLEAR_RETURN
    251292}
    252293/*----------------------------------------------------------------------------*/
     
    255296        assert(instance);
    256297        assert(batch);
    257         const int low_speed = (batch->speed == LOW_SPEED);
     298        const int low_speed = (batch->speed == USB_SPEED_LOW);
    258299        if (!allowed_usb_packet(
    259300            low_speed, batch->transfer_type, batch->max_packet_size)) {
    260301                usb_log_warning("Invalid USB packet specified %s SPEED %d %zu.\n",
    261                           low_speed ? "LOW" : "FULL" , batch->transfer_type,
     302                    low_speed ? "LOW" : "FULL" , batch->transfer_type,
    262303                    batch->max_packet_size);
    263304                return ENOTSUP;
     
    276317{
    277318        assert(instance);
    278         if ((status & (UHCI_STATUS_INTERRUPT | UHCI_STATUS_ERROR_INTERRUPT)) == 0)
    279                 return;
    280         usb_log_debug("UHCI interrupt: %X.\n", status);
    281         transfer_list_check(&instance->transfers_interrupt);
    282         transfer_list_check(&instance->transfers_control_slow);
    283         transfer_list_check(&instance->transfers_control_full);
    284         transfer_list_check(&instance->transfers_bulk_full);
     319        transfer_list_remove_finished(&instance->transfers_interrupt);
     320        transfer_list_remove_finished(&instance->transfers_control_slow);
     321        transfer_list_remove_finished(&instance->transfers_control_full);
     322        transfer_list_remove_finished(&instance->transfers_bulk_full);
    285323}
    286324/*----------------------------------------------------------------------------*/
     
    291329        assert(instance);
    292330
    293         while(1) {
     331        while (1) {
    294332                uint16_t status = pio_read_16(&instance->registers->usbsts);
     333                if (status != 0)
     334                        usb_log_debug2("UHCI status: %x.\n", status);
     335                status |= 1;
    295336                uhci_interrupt(instance, status);
    296                 async_usleep(UHCI_CLEANER_TIMEOUT);
     337                pio_write_16(&instance->registers->usbsts, 0x1f);
     338                async_usleep(UHCI_CLEANER_TIMEOUT * 5);
    297339        }
    298340        return EOK;
     
    303345        uhci_t *instance = (uhci_t*)arg;
    304346        assert(instance);
     347
     348#define QH(queue) \
     349        instance->transfers_##queue.queue_head
     350
    305351        while (1) {
    306352                const uint16_t cmd = pio_read_16(&instance->registers->usbcmd);
    307353                const uint16_t sts = pio_read_16(&instance->registers->usbsts);
    308                 const uint16_t intr = pio_read_16(&instance->registers->usbintr);
    309                 usb_log_debug("Command: %X Status: %X Interrupts: %x\n",
    310                     cmd, sts, intr);
    311 
    312                 uintptr_t frame_list = pio_read_32(&instance->registers->flbaseadd);
     354                const uint16_t intr =
     355                    pio_read_16(&instance->registers->usbintr);
     356
     357                if (((cmd & UHCI_CMD_RUN_STOP) != 1) || (sts != 0)) {
     358                        usb_log_debug2("Command: %X Status: %X Intr: %x\n",
     359                            cmd, sts, intr);
     360                }
     361
     362                uintptr_t frame_list =
     363                    pio_read_32(&instance->registers->flbaseadd) & ~0xfff;
    313364                if (frame_list != addr_to_phys(instance->frame_list)) {
    314365                        usb_log_debug("Framelist address: %p vs. %p.\n",
    315                                 frame_list, addr_to_phys(instance->frame_list));
    316                 }
     366                            frame_list, addr_to_phys(instance->frame_list));
     367                }
     368
    317369                int frnum = pio_read_16(&instance->registers->frnum) & 0x3ff;
    318370                usb_log_debug2("Framelist item: %d \n", frnum );
    319371
    320                 queue_head_t* qh = instance->transfers_interrupt.queue_head;
    321 
    322                 if ((instance->frame_list[frnum] & (~0xf)) != (uintptr_t)addr_to_phys(qh)) {
     372                uintptr_t expected_pa = instance->frame_list[frnum] & (~0xf);
     373                uintptr_t real_pa = addr_to_phys(QH(interrupt));
     374                if (expected_pa != real_pa) {
    323375                        usb_log_debug("Interrupt QH: %p vs. %p.\n",
    324                                 instance->frame_list[frnum] & (~0xf), addr_to_phys(qh));
    325                 }
    326 
    327                 if ((qh->next_queue & (~0xf))
    328                   != (uintptr_t)addr_to_phys(instance->transfers_control_slow.queue_head)) {
    329                         usb_log_debug("Control Slow QH: %p vs. %p.\n", qh->next_queue & (~0xf),
    330                                 addr_to_phys(instance->transfers_control_slow.queue_head));
    331                 }
    332                 qh = instance->transfers_control_slow.queue_head;
    333 
    334                 if ((qh->next_queue & (~0xf))
    335                   != (uintptr_t)addr_to_phys(instance->transfers_control_full.queue_head)) {
    336                         usb_log_debug("Control Full QH: %p vs. %p.\n", qh->next_queue & (~0xf),
    337                                 addr_to_phys(instance->transfers_control_full.queue_head));\
    338                 }
    339                 qh = instance->transfers_control_full.queue_head;
    340 
    341                 if ((qh->next_queue & (~0xf))
    342                   != (uintptr_t)addr_to_phys(instance->transfers_bulk_full.queue_head)) {
    343                         usb_log_debug("Bulk QH: %p vs. %p.\n", qh->next_queue & (~0xf),
    344                                 addr_to_phys(instance->transfers_bulk_full.queue_head));
    345                 }
    346 /*
    347         uint16_t cmd = pio_read_16(&instance->registers->usbcmd);
    348         cmd |= UHCI_CMD_RUN_STOP;
    349         pio_write_16(&instance->registers->usbcmd, cmd);
    350 */
     376                            expected_pa, real_pa);
     377                }
     378
     379                expected_pa = QH(interrupt)->next_queue & (~0xf);
     380                real_pa = addr_to_phys(QH(control_slow));
     381                if (expected_pa != real_pa) {
     382                        usb_log_debug("Control Slow QH: %p vs. %p.\n",
     383                            expected_pa, real_pa);
     384                }
     385
     386                expected_pa = QH(control_slow)->next_queue & (~0xf);
     387                real_pa = addr_to_phys(QH(control_full));
     388                if (expected_pa != real_pa) {
     389                        usb_log_debug("Control Full QH: %p vs. %p.\n",
     390                            expected_pa, real_pa);
     391                }
     392
     393                expected_pa = QH(control_full)->next_queue & (~0xf);
     394                real_pa = addr_to_phys(QH(bulk_full));
     395                if (expected_pa != real_pa ) {
     396                        usb_log_debug("Bulk QH: %p vs. %p.\n",
     397                            expected_pa, real_pa);
     398                }
    351399                async_usleep(UHCI_DEBUGER_TIMEOUT);
    352400        }
    353401        return 0;
     402#undef QH
    354403}
    355404/*----------------------------------------------------------------------------*/
    356405bool allowed_usb_packet(
    357         bool low_speed, usb_transfer_type_t transfer, size_t size)
     406    bool low_speed, usb_transfer_type_t transfer, size_t size)
    358407{
    359408        /* see USB specification chapter 5.5-5.8 for magic numbers used here */
    360         switch(transfer) {
    361                 case USB_TRANSFER_ISOCHRONOUS:
    362                         return (!low_speed && size < 1024);
    363                 case USB_TRANSFER_INTERRUPT:
    364                         return size <= (low_speed ? 8 : 64);
    365                 case USB_TRANSFER_CONTROL: /* device specifies its own max size */
    366                         return (size <= (low_speed ? 8 : 64));
    367                 case USB_TRANSFER_BULK: /* device specifies its own max size */
    368                         return (!low_speed && size <= 64);
     409        switch(transfer)
     410        {
     411        case USB_TRANSFER_ISOCHRONOUS:
     412                return (!low_speed && size < 1024);
     413        case USB_TRANSFER_INTERRUPT:
     414                return size <= (low_speed ? 8 : 64);
     415        case USB_TRANSFER_CONTROL: /* device specifies its own max size */
     416                return (size <= (low_speed ? 8 : 64));
     417        case USB_TRANSFER_BULK: /* device specifies its own max size */
     418                return (!low_speed && size <= 64);
    369419        }
    370420        return false;
  • uspace/drv/uhci-hcd/uhci.h

    rdff940f8 r8c877b2  
    4141#include <ddi.h>
    4242
    43 #include <usb/addrkeep.h>
    4443#include <usbhc_iface.h>
    4544
     45#include "batch.h"
    4646#include "transfer_list.h"
    47 #include "batch.h"
     47#include "utils/device_keeper.h"
    4848
    4949typedef struct uhci_regs {
     
    8282
    8383typedef struct uhci {
    84         usb_address_keeping_t address_manager;
     84        device_keeper_t device_manager;
     85
    8586        volatile regs_t *registers;
    8687
  • uspace/drv/uhci-hcd/uhci_struct/transfer_descriptor.c

    rdff940f8 r8c877b2  
    3939
    4040void transfer_descriptor_init(transfer_descriptor_t *instance,
    41     int error_count, size_t size, bool toggle, bool isochronous,
     41    int error_count, size_t size, bool toggle, bool isochronous, bool low_speed,
    4242    usb_target_t target, int pid, void *buffer, transfer_descriptor_t *next)
    4343{
     
    5050        instance->status = 0
    5151          | ((error_count & TD_STATUS_ERROR_COUNT_MASK) << TD_STATUS_ERROR_COUNT_POS)
     52                | (low_speed ? TD_STATUS_LOW_SPEED_FLAG : 0)
    5253          | TD_STATUS_ERROR_ACTIVE;
    5354
     
    6667        }
    6768
    68         usb_log_info("Created TD: %X:%X:%X:%X(%p).\n",
     69        usb_log_debug2("Created TD: %X:%X:%X:%X(%p).\n",
    6970                instance->next, instance->status, instance->device,
    7071          instance->buffer_ptr, buffer);
    71 #if 0
    72         if (size) {
    73                 unsigned char * buff = buffer;
    74                 uhci_print_verbose("TD Buffer dump(%p-%dB): ", buffer, size);
    75                 unsigned i = 0;
    76                 /* TODO: Verbose? */
    77                 for (; i < size; ++i) {
    78                         printf((i & 1) ? "%x " : "%x", buff[i]);
    79                 }
    80                 printf("\n");
    81         }
    82 #endif
    8372}
    8473/*----------------------------------------------------------------------------*/
     
    8877
    8978        if ((instance->status & TD_STATUS_ERROR_STALLED) != 0)
    90                 return EIO;
     79                return ESTALL;
    9180
    9281        if ((instance->status & TD_STATUS_ERROR_CRC) != 0)
    93                 return EAGAIN;
     82                return EBADCHECKSUM;
    9483
    9584        if ((instance->status & TD_STATUS_ERROR_BUFFER) != 0)
  • uspace/drv/uhci-hcd/uhci_struct/transfer_descriptor.h

    rdff940f8 r8c877b2  
    9292
    9393void transfer_descriptor_init(transfer_descriptor_t *instance,
    94     int error_count, size_t size, bool toggle, bool isochronous,
     94    int error_count, size_t size, bool toggle, bool isochronous, bool low_speed,
    9595    usb_target_t target, int pid, void *buffer, transfer_descriptor_t * next);
    9696
  • uspace/drv/uhci-rhd/main.c

    rdff940f8 r8c877b2  
    3333 */
    3434#include <ddf/driver.h>
     35#include <devman.h>
     36#include <device/hw_res.h>
    3537#include <usb_iface.h>
    3638#include <usb/ddfiface.h>
     
    4345
    4446#define NAME "uhci-rhd"
     47static int hc_get_my_registers(ddf_dev_t *dev,
     48    uintptr_t *io_reg_address, size_t *io_reg_size);
    4549
    4650static int usb_iface_get_hc_handle(ddf_fun_t *fun, devman_handle_t *handle)
     
    8084        }
    8185
    82         /* TODO: get register values from hc */
    83         int ret = uhci_root_hub_init(rh, (void*)0xc030, 4, device);
     86        uintptr_t io_regs = 0;
     87        size_t io_size = 0;
     88
     89        int ret = hc_get_my_registers(device, &io_regs, &io_size);
     90        assert(ret == EOK);
     91
     92        /* TODO: verify values from hc */
     93        usb_log_info("I/O regs at 0x%X (size %zu).\n", io_regs, io_size);
     94        ret = uhci_root_hub_init(rh, (void*)io_regs, io_size, device);
    8495        if (ret != EOK) {
    8596                usb_log_error("Failed(%d) to initialize driver instance.\n", ret);
     
    102113        .driver_ops = &uhci_rh_driver_ops
    103114};
    104 
     115/*----------------------------------------------------------------------------*/
    105116int main(int argc, char *argv[])
    106117{
    107         usb_log_enable(USB_LOG_LEVEL_INFO, NAME);
     118        usb_log_enable(USB_LOG_LEVEL_DEBUG, NAME);
    108119        return ddf_driver_main(&uhci_rh_driver);
     120}
     121/*----------------------------------------------------------------------------*/
     122int hc_get_my_registers(ddf_dev_t *dev,
     123    uintptr_t *io_reg_address, size_t *io_reg_size)
     124{
     125        assert(dev != NULL);
     126
     127        int parent_phone = devman_parent_device_connect(dev->handle,
     128            IPC_FLAG_BLOCKING);
     129        if (parent_phone < 0) {
     130                return parent_phone;
     131        }
     132
     133        int rc;
     134
     135        hw_resource_list_t hw_resources;
     136        rc = hw_res_get_resource_list(parent_phone, &hw_resources);
     137        if (rc != EOK) {
     138                goto leave;
     139        }
     140
     141        uintptr_t io_address = 0;
     142        size_t io_size = 0;
     143        bool io_found = false;
     144
     145        size_t i;
     146        for (i = 0; i < hw_resources.count; i++) {
     147                hw_resource_t *res = &hw_resources.resources[i];
     148                switch (res->type) {
     149                        case IO_RANGE:
     150                                io_address = (uintptr_t)
     151                                    res->res.io_range.address;
     152                                io_size = res->res.io_range.size;
     153                                io_found = true;
     154                                break;
     155                        default:
     156                                break;
     157                }
     158        }
     159
     160        if (!io_found) {
     161                rc = ENOENT;
     162                goto leave;
     163        }
     164
     165        if (io_reg_address != NULL) {
     166                *io_reg_address = io_address;
     167        }
     168        if (io_reg_size != NULL) {
     169                *io_reg_size = io_size;
     170        }
     171        rc = EOK;
     172leave:
     173        async_hangup(parent_phone);
     174
     175        return rc;
    109176}
    110177/**
  • uspace/drv/uhci-rhd/port.c

    rdff940f8 r8c877b2  
    3434#include <errno.h>
    3535#include <str_error.h>
     36#include <fibril_synch.h>
    3637
    3738#include <usb/usb.h>    /* usb_address_t */
     
    4546#include "port_status.h"
    4647
    47 static int uhci_port_new_device(uhci_port_t *port);
     48static int uhci_port_new_device(uhci_port_t *port, uint16_t status);
    4849static int uhci_port_remove_device(uhci_port_t *port);
    4950static int uhci_port_set_enabled(uhci_port_t *port, bool enabled);
    5051static int uhci_port_check(void *port);
     52static int new_device_enable_port(int portno, void *arg);
    5153
    5254int uhci_port_init(
    5355  uhci_port_t *port, port_status_t *address, unsigned number,
    54   unsigned usec, ddf_dev_t *rh, int parent_phone)
     56  unsigned usec, ddf_dev_t *rh)
    5557{
    5658        assert(port);
     
    6971        port->checker = fibril_create(uhci_port_check, port);
    7072        if (port->checker == 0) {
    71                 usb_log_error(": failed to launch root hub fibril.");
     73                usb_log_error("Port(%p - %d): failed to launch root hub fibril.",
     74                    port->address, port->number);
    7275                return ENOMEM;
    7376        }
    7477        fibril_add_ready(port->checker);
    75         usb_log_debug(
    76           "Added fibril for port %d: %p.\n", number, port->checker);
     78        usb_log_debug("Port(%p - %d): Added fibril. %x\n",
     79            port->address, port->number, port->checker);
    7780        return EOK;
    7881}
     
    9093        uhci_port_t *port_instance = port;
    9194        assert(port_instance);
     95//      port_status_write(port_instance->address, 0);
     96
     97        unsigned count = 0;
    9298
    9399        while (1) {
     100                async_usleep(port_instance->wait_period_usec);
     101
    94102                /* read register value */
    95103                port_status_t port_status =
     
    97105
    98106                /* debug print */
    99                 usb_log_debug("Port %d status at %p: 0x%04x.\n",
    100                   port_instance->number, port_instance->address, port_status);
    101                 print_port_status(port_status);
    102 
    103                 if (port_status & STATUS_CONNECTED_CHANGED) {
     107                static fibril_mutex_t dbg_mtx = FIBRIL_MUTEX_INITIALIZER(dbg_mtx);
     108                fibril_mutex_lock(&dbg_mtx);
     109                usb_log_debug2("Port(%p - %d): Status: %#04x. === %u\n",
     110                  port_instance->address, port_instance->number, port_status, count++);
     111//              print_port_status(port_status);
     112                fibril_mutex_unlock(&dbg_mtx);
     113
     114                if ((port_status & STATUS_CONNECTED_CHANGED) != 0) {
     115                        usb_log_debug("Port(%p - %d): Connected change detected: %x.\n",
     116                            port_instance->address, port_instance->number, port_status);
     117
     118
    104119                        int rc = usb_hc_connection_open(
    105120                            &port_instance->hc_connection);
    106121                        if (rc != EOK) {
    107                                 usb_log_error("Failed to connect to HC.");
    108                                 goto next;
    109                         }
    110 
    111                         if (port_status & STATUS_CONNECTED) {
     122                                usb_log_error("Port(%p - %d): Failed to connect to HC.",
     123                                    port_instance->address, port_instance->number);
     124                                continue;
     125                        }
     126
     127                        /* remove any old device */
     128                        if (port_instance->attached_device) {
     129                                usb_log_debug("Port(%p - %d): Removing device.\n",
     130                                    port_instance->address, port_instance->number);
     131                                uhci_port_remove_device(port_instance);
     132                        }
     133
     134                        if ((port_status & STATUS_CONNECTED) != 0) {
    112135                                /* new device */
    113                                 uhci_port_new_device(port_instance);
     136                                uhci_port_new_device(port_instance, port_status);
    114137                        } else {
    115                                 uhci_port_remove_device(port_instance);
     138                                /* ack changes by writing one to WC bits */
     139                                port_status_write(port_instance->address, port_status);
     140                                usb_log_debug("Port(%p - %d): Change status ACK.\n",
     141                                                port_instance->address, port_instance->number);
    116142                        }
    117143
     
    119145                            &port_instance->hc_connection);
    120146                        if (rc != EOK) {
    121                                 usb_log_error("Failed to disconnect from HC.");
    122                                 goto next;
     147                                usb_log_error("Port(%p - %d): Failed to disconnect from HC.",
     148                                    port_instance->address, port_instance->number);
    123149                        }
    124150                }
    125         next:
    126                 async_usleep(port_instance->wait_period_usec);
    127151        }
    128152        return EOK;
     
    139163        uhci_port_t *port = (uhci_port_t *) arg;
    140164
    141         usb_log_debug("new_device_enable_port(%d)\n", port->number);
     165        usb_log_debug2("Port(%p - %d): new_device_enable_port.\n",
     166            port->address, port->number);
    142167
    143168        /*
     
    147172        async_usleep(100000);
    148173
    149         /* Enable the port. */
    150         uhci_port_set_enabled(port, true);
    151174
    152175        /* The hub maintains the reset signal to that port for 10 ms
     
    154177         */
    155178        {
    156                 usb_log_debug("Reset Signal start on port %d.\n",
    157                     port->number);
     179                usb_log_debug("Port(%p - %d): Reset Signal start.\n",
     180                    port->address, port->number);
    158181                port_status_t port_status =
    159182                        port_status_read(port->address);
     
    165188                port_status &= ~STATUS_IN_RESET;
    166189                port_status_write(port->address, port_status);
    167                 usb_log_debug("Reset Signal stop on port %d.\n",
    168                     port->number);
    169         }
    170 
    171         return EOK;
    172 }
    173 
    174 /*----------------------------------------------------------------------------*/
    175 static int uhci_port_new_device(uhci_port_t *port)
     190                usb_log_debug("Port(%p - %d): Reset Signal stop.\n",
     191                    port->address, port->number);
     192        }
     193
     194        /* Enable the port. */
     195        uhci_port_set_enabled(port, true);
     196
     197        return EOK;
     198}
     199
     200/*----------------------------------------------------------------------------*/
     201static int uhci_port_new_device(uhci_port_t *port, uint16_t status)
    176202{
    177203        assert(port);
    178204        assert(usb_hc_connection_is_opened(&port->hc_connection));
    179205
    180         usb_log_info("Detected new device on port %u.\n", port->number);
     206        usb_log_info("Port(%p-%d): Detected new device.\n",
     207            port->address, port->number);
    181208
    182209        usb_address_t dev_addr;
    183210        int rc = usb_hc_new_device_wrapper(port->rh, &port->hc_connection,
    184             USB_SPEED_FULL,
     211            ((status & STATUS_LOW_SPEED) != 0) ? USB_SPEED_LOW : USB_SPEED_FULL,
    185212            new_device_enable_port, port->number, port,
    186213            &dev_addr, &port->attached_device, NULL, NULL, NULL);
     214
    187215        if (rc != EOK) {
    188                 usb_log_error("Failed adding new device on port %u: %s.\n",
    189                     port->number, str_error(rc));
     216                usb_log_error("Port(%p-%d): Failed(%d) adding new device: %s.\n",
     217                    port->address, port->number, rc, str_error(rc));
    190218                uhci_port_set_enabled(port, false);
    191219                return rc;
    192220        }
    193221
    194         usb_log_info("New device on port %u has address %d (handle %zu).\n",
    195             port->number, dev_addr, port->attached_device);
     222        usb_log_info("Port(%p-%d): New device has address %d (handle %zu).\n",
     223            port->address, port->number, dev_addr, port->attached_device);
    196224
    197225        return EOK;
     
    201229static int uhci_port_remove_device(uhci_port_t *port)
    202230{
    203         usb_log_error("Don't know how to remove device %#x.\n",
    204                 (unsigned int)port->attached_device);
     231        usb_log_error("Port(%p-%d): Don't know how to remove device %#x.\n",
     232                port->address, port->number, (unsigned int)port->attached_device);
    205233//      uhci_port_set_enabled(port, false);
    206234        return EOK;
     
    223251        port_status_write(port->address, port_status);
    224252
    225         usb_log_info("%s port %d.\n",
    226           enabled ? "Enabled" : "Disabled", port->number);
     253        usb_log_info("Port(%p-%d): %sabled port.\n",
     254                port->address, port->number, enabled ? "En" : "Dis");
    227255        return EOK;
    228256}
  • uspace/drv/uhci-rhd/port.h

    rdff940f8 r8c877b2  
    5555int uhci_port_init(
    5656  uhci_port_t *port, port_status_t *address, unsigned number,
    57   unsigned usec, ddf_dev_t *rh, int parent_phone);
     57  unsigned usec, ddf_dev_t *rh);
    5858
    5959void uhci_port_fini(uhci_port_t *port);
  • uspace/drv/uhci-rhd/port_status.c

    rdff940f8 r8c877b2  
    4141struct flag_name
    4242{
    43         unsigned flag;
     43        uint16_t flag;
    4444        const char *name;
    4545};
     
    6565        for (;i < sizeof(flags)/sizeof(struct flag_name); ++i) {
    6666                usb_log_debug2("\t%s status: %s.\n", flags[i].name,
    67                   value & flags[i].flag ? "YES" : "NO");
     67                  ((value & flags[i].flag) != 0) ? "YES" : "NO");
    6868        }
    6969}
  • uspace/drv/uhci-rhd/port_status.h

    rdff940f8 r8c877b2  
    4141typedef uint16_t port_status_t;
    4242
    43 enum {
    44         STATUS_CONNECTED         = 1 << 0,
    45         STATUS_CONNECTED_CHANGED = 1 << 1,
    46         STATUS_ENABLED           = 1 << 2,
    47         STATUS_ENABLED_CHANGED   = 1 << 3,
    48         STATUS_LINE_D_PLUS       = 1 << 4,
    49         STATUS_LINE_D_MINUS      = 1 << 5,
    50         STATUS_RESUME            = 1 << 6,
    51         STATUS_ALWAYS_ONE        = 1 << 7,
     43#define STATUS_CONNECTED         (1 << 0)
     44#define STATUS_CONNECTED_CHANGED (1 << 1)
     45#define STATUS_ENABLED           (1 << 2)
     46#define STATUS_ENABLED_CHANGED   (1 << 3)
     47#define STATUS_LINE_D_PLUS       (1 << 4)
     48#define STATUS_LINE_D_MINUS      (1 << 5)
     49#define STATUS_RESUME            (1 << 6)
     50#define STATUS_ALWAYS_ONE        (1 << 7)
    5251
    53         STATUS_LOW_SPEED = 1 <<  8,
    54         STATUS_IN_RESET  = 1 <<  9,
    55         STATUS_SUSPEND   = 1 << 12,
    56 };
     52#define STATUS_LOW_SPEED (1 <<  8)
     53#define STATUS_IN_RESET  (1 <<  9)
     54#define STATUS_SUSPEND   (1 << 12)
    5755
    5856static inline port_status_t port_status_read(port_status_t * address)
  • uspace/drv/uhci-rhd/root_hub.c

    rdff940f8 r8c877b2  
    4040#include "root_hub.h"
    4141
    42 
    4342int uhci_root_hub_init(
    4443  uhci_root_hub_t *instance, void *addr, size_t size, ddf_dev_t *rh)
     
    4746        assert(rh);
    4847        int ret;
    49         ret = usb_hc_find(rh->handle, &instance->hc_handle);
    50         usb_log_info("rh found(%d) hc handle: %d.\n", ret, instance->hc_handle);
    51         if (ret != EOK) {
    52                 return ret;
    53         }
    5448
    5549        /* allow access to root hub registers */
    5650        assert(sizeof(port_status_t) * UHCI_ROOT_HUB_PORT_COUNT == size);
    5751        port_status_t *regs;
    58         ret = pio_enable(
    59           addr, sizeof(port_status_t) * UHCI_ROOT_HUB_PORT_COUNT, (void**)&regs);
     52        ret = pio_enable(addr, size, (void**)&regs);
    6053
    6154        if (ret < 0) {
     
    6760        unsigned i = 0;
    6861        for (; i < UHCI_ROOT_HUB_PORT_COUNT; ++i) {
    69                 /* connect to the parent device (HC) */
    70                 int parent_phone = devman_device_connect(instance->hc_handle, 0);
    71                 //usb_drv_hc_connect(rh, instance->hc_handle, 0);
    72                 if (parent_phone < 0) {
    73                         usb_log_error("Failed to connect to the HC device port %d.\n", i);
    74                         return parent_phone;
    75                 }
    7662                /* mind pointer arithmetics */
    77                 int ret = uhci_port_init(
    78                   &instance->ports[i], regs + i, i, ROOT_HUB_WAIT_USEC, rh, parent_phone);
     63                ret = uhci_port_init(
     64                  &instance->ports[i], regs + i, i, ROOT_HUB_WAIT_USEC, rh);
    7965                if (ret != EOK) {
    8066                        unsigned j = 0;
  • uspace/drv/uhci-rhd/root_hub.h

    rdff940f8 r8c877b2  
    4141
    4242#define UHCI_ROOT_HUB_PORT_COUNT 2
    43 #define UHCI_ROOT_HUB_PORT_REGISTERS_OFFSET 0x10
    44 #define ROOT_HUB_WAIT_USEC 10000000 /* 10 seconds */
     43#define ROOT_HUB_WAIT_USEC 5000000 /* 5 seconds */
    4544
    4645typedef struct root_hub {
  • uspace/drv/usbhid/Makefile

    rdff940f8 r8c877b2  
    3939SOURCES = \
    4040        main.c \
    41         descparser.c \
    42         descdump.c \
    4341        conv.c \
     42        hidreq.c \
     43        kbddev.c \
     44        hiddev.c \
    4445        $(STOLEN_LAYOUT_SOURCES)
    4546
  • uspace/drv/usbhid/conv.c

    rdff940f8 r8c877b2  
    3636#include <io/keycode.h>
    3737#include <stdint.h>
     38#include <stdio.h>
     39#include <usb/debug.h>
    3840#include "conv.h"
    3941
     
    141143        //[0xe7] = KC_R // TODO: right GUI
    142144       
     145        [0x53] = KC_NUM_LOCK,
     146        [0x54] = KC_NSLASH,
     147        [0x55] = KC_NTIMES,
     148        [0x56] = KC_NMINUS,
     149        [0x57] = KC_NPLUS,
     150        [0x58] = KC_NENTER,
     151        [0x59] = KC_N1,
     152        [0x5a] = KC_N2,
     153        [0x5b] = KC_N3,
     154        [0x5c] = KC_N4,
     155        [0x5d] = KC_N5,
     156        [0x5e] = KC_N6,
     157        [0x5f] = KC_N7,
     158        [0x60] = KC_N8,
     159        [0x61] = KC_N9,
     160        [0x62] = KC_N0,
     161        [0x63] = KC_NPERIOD
     162       
    143163};
    144164
    145 unsigned int usbkbd_parse_scancode(int scancode)
     165unsigned int usbhid_parse_scancode(int scancode)
    146166{
    147 //      console_ev_type_t type;
    148167        unsigned int key;
    149168        int *map = scanmap_simple;
    150169        size_t map_length = sizeof(scanmap_simple) / sizeof(int);
    151 
    152         /*
    153          * ACK/NAK are returned as response to us sending a command.
    154          * We are not interested in them.
    155          */
    156 //      if (scancode == SC_ACK || scancode == SC_NAK)
    157 //              return;
    158 
    159 //      if (scancode == 0xe0) {
    160 //              ds = ds_e;
    161 //              return;
    162 //      }
    163 
    164 //      switch (ds) {
    165 //      case ds_s:
    166 //              map = scanmap_simple;
    167 //              map_length = sizeof(scanmap_simple) / sizeof(int);
    168 //              break;
    169 //      case ds_e:
    170 //              map = scanmap_e0;
    171 //              map_length = sizeof(scanmap_e0) / sizeof(int);
    172 //              break;
    173 //      default:
    174 //              map = NULL;
    175 //              map_length = 0;
    176 //      }
    177 
    178 //      ds = ds_s;
    179 
    180 //      if (scancode & 0x80) {
    181 //              scancode &= ~0x80;
    182 //              type = KEY_RELEASE;
    183 //      } else {
    184 //              type = KEY_PRESS;
    185 //      }
    186170
    187171        if ((scancode < 0) || ((size_t) scancode >= map_length))
     
    189173
    190174        key = map[scancode];
    191 //      if (key != 0)
    192 //              kbd_push_ev(type, key);
     175       
    193176        return key;
    194177}
  • uspace/drv/usbhid/conv.h

    rdff940f8 r8c877b2  
    3737#define USBHID_CONV_H_
    3838
    39 unsigned int usbkbd_parse_scancode(int scancode);
     39unsigned int usbhid_parse_scancode(int scancode);
    4040
    41 #endif
     41#endif /* USBHID_CONV_H_ */
    4242
    4343/**
  • uspace/drv/usbhid/descdump.h

    rdff940f8 r8c877b2  
    3737#define USBHID_DESCDUMP_H_
    3838
    39 #include "hid.h"
     39#include <usb/descriptor.h>
     40#include <usb/classes/hid.h>
    4041
    4142void dump_standard_configuration_descriptor(
  • uspace/drv/usbhid/hiddev.h

    rdff940f8 r8c877b2  
    3131 */
    3232/** @file
    33  * Common definitions.
     33 * Generic USB HID device structure and API.
    3434 */
    3535
    36 #ifndef USBHID_HID_H_
    37 #define USBHID_HID_H_
     36#ifndef USBHID_HIDDEV_H_
     37#define USBHID_HIDDEV_H_
     38
     39#include <stdint.h>
     40
     41#include <ddf/driver.h>
    3842
    3943#include <usb/classes/hid.h>
    40 #include <ddf/driver.h>
    4144#include <usb/pipes.h>
     45#include <usb/classes/hidparser.h>
     46
     47/*----------------------------------------------------------------------------*/
    4248
    4349/**
    44  *
    45  */
    46 typedef struct {
    47         usb_standard_interface_descriptor_t iface_desc;
    48         usb_standard_endpoint_descriptor_t *endpoints;
    49         usb_standard_hid_descriptor_t hid_desc;
    50         uint8_t *report_desc;
    51         //usb_standard_hid_class_descriptor_info_t *class_desc_info;
    52         //uint8_t **class_descs;
    53 } usb_hid_iface_t;
    54 
    55 /**
    56  *
    57  */
    58 typedef struct {
    59         usb_standard_configuration_descriptor_t config_descriptor;
    60         usb_hid_iface_t *interfaces;
    61 } usb_hid_configuration_t;
    62 
    63 /**
    64  * @brief USB/HID keyboard device type.
    65  *
    66  * Quite dummy right now.
     50 * @brief USB/HID device type.
    6751 */
    6852typedef struct {
    6953        ddf_dev_t *device;
    70         usb_hid_configuration_t *conf;
    71         usb_hid_report_parser_t *parser;
    7254
    7355        usb_device_connection_t wire;
    7456        usb_endpoint_pipe_t ctrl_pipe;
    7557        usb_endpoint_pipe_t poll_pipe;
    76 } usb_hid_dev_kbd_t;
     58       
     59        uint16_t iface;
     60       
     61        uint8_t *report_desc;
     62        usb_hid_report_parser_t *parser;
     63       
     64        int initialized;
     65} usbhid_dev_t;
    7766
    78 // TODO: more configurations!
     67/*----------------------------------------------------------------------------*/
    7968
    80 #endif
     69usbhid_dev_t *usbhid_dev_new(void);
     70
     71void usbhid_dev_free(usbhid_dev_t **hid_dev);
     72
     73int usbhid_dev_init(usbhid_dev_t *hid_dev, ddf_dev_t *dev,
     74    usb_endpoint_description_t *poll_ep_desc);
     75
     76/*----------------------------------------------------------------------------*/
     77
     78#endif /* USBHID_HIDDEV_H_ */
     79
     80/**
     81 * @}
     82 */
  • uspace/drv/usbhid/main.c

    rdff940f8 r8c877b2  
    3737
    3838#include <ddf/driver.h>
    39 #include <ipc/driver.h>
    40 #include <ipc/kbd.h>
    41 #include <io/keycode.h>
    42 #include <io/console.h>
     39#include <usb/debug.h>
    4340#include <errno.h>
    44 #include <str_error.h>
    45 #include <fibril.h>
    46 #include <usb/debug.h>
    47 #include <usb/classes/classes.h>
    48 #include <usb/classes/hid.h>
    49 #include <usb/classes/hidparser.h>
    50 #include <usb/request.h>
    51 #include <usb/descriptor.h>
    52 #include <io/console.h>
    53 #include "hid.h"
    54 #include "descparser.h"
    55 #include "descdump.h"
    56 #include "conv.h"
    57 #include "layout.h"
    5841
    59 #define BUFFER_SIZE 8
     42#include "kbddev.h"
     43
     44/*----------------------------------------------------------------------------*/
     45
    6046#define NAME "usbhid"
    6147
    62 #define GUESSED_POLL_ENDPOINT 1
     48/*----------------------------------------------------------------------------*/
    6349
    64 /** Keyboard polling endpoint description for boot protocol class. */
    65 static usb_endpoint_description_t poll_endpoint_description = {
    66         .transfer_type = USB_TRANSFER_INTERRUPT,
    67         .direction = USB_DIRECTION_IN,
    68         .interface_class = USB_CLASS_HID,
    69         .interface_subclass = USB_HID_SUBCLASS_BOOT,
    70         .interface_protocol = USB_HID_PROTOCOL_KEYBOARD,
    71         .flags = 0
    72 };
    73 
    74 static void default_connection_handler(ddf_fun_t *, ipc_callid_t, ipc_call_t *);
    75 static ddf_dev_ops_t keyboard_ops = {
    76         .default_handler = default_connection_handler
    77 };
    78 
    79 static int console_callback_phone = -1;
    80 
    81 /** Default handler for IPC methods not handled by DDF.
    82  *
    83  * @param dev Device handling the call.
    84  * @param icallid Call id.
    85  * @param icall Call data.
    86  */
    87 void default_connection_handler(ddf_fun_t *fun,
    88     ipc_callid_t icallid, ipc_call_t *icall)
     50static int usbhid_add_device(ddf_dev_t *dev)
    8951{
    90         sysarg_t method = IPC_GET_IMETHOD(*icall);
    91 
    92         if (method == IPC_M_CONNECT_TO_ME) {
    93                 int callback = IPC_GET_ARG5(*icall);
    94 
    95                 if (console_callback_phone != -1) {
    96                         async_answer_0(icallid, ELIMIT);
    97                         return;
    98                 }
    99 
    100                 console_callback_phone = callback;
    101                 async_answer_0(icallid, EOK);
    102                 return;
    103         }
    104 
    105         async_answer_0(icallid, EINVAL);
    106 }
    107 
    108 #if 0
    109 static void send_key(int key, int type, wchar_t c) {
    110         async_msg_4(console_callback_phone, KBD_EVENT, type, key,
    111             KM_NUM_LOCK, c);
    112 }
    113 #endif
    114 
    115 /*
    116  * TODO: Move somewhere else
    117  */
    118 /*
    119 #define BYTES_PER_LINE 12
    120 
    121 static void dump_buffer(const char *msg, const uint8_t *buffer, size_t length)
    122 {
    123         printf("%s\n", msg);
     52        usb_log_debug("usbhid_add_device()\n");
    12453       
    125         size_t i;
    126         for (i = 0; i < length; i++) {
    127                 printf("  0x%02X", buffer[i]);
    128                 if (((i > 0) && (((i+1) % BYTES_PER_LINE) == 0))
    129                     || (i + 1 == length)) {
    130                         printf("\n");
    131                 }
    132         }
    133 }
    134 */
    135 /*
    136  * Copy-paste from srv/hid/kbd/generic/kbd.c
    137  */
    138 
    139 /** Currently active modifiers.
    140  *
    141  * TODO: put to device?
    142  */
    143 static unsigned mods = KM_NUM_LOCK;
    144 
    145 /** Currently pressed lock keys. We track these to tackle autorepeat. 
    146  *
    147  * TODO: put to device?
    148  */
    149 static unsigned lock_keys;
    150 
    151 #define NUM_LAYOUTS 3
    152 
    153 static layout_op_t *layout[NUM_LAYOUTS] = {
    154         &us_qwerty_op,
    155         &us_dvorak_op,
    156         &cz_op
    157 };
    158 
    159 static int active_layout = 0;
    160 
    161 static void kbd_push_ev(int type, unsigned int key)
    162 {
    163         console_event_t ev;
    164         unsigned mod_mask;
    165 
    166         // TODO: replace by our own parsing?? or are the key codes identical??
    167         switch (key) {
    168         case KC_LCTRL: mod_mask = KM_LCTRL; break;
    169         case KC_RCTRL: mod_mask = KM_RCTRL; break;
    170         case KC_LSHIFT: mod_mask = KM_LSHIFT; break;
    171         case KC_RSHIFT: mod_mask = KM_RSHIFT; break;
    172         case KC_LALT: mod_mask = KM_LALT; break;
    173         case KC_RALT: mod_mask = KM_RALT; break;
    174         default: mod_mask = 0; break;
    175         }
    176 
    177         if (mod_mask != 0) {
    178                 if (type == KEY_PRESS)
    179                         mods = mods | mod_mask;
    180                 else
    181                         mods = mods & ~mod_mask;
    182         }
    183 
    184         switch (key) {
    185         case KC_CAPS_LOCK: mod_mask = KM_CAPS_LOCK; break;
    186         case KC_NUM_LOCK: mod_mask = KM_NUM_LOCK; break;
    187         case KC_SCROLL_LOCK: mod_mask = KM_SCROLL_LOCK; break;
    188         default: mod_mask = 0; break;
    189         }
    190 
    191         if (mod_mask != 0) {
    192                 if (type == KEY_PRESS) {
    193                         /*
    194                          * Only change lock state on transition from released
    195                          * to pressed. This prevents autorepeat from messing
    196                          * up the lock state.
    197                          */
    198                         mods = mods ^ (mod_mask & ~lock_keys);
    199                         lock_keys = lock_keys | mod_mask;
    200 
    201                         /* Update keyboard lock indicator lights. */
    202                         // TODO
    203                         //kbd_ctl_set_ind(mods);
    204                 } else {
    205                         lock_keys = lock_keys & ~mod_mask;
    206                 }
    207         }
    208 /*
    209         printf("type: %d\n", type);
    210         printf("mods: 0x%x\n", mods);
    211         printf("keycode: %u\n", key);
    212 */
     54        int rc = usbhid_kbd_try_add_device(dev);
    21355       
    214         if (type == KEY_PRESS && (mods & KM_LCTRL) &&
    215                 key == KC_F1) {
    216                 active_layout = 0;
    217                 layout[active_layout]->reset();
    218                 return;
    219         }
    220 
    221         if (type == KEY_PRESS && (mods & KM_LCTRL) &&
    222                 key == KC_F2) {
    223                 active_layout = 1;
    224                 layout[active_layout]->reset();
    225                 return;
    226         }
    227 
    228         if (type == KEY_PRESS && (mods & KM_LCTRL) &&
    229                 key == KC_F3) {
    230                 active_layout = 2;
    231                 layout[active_layout]->reset();
    232                 return;
     56        if (rc != EOK) {
     57                usb_log_info("Device is not a supported keyboard.\n");
     58                usb_log_error("Failed to add HID device.\n");
     59                return EREFUSED;
    23360        }
    23461       
    235         ev.type = type;
    236         ev.key = key;
    237         ev.mods = mods;
    238 
    239         ev.c = layout[active_layout]->parse_ev(&ev);
    240 
    241         printf("Sending key %d to the console\n", ev.key);
    242         assert(console_callback_phone != -1);
    243         async_msg_4(console_callback_phone, KBD_EVENT, ev.type, ev.key, ev.mods, ev.c);
    244 }
    245 /*
    246  * End of copy-paste
    247  */
    248 
    249         /*
    250          * TODO:
    251          * 1) key press / key release - how does the keyboard notify about release?
    252          * 2) layouts (use the already defined), not important now
    253          * 3)
    254          */
    255 
    256 /*
    257  * Callbacks for parser
    258  */
    259 static void usbkbd_process_keycodes(const uint8_t *key_codes, size_t count,
    260     uint8_t modifiers, void *arg)
    261 {
    262         printf("Got keys: ");
    263         unsigned i;
    264         for (i = 0; i < count; ++i) {
    265                 printf("%d ", key_codes[i]);
    266         }
    267         printf("\n");
    268 
    269         for (i = 0; i < count; ++i) {
    270                 // TODO: Key press / release
    271 
    272                 // TODO: NOT WORKING
    273                 unsigned int key = usbkbd_parse_scancode(key_codes[i]);
    274 
    275                 if (key == 0) {
    276                         continue;
    277                 }
    278                 kbd_push_ev(KEY_PRESS, key);
    279         }
    280         printf("\n");
    281 }
    282 
    283 /*
    284  * Kbd functions
    285  */
    286 static int usbkbd_get_report_descriptor(usb_hid_dev_kbd_t *kbd_dev)
    287 {
    288         // iterate over all configurations and interfaces
    289         // TODO: more configurations!!
    290         unsigned i;
    291         for (i = 0; i < kbd_dev->conf->config_descriptor.interface_count; ++i) {
    292                 // TODO: endianness
    293                 uint16_t length =
    294                     kbd_dev->conf->interfaces[i].hid_desc.report_desc_info.length;
    295                 size_t actual_size = 0;
    296 
    297                 // allocate space for the report descriptor
    298                 kbd_dev->conf->interfaces[i].report_desc = (uint8_t *)malloc(length);
    299                
    300                 // get the descriptor from the device
    301                 int rc = usb_request_get_descriptor(&kbd_dev->ctrl_pipe,
    302                     USB_REQUEST_TYPE_CLASS, USB_DESCTYPE_HID_REPORT,
    303                     i, 0,
    304                     kbd_dev->conf->interfaces[i].report_desc, length,
    305                     &actual_size);
    306 
    307                 if (rc != EOK) {
    308                         return rc;
    309                 }
    310 
    311                 assert(actual_size == length);
    312 
    313                 //dump_hid_class_descriptor(0, USB_DESCTYPE_HID_REPORT,
    314                 //    kbd_dev->conf->interfaces[i].report_desc, length);
    315         }
    316 
    317         return EOK;
    318 }
    319 static int usbkbd_process_descriptors(usb_hid_dev_kbd_t *kbd_dev)
    320 {
    321         // get the first configuration descriptor (TODO: parse also other!)
    322         usb_standard_configuration_descriptor_t config_desc;
    323        
    324         int rc;
    325         rc = usb_request_get_bare_configuration_descriptor(&kbd_dev->ctrl_pipe,
    326             0, &config_desc);
    327        
    328         if (rc != EOK) {
    329                 return rc;
    330         }
    331        
    332         // prepare space for all underlying descriptors
    333         uint8_t *descriptors = (uint8_t *)malloc(config_desc.total_length);
    334         if (descriptors == NULL) {
    335                 return ENOMEM;
    336         }
    337        
    338         size_t transferred = 0;
    339         // get full configuration descriptor
    340         rc = usb_request_get_full_configuration_descriptor(&kbd_dev->ctrl_pipe,
    341             0, descriptors,
    342             config_desc.total_length, &transferred);
    343        
    344         if (rc != EOK) {
    345                 return rc;
    346         }
    347         if (transferred != config_desc.total_length) {
    348                 return ELIMIT;
    349         }
    350        
    351         /*
    352          * Initialize the interrupt in endpoint.
    353          */
    354         usb_endpoint_mapping_t endpoint_mapping[1] = {
    355                 {
    356                         .pipe = &kbd_dev->poll_pipe,
    357                         .description = &poll_endpoint_description,
    358                         .interface_no =
    359                             usb_device_get_assigned_interface(kbd_dev->device)
    360                 }
    361         };
    362         rc = usb_endpoint_pipe_initialize_from_configuration(
    363             endpoint_mapping, 1,
    364             descriptors, config_desc.total_length,
    365             &kbd_dev->wire);
    366         if (rc != EOK) {
    367                 usb_log_error("Failed to initialize poll pipe: %s.\n",
    368                     str_error(rc));
    369                 return rc;
    370         }
    371         if (!endpoint_mapping[0].present) {
    372                 usb_log_warning("Not accepting device, " \
    373                     "not boot-protocol keyboard.\n");
    374                 return EREFUSED;
    375         }
    376 
    377 
    378 
    379 
    380         kbd_dev->conf = (usb_hid_configuration_t *)calloc(1,
    381             sizeof(usb_hid_configuration_t));
    382         if (kbd_dev->conf == NULL) {
    383                 free(descriptors);
    384                 return ENOMEM;
    385         }
    386        
    387         /*rc = usbkbd_parse_descriptors(descriptors, transferred, kbd_dev->conf);
    388         free(descriptors);
    389         if (rc != EOK) {
    390                 printf("Problem with parsing standard descriptors.\n");
    391                 return rc;
    392         }
    393 
    394         // get and report descriptors*/
    395         rc = usbkbd_get_report_descriptor(kbd_dev);
    396         if (rc != EOK) {
    397                 printf("Problem with parsing HID REPORT descriptor.\n");
    398                 return rc;
    399         }
    400        
    401         //usbkbd_print_config(kbd_dev->conf);
    402 
    403         /*
    404          * TODO:
    405          * 1) select one configuration (lets say the first)
    406          * 2) how many interfaces?? how to select one??
    407      *    ("The default setting for an interface is always alternate setting zero.")
    408          * 3) find endpoint which is IN and INTERRUPT (parse), save its number
    409      *    as the endpoint for polling
    410          */
    411 
    41262        return EOK;
    41363}
    41464
    415 static usb_hid_dev_kbd_t *usbkbd_init_device(ddf_dev_t *dev)
    416 {
    417         int rc;
    418 
    419         usb_hid_dev_kbd_t *kbd_dev = (usb_hid_dev_kbd_t *)calloc(1,
    420             sizeof(usb_hid_dev_kbd_t));
    421 
    422         if (kbd_dev == NULL) {
    423                 fprintf(stderr, NAME ": No memory!\n");
    424                 return NULL;
    425         }
    426 
    427         kbd_dev->device = dev;
    428 
    429         /*
    430          * Initialize the backing connection to the host controller.
    431          */
    432         rc = usb_device_connection_initialize_from_device(&kbd_dev->wire, dev);
    433         if (rc != EOK) {
    434                 printf("Problem initializing connection to device: %s.\n",
    435                     str_error(rc));
    436                 goto error_leave;
    437         }
    438 
    439         /*
    440          * Initialize device pipes.
    441          */
    442         rc = usb_endpoint_pipe_initialize_default_control(&kbd_dev->ctrl_pipe,
    443             &kbd_dev->wire);
    444         if (rc != EOK) {
    445                 printf("Failed to initialize default control pipe: %s.\n",
    446                     str_error(rc));
    447                 goto error_leave;
    448         }
    449 
    450         /*
    451          * will need all descriptors:
    452          * 1) choose one configuration from configuration descriptors
    453          *    (set it to the device)
    454          * 2) set endpoints from endpoint descriptors
    455          */
    456 
    457         // TODO: get descriptors, parse descriptors and save endpoints
    458         usb_endpoint_pipe_start_session(&kbd_dev->ctrl_pipe);
    459         //usb_request_set_configuration(&kbd_dev->ctrl_pipe, 1);
    460         rc = usbkbd_process_descriptors(kbd_dev);
    461         usb_endpoint_pipe_end_session(&kbd_dev->ctrl_pipe);
    462         if (rc != EOK) {
    463                 goto error_leave;
    464         }
    465 
    466         return kbd_dev;
    467 
    468 error_leave:
    469         free(kbd_dev);
    470         return NULL;
    471 }
    472 
    473 static void usbkbd_process_interrupt_in(usb_hid_dev_kbd_t *kbd_dev,
    474                                         uint8_t *buffer, size_t actual_size)
    475 {
    476         usb_hid_report_in_callbacks_t *callbacks =
    477             (usb_hid_report_in_callbacks_t *)malloc(
    478                 sizeof(usb_hid_report_in_callbacks_t));
    479         callbacks->keyboard = usbkbd_process_keycodes;
    480 
    481         //usb_hid_parse_report(kbd_dev->parser, buffer, actual_size, callbacks,
    482         //    NULL);
    483         printf("Calling usb_hid_boot_keyboard_input_report() with size %zu\n",
    484             actual_size);
    485         //dump_buffer("bufffer: ", buffer, actual_size);
    486         int rc = usb_hid_boot_keyboard_input_report(buffer, actual_size, callbacks,
    487             NULL);
    488         if (rc != EOK) {
    489                 printf("Error in usb_hid_boot_keyboard_input_report(): %d\n", rc);
    490         }
    491 }
    492 
    493 static void usbkbd_poll_keyboard(usb_hid_dev_kbd_t *kbd_dev)
    494 {
    495         int rc, sess_rc;
    496         uint8_t buffer[BUFFER_SIZE];
    497         size_t actual_size;
    498 
    499         printf("Polling keyboard...\n");
    500 
    501         while (true) {
    502                 async_usleep(1000 * 10);
    503 
    504                 sess_rc = usb_endpoint_pipe_start_session(&kbd_dev->poll_pipe);
    505                 if (sess_rc != EOK) {
    506                         printf("Failed to start a session: %s.\n",
    507                             str_error(sess_rc));
    508                         continue;
    509                 }
    510 
    511                 rc = usb_endpoint_pipe_read(&kbd_dev->poll_pipe, buffer,
    512                     BUFFER_SIZE, &actual_size);
    513                 sess_rc = usb_endpoint_pipe_end_session(&kbd_dev->poll_pipe);
    514 
    515                 if (rc != EOK) {
    516                         printf("Error polling the keyboard: %s.\n",
    517                             str_error(rc));
    518                         continue;
    519                 }
    520 
    521                 if (sess_rc != EOK) {
    522                         printf("Error closing session: %s.\n",
    523                             str_error(sess_rc));
    524                         continue;
    525                 }
    526 
    527                 /*
    528                  * If the keyboard answered with NAK, it returned no data.
    529                  * This implies that no change happened since last query.
    530                  */
    531                 if (actual_size == 0) {
    532                         printf("Keyboard returned NAK\n");
    533                         continue;
    534                 }
    535 
    536                 /*
    537                  * TODO: Process pressed keys.
    538                  */
    539                 printf("Calling usbkbd_process_interrupt_in()\n");
    540                 usbkbd_process_interrupt_in(kbd_dev, buffer, actual_size);
    541         }
    542 
    543         // not reached
    544         assert(0);
    545 }
    546 
    547 static int usbkbd_fibril_device(void *arg)
    548 {
    549         printf("!!! USB device fibril\n");
    550 
    551         if (arg == NULL) {
    552                 printf("No device!\n");
    553                 return -1;
    554         }
    555 
    556         ddf_dev_t *dev = (ddf_dev_t *)arg;
    557 
    558         // initialize device (get and process descriptors, get address, etc.)
    559         usb_hid_dev_kbd_t *kbd_dev = usbkbd_init_device(dev);
    560         if (kbd_dev == NULL) {
    561                 printf("Error while initializing device.\n");
    562                 return -1;
    563         }
    564 
    565         usbkbd_poll_keyboard(kbd_dev);
    566 
    567         return EOK;
    568 }
    569 
    570 static int usbkbd_add_device(ddf_dev_t *dev)
    571 {
    572         /* For now, fail immediately. */
    573         //return ENOTSUP;
    574 
    575         /*
    576          * When everything is okay, connect to "our" HC.
    577          *
    578          * Not supported yet, skip..
    579          */
    580 //      int phone = usb_drv_hc_connect_auto(dev, 0);
    581 //      if (phone < 0) {
    582 //              /*
    583 //               * Connecting to HC failed, roll-back and announce
    584 //               * failure.
    585 //               */
    586 //              return phone;
    587 //      }
    588 
    589 //      dev->parent_phone = phone;
    590 
    591         /*
    592          * Create default function.
    593          */
    594         // FIXME - check for errors
    595         ddf_fun_t *kbd_fun = ddf_fun_create(dev, fun_exposed, "keyboard");
    596         assert(kbd_fun != NULL);
    597         kbd_fun->ops = &keyboard_ops;
    598 
    599         int rc = ddf_fun_bind(kbd_fun);
    600         assert(rc == EOK);
    601         rc = ddf_fun_add_to_class(kbd_fun, "keyboard");
    602         assert(rc == EOK);
    603 
    604         /*
    605          * Create new fibril for handling this keyboard
    606          */
    607         fid_t fid = fibril_create(usbkbd_fibril_device, dev);
    608         if (fid == 0) {
    609                 printf("%s: failed to start fibril for HID device\n", NAME);
    610                 return ENOMEM;
    611         }
    612         fibril_add_ready(fid);
    613 
    614         //dev->ops = &keyboard_ops;
    615         (void)keyboard_ops;
    616 
    617         //add_device_to_class(dev, "keyboard");
    618 
    619         /*
    620          * Hurrah, device is initialized.
    621          */
    622         return EOK;
    623 }
     65/*----------------------------------------------------------------------------*/
    62466
    62567static driver_ops_t kbd_driver_ops = {
    626         .add_device = usbkbd_add_device,
     68        .add_device = usbhid_add_device,
    62769};
     70
     71/*----------------------------------------------------------------------------*/
    62872
    62973static driver_t kbd_driver = {
     
    63276};
    63377
     78/*----------------------------------------------------------------------------*/
     79
    63480int main(int argc, char *argv[])
    63581{
    636         usb_log_enable(USB_LOG_LEVEL_INFO, "usbhid");
     82        usb_log_enable(USB_LOG_LEVEL_INFO, NAME);
    63783        return ddf_driver_main(&kbd_driver);
    63884}
  • uspace/drv/usbhid/usbhid.ma

    rdff940f8 r8c877b2  
    1 10 usb&class=hid
    2 10 usb&class=HID
     1100 usb&interface&class=HID&subclass=0x01&protocol=0x01
    3210 usb&interface&class=HID
    4 10 usb&hid
  • uspace/drv/usbhub/usbhub.c

    rdff940f8 r8c877b2  
    149149        }
    150150
    151         //configuration descriptor
    152         /// \TODO check other configurations?
    153         usb_standard_configuration_descriptor_t config_descriptor;
    154         opResult = usb_request_get_bare_configuration_descriptor(
     151        /* Retrieve full configuration descriptor. */
     152        uint8_t *descriptors = NULL;
     153        size_t descriptors_size = 0;
     154        opResult = usb_request_get_full_configuration_descriptor_alloc(
    155155            &hub->endpoints.control, 0,
    156         &config_descriptor);
    157         if(opResult!=EOK){
    158                 dprintf(USB_LOG_LEVEL_ERROR, "could not get configuration descriptor, %d",opResult);
     156            (void **) &descriptors, &descriptors_size);
     157        if (opResult != EOK) {
     158                usb_log_error("Could not get configuration descriptor: %s.\n",
     159                    str_error(opResult));
    159160                return opResult;
    160161        }
    161         //set configuration
     162        usb_standard_configuration_descriptor_t *config_descriptor
     163            = (usb_standard_configuration_descriptor_t *) descriptors;
     164
     165        /* Set configuration. */
    162166        opResult = usb_request_set_configuration(&hub->endpoints.control,
    163                 config_descriptor.configuration_number);
    164 
    165         if (opResult != EOK) {
    166                 dprintf(USB_LOG_LEVEL_ERROR,
    167                                 "something went wrong when setting hub`s configuration, %d",
    168                                 opResult);
     167            config_descriptor->configuration_number);
     168
     169        if (opResult != EOK) {
     170                usb_log_error("Failed to set hub configuration: %s.\n",
     171                    str_error(opResult));
    169172                return opResult;
    170173        }
    171174        dprintf(USB_LOG_LEVEL_DEBUG, "\tused configuration %d",
    172                         config_descriptor.configuration_number);
    173 
    174         //full configuration descriptor
    175         size_t transferred = 0;
    176         uint8_t * descriptors = (uint8_t *)malloc(config_descriptor.total_length);
    177         if (descriptors == NULL) {
    178                 dprintf(USB_LOG_LEVEL_ERROR, "insufficient memory");
    179                 return ENOMEM;
    180         }
    181         opResult = usb_request_get_full_configuration_descriptor(&hub->endpoints.control,
    182             0, descriptors,
    183             config_descriptor.total_length, &transferred);
    184         if(opResult!=EOK){
    185                 free(descriptors);
    186                 dprintf(USB_LOG_LEVEL_ERROR,
    187                                 "could not get full configuration descriptor, %d",opResult);
    188                 return opResult;
    189         }
    190         if (transferred != config_descriptor.total_length) {
    191                 dprintf(USB_LOG_LEVEL_ERROR,
    192                                 "received incorrect full configuration descriptor");
    193                 return ELIMIT;
    194         }
     175                        config_descriptor->configuration_number);
    195176
    196177        usb_endpoint_mapping_t endpoint_mapping[1] = {
     
    204185        opResult = usb_endpoint_pipe_initialize_from_configuration(
    205186            endpoint_mapping, 1,
    206             descriptors, config_descriptor.total_length,
     187            descriptors, descriptors_size,
    207188            &hub->device_connection);
    208189        if (opResult != EOK) {
     
    253234        usb_endpoint_pipe_start_session(&result->endpoints.control);
    254235        opResult = usb_request_get_descriptor(&result->endpoints.control,
    255                         USB_REQUEST_TYPE_CLASS,
    256                         USB_DESCTYPE_HUB, 0, 0, serialized_descriptor,
     236                        USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_DEVICE,
     237                        USB_DESCTYPE_HUB,
     238                        0, 0, serialized_descriptor,
    257239                        USB_HUB_MAX_DESCRIPTOR_SIZE, &received_size);
    258240        usb_endpoint_pipe_end_session(&result->endpoints.control);
  • uspace/drv/usbmid/explore.c

    rdff940f8 r8c877b2  
    4242#include "usbmid.h"
    4343
    44 /** Allocate and retrieve full configuration descriptor.
    45  *
    46  * @param[in] dev USB device.
    47  * @param[in] config_index Configuration index.
    48  * @param[out] size Pointer where to store size of the allocated buffer.
    49  * @return Allocated full configuration descriptor.
    50  * @retval NULL Error occured.
    51  */
    52 static void *get_configuration_descriptor(usbmid_device_t *dev,
    53     size_t config_index, size_t *size)
    54 {
    55         usb_standard_configuration_descriptor_t config_descriptor;
    56         int rc = usb_request_get_bare_configuration_descriptor(&dev->ctrl_pipe,
    57             config_index, &config_descriptor);
    58         if (rc != EOK) {
    59                 usb_log_error("Failed getting configuration descriptor: %s.\n",
    60                     str_error(rc));
    61                 return NULL;
    62         }
    63 
    64         void *full_config_descriptor = malloc(config_descriptor.total_length);
    65         if (full_config_descriptor == NULL) {
    66                 usb_log_fatal("Out of memory (wanted: %zuB).\n",
    67                     (size_t) config_descriptor.total_length);
    68                 return NULL;
    69         }
    70 
    71         size_t full_config_descriptor_size;
    72         rc = usb_request_get_full_configuration_descriptor(&dev->ctrl_pipe,
    73             config_index,
    74             full_config_descriptor, config_descriptor.total_length,
    75             &full_config_descriptor_size);
    76         if (rc != EOK) {
    77                 usb_log_error("Failed getting configuration descriptor: %s.\n",
    78                     str_error(rc));
    79                 free(full_config_descriptor);
    80                 return NULL;
    81         }
    82 
    83         if (full_config_descriptor_size != config_descriptor.total_length) {
    84                 usb_log_error("Failed getting full configuration descriptor.\n");
    85                 free(full_config_descriptor);
    86                 return NULL;
    87         }
    88 
    89         if (size != NULL) {
    90                 *size = full_config_descriptor_size;
    91         }
    92 
    93         return full_config_descriptor;
    94 }
    95 
    9644/** Find starting indexes of all interface descriptors in a configuration.
    9745 *
     
    178126
    179127        size_t config_descriptor_size;
    180         uint8_t *config_descriptor_raw = get_configuration_descriptor(dev, 0,
    181             &config_descriptor_size);
    182         if (config_descriptor_raw == NULL) {
     128        uint8_t *config_descriptor_raw = NULL;
     129        rc = usb_request_get_full_configuration_descriptor_alloc(
     130            &dev->ctrl_pipe, 0,
     131            (void **) &config_descriptor_raw, &config_descriptor_size);
     132        if (rc != EOK) {
     133                usb_log_error("Failed getting full config descriptor: %s.\n",
     134                    str_error(rc));
    183135                return false;
    184136        }
     
    207159        }
    208160
     161        /* Select the first configuration */
     162        rc = usb_request_set_configuration(&dev->ctrl_pipe,
     163            config_descriptor->configuration_number);
     164        if (rc != EOK) {
     165                usb_log_error("Failed to set device configuration: %s.\n",
     166                    str_error(rc));
     167                free(config_descriptor_raw);
     168                free(interface_descriptors);
     169                return false;
     170        }
     171
     172
     173        /* Create control function */
    209174        ddf_fun_t *ctl_fun = ddf_fun_create(dev->dev, fun_exposed, "ctl");
    210175        if (ctl_fun == NULL) {
     
    223188        }
    224189
     190        /* Spawn interface children */
    225191        size_t i;
    226192        for (i = 0; i < interface_descriptors_count; i++) {
  • uspace/lib/c/generic/loader.c

    rdff940f8 r8c877b2  
    160160        int rc = async_data_write_start(ldr->phone_id, (void *) pa, pa_len);
    161161        if (rc != EOK) {
     162                free(pa);
    162163                async_wait_for(req, NULL);
    163164                return rc;
  • uspace/lib/c/generic/vfs/vfs.c

    rdff940f8 r8c877b2  
    6969        char *ncwd_path;
    7070        char *ncwd_path_nc;
     71        size_t total_size;
    7172
    7273        fibril_mutex_lock(&cwd_mutex);
     
    7778                        return NULL;
    7879                }
    79                 ncwd_path_nc = malloc(cwd_size + 1 + size + 1);
     80                total_size = cwd_size + 1 + size + 1;
     81                ncwd_path_nc = malloc(total_size);
    8082                if (!ncwd_path_nc) {
    8183                        fibril_mutex_unlock(&cwd_mutex);
    8284                        return NULL;
    8385                }
    84                 str_cpy(ncwd_path_nc, cwd_size + 1 + size + 1, cwd_path);
     86                str_cpy(ncwd_path_nc, total_size, cwd_path);
    8587                ncwd_path_nc[cwd_size] = '/';
    8688                ncwd_path_nc[cwd_size + 1] = '\0';
    8789        } else {
    88                 ncwd_path_nc = malloc(size + 1);
     90                total_size = size + 1;
     91                ncwd_path_nc = malloc(total_size);
    8992                if (!ncwd_path_nc) {
    9093                        fibril_mutex_unlock(&cwd_mutex);
     
    9396                ncwd_path_nc[0] = '\0';
    9497        }
    95         str_append(ncwd_path_nc, cwd_size + 1 + size + 1, path);
     98        str_append(ncwd_path_nc, total_size, path);
    9699        ncwd_path = canonify(ncwd_path_nc, retlen);
    97100        if (!ncwd_path) {
  • uspace/lib/c/include/ipc/dev_iface.h

    rdff940f8 r8c877b2  
    3838        CHAR_DEV_IFACE,
    3939
     40        /** Interface provided by any PCI device. */
     41        PCI_DEV_IFACE,
     42
    4043        /** Interface provided by any USB device. */
    4144        USB_DEV_IFACE,
  • uspace/lib/drv/Makefile

    rdff940f8 r8c877b2  
    3838        generic/remote_hw_res.c \
    3939        generic/remote_usb.c \
     40        generic/remote_pci.c \
    4041        generic/remote_usbhc.c
    4142
  • uspace/lib/drv/generic/dev_iface.c

    rdff940f8 r8c877b2  
    4343#include "remote_usb.h"
    4444#include "remote_usbhc.h"
     45#include "remote_pci.h"
    4546
    4647static iface_dipatch_table_t remote_ifaces = {
     
    4849                &remote_hw_res_iface,
    4950                &remote_char_dev_iface,
     51                &remote_pci_iface,
    5052                &remote_usb_iface,
    5153                &remote_usbhc_iface
  • uspace/lib/drv/include/remote_pci.h

    rdff940f8 r8c877b2  
    11/*
    2  * Copyright (c) 2010 Lubos Slovak
     2 * Copyright (c) 2011 Jan Vesely
    33 * All rights reserved.
    44 *
     
    2727 */
    2828
    29 /** @addtogroup drvusbhid
     29/** @addtogroup libdrv
    3030 * @{
    3131 */
    3232/** @file
    33  * Descriptor parser.
    3433 */
    3534
    36 #ifndef USBHID_DESCPARSER_H_
    37 #define USBHID_DESCPARSER_H_
     35#ifndef LIBDRV_REMOTE_PCI_H_
     36#define LIBDRV_REMOTE_PCI_H_
    3837
    39 #include "hid.h"
    40 
    41 int usbkbd_parse_descriptors(const uint8_t *data, size_t size,
    42                              usb_hid_configuration_t *config);
    43 
    44 void usbkbd_print_config(const usb_hid_configuration_t *config);
     38remote_iface_t remote_pci_iface;
    4539
    4640#endif
     
    4943 * @}
    5044 */
     45
  • uspace/lib/usb/include/usb/classes/hid.h

    rdff940f8 r8c877b2  
    5151} usb_hid_request_t;
    5252
     53typedef enum {
     54        USB_HID_REPORT_TYPE_INPUT = 1,
     55        USB_HID_REPORT_TYPE_OUTPUT = 2,
     56        USB_HID_REPORT_TYPE_FEATURE = 3
     57} usb_hid_report_type_t;
     58
     59typedef enum {
     60        USB_HID_PROTOCOL_BOOT = 0,
     61        USB_HID_PROTOCOL_REPORT = 1
     62} usb_hid_protocol_t;
     63
    5364/** USB/HID subclass constants. */
    5465typedef enum {
     
    6273        USB_HID_PROTOCOL_KEYBOARD = 1,
    6374        USB_HID_PROTOCOL_MOUSE = 2
    64 } usb_hid_protocol_t;
     75} usb_hid_iface_protocol_t;
    6576
    6677/** Part of standard USB HID descriptor specifying one class descriptor.
  • uspace/lib/usb/include/usb/classes/hidparser.h

    rdff940f8 r8c877b2  
    7070} usb_hid_report_in_callbacks_t;
    7171
    72 #define USB_HID_BOOT_KEYBOARD_NUM_LOCK          0x01
    73 #define USB_HID_BOOT_KEYBOARD_CAPS_LOCK         0x02
    74 #define USB_HID_BOOT_KEYBOARD_SCROLL_LOCK       0x04
    75 #define USB_HID_BOOT_KEYBOARD_COMPOSE           0x08
    76 #define USB_HID_BOOT_KEYBOARD_KANA                      0x10
     72
     73typedef enum {
     74        USB_HID_MOD_LCTRL = 0x01,
     75        USB_HID_MOD_LSHIFT = 0x02,
     76        USB_HID_MOD_LALT = 0x04,
     77        USB_HID_MOD_LGUI = 0x08,
     78        USB_HID_MOD_RCTRL = 0x10,
     79        USB_HID_MOD_RSHIFT = 0x20,
     80        USB_HID_MOD_RALT = 0x40,
     81        USB_HID_MOD_RGUI = 0x80,
     82        USB_HID_MOD_COUNT = 8
     83} usb_hid_modifiers_t;
     84
     85typedef enum {
     86        USB_HID_LED_NUM_LOCK = 0x1,
     87        USB_HID_LED_CAPS_LOCK = 0x2,
     88        USB_HID_LED_SCROLL_LOCK = 0x4,
     89        USB_HID_LED_COMPOSE = 0x8,
     90        USB_HID_LED_KANA = 0x10,
     91        USB_HID_LED_COUNT = 5
     92} usb_hid_led_t;
     93
     94static const usb_hid_modifiers_t
     95    usb_hid_modifiers_consts[USB_HID_MOD_COUNT] = {
     96        USB_HID_MOD_LCTRL,
     97        USB_HID_MOD_LSHIFT,
     98        USB_HID_MOD_LALT,
     99        USB_HID_MOD_LGUI,
     100        USB_HID_MOD_RCTRL,
     101        USB_HID_MOD_RSHIFT,
     102        USB_HID_MOD_RALT,
     103        USB_HID_MOD_RGUI
     104};
     105
     106//static const usb_hid_led_t usb_hid_led_consts[USB_HID_LED_COUNT] = {
     107//      USB_HID_LED_NUM_LOCK,
     108//      USB_HID_LED_CAPS_LOCK,
     109//      USB_HID_LED_SCROLL_LOCK,
     110//      USB_HID_LED_COMPOSE,
     111//      USB_HID_LED_KANA
     112//};
     113
     114//#define USB_HID_BOOT_KEYBOARD_NUM_LOCK                0x01
     115//#define USB_HID_BOOT_KEYBOARD_CAPS_LOCK               0x02
     116//#define USB_HID_BOOT_KEYBOARD_SCROLL_LOCK     0x04
     117//#define USB_HID_BOOT_KEYBOARD_COMPOSE         0x08
     118//#define USB_HID_BOOT_KEYBOARD_KANA                    0x10
    77119
    78120/*
  • uspace/lib/usb/include/usb/request.h

    rdff940f8 r8c877b2  
    9696int usb_request_set_address(usb_endpoint_pipe_t *, usb_address_t);
    9797int usb_request_get_descriptor(usb_endpoint_pipe_t *, usb_request_type_t,
    98     uint8_t, uint8_t, uint16_t, void *, size_t, size_t *);
     98    usb_request_recipient_t, uint8_t, uint8_t, uint16_t, void *, size_t,
     99    size_t *);
    99100int usb_request_get_descriptor_alloc(usb_endpoint_pipe_t *, usb_request_type_t,
    100     uint8_t, uint8_t, uint16_t, void **, size_t *);
     101    usb_request_recipient_t, uint8_t, uint8_t, uint16_t, void **, size_t *);
    101102int usb_request_get_device_descriptor(usb_endpoint_pipe_t *,
    102103    usb_standard_device_descriptor_t *);
     
    105106int usb_request_get_full_configuration_descriptor(usb_endpoint_pipe_t *, int,
    106107    void *, size_t, size_t *);
     108int usb_request_get_full_configuration_descriptor_alloc(usb_endpoint_pipe_t *,
     109    int, void **, size_t *);
    107110int usb_request_set_configuration(usb_endpoint_pipe_t *, uint8_t);
    108111
  • uspace/lib/usb/src/hidparser.c

    rdff940f8 r8c877b2  
    144144int usb_hid_boot_keyboard_output_report(uint8_t leds, uint8_t *data, size_t size)
    145145{
    146         if(size != 1){
     146        if (size < 1){
    147147                return -1;
    148148        }
    149149
    150         /* used only first five bits, others are only padding*/
    151         *data = leds;
     150        data[0] = leds;
    152151        return EOK;
    153152}
  • uspace/lib/usb/src/request.c

    rdff940f8 r8c877b2  
    3636#include <errno.h>
    3737#include <assert.h>
     38#include <usb/debug.h>
    3839
    3940#define MAX_DATA_LENGTH ((size_t)(0xFFFF))
     
    209210 */
    210211int usb_request_get_descriptor(usb_endpoint_pipe_t *pipe,
    211     usb_request_type_t request_type,
     212    usb_request_type_t request_type, usb_request_recipient_t recipient,
    212213    uint8_t descriptor_type, uint8_t descriptor_index,
    213214    uint16_t language,
     
    224225
    225226        return usb_control_request_get(pipe,
    226             request_type, USB_REQUEST_RECIPIENT_DEVICE,
     227            request_type, recipient,
    227228            USB_DEVREQ_GET_DESCRIPTOR,
    228229            wValue, language,
     
    242243 */
    243244int usb_request_get_descriptor_alloc(usb_endpoint_pipe_t * pipe,
    244     usb_request_type_t request_type,
     245    usb_request_type_t request_type, usb_request_recipient_t recipient,
    245246    uint8_t descriptor_type, uint8_t descriptor_index,
    246247    uint16_t language,
     
    258259        uint8_t tmp_buffer[1];
    259260        size_t bytes_transfered;
    260         rc = usb_request_get_descriptor(pipe, request_type,
     261        rc = usb_request_get_descriptor(pipe, request_type, recipient,
    261262            descriptor_type, descriptor_index, language,
    262263            &tmp_buffer, 1, &bytes_transfered);
     
    283284        }
    284285
    285         rc = usb_request_get_descriptor(pipe, request_type,
     286        rc = usb_request_get_descriptor(pipe, request_type, recipient,
    286287            descriptor_type, descriptor_index, language,
    287288            buffer, size, &bytes_transfered);
     
    320321        usb_standard_device_descriptor_t descriptor_tmp;
    321322        int rc = usb_request_get_descriptor(pipe,
    322             USB_REQUEST_TYPE_STANDARD, USB_DESCTYPE_DEVICE,
    323             0, 0,
     323            USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE,
     324            USB_DESCTYPE_DEVICE, 0, 0,
    324325            &descriptor_tmp, sizeof(descriptor_tmp),
    325326            &actually_transferred);
     
    366367        usb_standard_configuration_descriptor_t descriptor_tmp;
    367368        int rc = usb_request_get_descriptor(pipe,
    368             USB_REQUEST_TYPE_STANDARD, USB_DESCTYPE_CONFIGURATION,
    369             index, 0,
     369            USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE,
     370            USB_DESCTYPE_CONFIGURATION, index, 0,
    370371            &descriptor_tmp, sizeof(descriptor_tmp),
    371372            &actually_transferred);
     
    406407
    407408        return usb_request_get_descriptor(pipe,
    408             USB_REQUEST_TYPE_STANDARD, USB_DESCTYPE_CONFIGURATION,
    409             index, 0,
     409            USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE,
     410            USB_DESCTYPE_CONFIGURATION, index, 0,
    410411            descriptor, descriptor_size, actual_size);
     412}
     413
     414/** Retrieve full configuration descriptor, allocate space for it.
     415 *
     416 * The function takes care that full configuration descriptor is returned
     417 * (i.e. the function will fail when less data then descriptor.totalLength
     418 * is returned).
     419 *
     420 * @param[in] pipe Control endpoint pipe (session must be already started).
     421 * @param[in] index Configuration index.
     422 * @param[out] descriptor_ptr Where to store pointer to allocated buffer.
     423 * @param[out] descriptor_size Where to store the size of the descriptor.
     424 * @return Error code.
     425 */
     426int usb_request_get_full_configuration_descriptor_alloc(
     427    usb_endpoint_pipe_t *pipe, int index,
     428    void **descriptor_ptr, size_t *descriptor_size)
     429{
     430        int rc;
     431
     432        if (descriptor_ptr == NULL) {
     433                return EBADMEM;
     434        }
     435
     436        usb_standard_configuration_descriptor_t bare_config;
     437        rc = usb_request_get_bare_configuration_descriptor(pipe, index,
     438            &bare_config);
     439        if (rc != EOK) {
     440                return rc;
     441        }
     442
     443        if (bare_config.descriptor_type != USB_DESCTYPE_CONFIGURATION) {
     444                return ENOENT;
     445        }
     446        if (bare_config.total_length < sizeof(bare_config)) {
     447                return ELIMIT;
     448        }
     449
     450        void *buffer = malloc(bare_config.total_length);
     451        if (buffer == NULL) {
     452                return ENOMEM;
     453        }
     454
     455        size_t transferred = 0;
     456        rc = usb_request_get_full_configuration_descriptor(pipe, index,
     457            buffer, bare_config.total_length, &transferred);
     458        if (rc != EOK) {
     459                free(buffer);
     460                return rc;
     461        }
     462
     463        if (transferred != bare_config.total_length) {
     464                free(buffer);
     465                return ELIMIT;
     466        }
     467
     468        /* Everything looks okay, copy the pointers. */
     469
     470        *descriptor_ptr = buffer;
     471
     472        if (descriptor_size != NULL) {
     473                *descriptor_size = bare_config.total_length;
     474        }
     475
     476        return EOK;
    411477}
    412478
     
    452518        size_t string_descriptor_size = 0;
    453519        rc = usb_request_get_descriptor_alloc(pipe,
    454             USB_REQUEST_TYPE_STANDARD, USB_DESCTYPE_STRING, 0, 0,
     520            USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE,
     521            USB_DESCTYPE_STRING, 0, 0,
    455522            (void **) &string_descriptor, &string_descriptor_size);
    456523        if (rc != EOK) {
     
    502569 *
    503570 * @param[in] pipe Control endpoint pipe (session must be already started).
    504  * @param[in] index String index (in native endianess).
     571 * @param[in] index String index (in native endianess),
     572 *      first index has number 1 (index from descriptors can be used directly).
    505573 * @param[in] lang String language (in native endianess).
    506574 * @param[out] string_ptr Where to store allocated string in native encoding.
     
    513581                return EBADMEM;
    514582        }
    515         /* Index is actually one byte value. */
    516         if (index > 0xFF) {
     583        /*
     584         * Index is actually one byte value and zero index is used
     585         * to retrieve list of supported languages.
     586         */
     587        if ((index < 1) || (index > 0xFF)) {
    517588                return ERANGE;
    518589        }
     
    531602        size_t string_size;
    532603        rc = usb_request_get_descriptor_alloc(pipe,
    533             USB_REQUEST_TYPE_STANDARD, USB_DESCTYPE_STRING,
    534             index, uint16_host2usb(lang),
     604            USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE,
     605            USB_DESCTYPE_STRING, index, uint16_host2usb(lang),
    535606            (void **) &string, &string_size);
    536607        if (rc != EOK) {
  • uspace/srv/devmap/devmap.c

    rdff940f8 r8c877b2  
    123123static devmap_handle_t last_handle = 0;
    124124static devmap_device_t *null_devices[NULL_DEVICES];
     125
     126/*
     127 * Dummy list for null devices. This is necessary so that null devices can
     128 * be used just as any other devices, e.g. in devmap_device_unregister_core().
     129 */
     130static LIST_INITIALIZE(dummy_null_driver_devices);
    125131
    126132static devmap_handle_t devmap_create_handle(void)
     
    953959        device->name = dev_name;
    954960       
    955         /* Insert device into list of all devices
    956            and into null devices array */
     961        /*
     962         * Insert device into list of all devices and into null devices array.
     963         * Insert device into a dummy list of null driver's devices so that it
     964         * can be safely removed later.
     965         */
    957966        list_append(&device->devices, &devices_list);
     967        list_append(&device->driver_devices, &dummy_null_driver_devices);
    958968        null_devices[i] = device;
    959969       
  • uspace/srv/fs/fat/fat_dentry.c

    rdff940f8 r8c877b2  
    4242static bool is_d_char(const char ch)
    4343{
    44         if (isalnum(ch) || ch == '_')
     44        if (isalnum(ch) || ch == '_' || ch == '-')
    4545                return true;
    4646        else
  • uspace/srv/fs/fat/fat_ops.c

    rdff940f8 r8c877b2  
    325325                    uint16_t_le2host(d->firstc));
    326326                if (rc != EOK) {
     327                        (void) block_put(b);
    327328                        (void) fat_node_put(FS_NODE(nodep));
    328329                        return rc;
     
    811812        fibril_mutex_unlock(&childp->idx->lock);
    812813        childp->lnkcnt = 0;
     814        childp->refcnt++;       /* keep the node in memory until destroyed */
    813815        childp->dirty = true;
    814816        fibril_mutex_unlock(&childp->lock);
     
    14881490        fs_index_t index = (fs_index_t)IPC_GET_ARG2(*request);
    14891491        fs_node_t *fn;
     1492        fat_node_t *nodep;
    14901493        int rc;
    14911494
     
    14991502                return;
    15001503        }
     1504
     1505        nodep = FAT_NODE(fn);
     1506        /*
     1507         * We should have exactly two references. One for the above
     1508         * call to fat_node_get() and one from fat_unlink().
     1509         */
     1510        assert(nodep->refcnt == 2);
    15011511
    15021512        rc = fat_destroy_node(fn);
  • uspace/srv/hid/console/console.c

    rdff940f8 r8c877b2  
    4141#include <ipc/ns.h>
    4242#include <errno.h>
     43#include <str_error.h>
    4344#include <ipc/console.h>
    4445#include <unistd.h>
     
    6465#define NAME       "console"
    6566#define NAMESPACE  "term"
     67/** Interval for checking for new keyboard (1/4s). */
     68#define HOTPLUG_WATCH_INTERVAL (1000 * 250)
    6669
    6770/** Phone to the keyboard driver. */
     
    712715}
    713716
    714 static int connect_keyboard(char *path)
     717static int connect_keyboard_or_mouse(const char *devname,
     718    async_client_conn_t handler, const char *path)
    715719{
    716720        int fd = open(path, O_RDONLY);
     
    725729        }
    726730       
    727         /* NB: The callback connection is slotted for removal */
    728         sysarg_t phonehash;
    729         sysarg_t taskhash;
    730         int rc = async_req_3_5(phone, IPC_M_CONNECT_TO_ME, SERVICE_CONSOLE,
    731             0, 0, NULL, NULL, NULL, &taskhash, &phonehash);
     731        int rc = async_connect_to_me(phone, SERVICE_CONSOLE, 0, 0, handler);
    732732        if (rc != EOK) {
    733                 printf(NAME ": Failed to create callback from input device\n");
     733                printf(NAME ": " \
     734                    "Failed to create callback from input device: %s.\n",
     735                    str_error(rc));
    734736                return rc;
    735737        }
    736738       
    737         async_new_connection(taskhash, phonehash, 0, NULL, keyboard_events);
    738 
    739         printf(NAME ": we got a hit (new keyboard \"%s\").\n", path);
     739        printf(NAME ": found %s \"%s\".\n", devname, path);
    740740
    741741        return phone;
    742742}
    743743
    744 /** Try to connect to given keyboard, bypassing provided libc routines.
     744static int connect_keyboard(const char *path)
     745{
     746        return connect_keyboard_or_mouse("keyboard", keyboard_events, path);
     747}
     748
     749static int connect_mouse(const char *path)
     750{
     751        return connect_keyboard_or_mouse("mouse", mouse_events, path);
     752}
     753
     754struct hid_class_info {
     755        char *classname;
     756        int (*connection_func)(const char *);
     757};
     758
     759/** Periodically check for new keyboards in /dev/class/.
    745760 *
    746  * @param devmap_path Path to keyboard without /dev prefix.
    747  * @return Phone or error code.
     761 * @param arg Class name.
     762 * @return This function should never exit.
    748763 */
    749 static int connect_keyboard_bypass(char *devmap_path)
    750 {
    751         int devmap_phone = async_connect_me_to_blocking(PHONE_NS,
    752             SERVICE_DEVMAP, DEVMAP_CLIENT, 0);
    753         if (devmap_phone < 0) {
    754                 return devmap_phone;
    755         }
    756         ipc_call_t answer;
    757         aid_t req = async_send_2(devmap_phone, DEVMAP_DEVICE_GET_HANDLE,
    758             0, 0,  &answer);
    759 
    760         sysarg_t retval = async_data_write_start(devmap_phone,
    761             devmap_path, str_size(devmap_path));
    762         if (retval != EOK) {
    763                 async_wait_for(req, NULL);
    764                 async_hangup(devmap_phone);
    765                 return retval;
    766         }
    767 
    768         async_wait_for(req, &retval);
    769 
    770         if (retval != EOK) {
    771                 async_hangup(devmap_phone);
    772                 return retval;
    773         }
    774 
    775         devmap_handle_t handle = (devmap_handle_t) IPC_GET_ARG1(answer);
    776 
    777         async_hangup(devmap_phone);
    778 
    779         int phone = async_connect_me_to(PHONE_NS,
    780             SERVICE_DEVMAP, DEVMAP_CONNECT_TO_DEVICE, handle);
    781         if (phone < 0) {
    782                 return phone;
    783         }
    784 
    785         /* NB: The callback connection is slotted for removal */
    786         sysarg_t phonehash;
    787         sysarg_t taskhash;
    788         int rc = async_req_3_5(phone, IPC_M_CONNECT_TO_ME, SERVICE_CONSOLE,
    789             0, 0, NULL, NULL, NULL, &taskhash, &phonehash);
    790         if (rc != EOK) {
    791                 printf(NAME ": Failed to create callback from input device\n");
    792                 return rc;
    793         }
    794 
    795         async_new_connection(taskhash, phonehash, 0, NULL, keyboard_events);
    796 
    797         printf(NAME ": we got a hit (new keyboard \"/dev/%s\").\n",
    798             devmap_path);
    799 
    800         return phone;
    801 }
    802 
    803 
    804 static int check_new_keyboards(void *arg)
    805 {
    806         char *class_name = (char *) arg;
    807 
    808         int index = 1;
     764static int check_new_device_fibril(void *arg)
     765{
     766        struct hid_class_info *dev_info = arg;
     767
     768        size_t index = 1;
    809769
    810770        while (true) {
    811                 async_usleep(1 * 500 * 1000);
     771                async_usleep(HOTPLUG_WATCH_INTERVAL);
    812772                char *path;
    813                 int rc = asprintf(&path, "class/%s\\%d", class_name, index);
     773                int rc = asprintf(&path, "/dev/class/%s\\%zu",
     774                    dev_info->classname, index);
    814775                if (rc < 0) {
    815776                        continue;
    816777                }
    817778                rc = 0;
    818                 rc = connect_keyboard_bypass(path);
     779                rc = dev_info->connection_func(path);
    819780                if (rc > 0) {
    820781                        /* We do not allow unplug. */
     
    831792/** Start a fibril monitoring hot-plugged keyboards.
    832793 */
    833 static void check_new_keyboards_in_background()
    834 {
    835         fid_t fid = fibril_create(check_new_keyboards, (void *)"keyboard");
     794static void check_new_devices_in_background(int (*connection_func)(const char *),
     795    const char *classname)
     796{
     797        struct hid_class_info *dev_info = malloc(sizeof(struct hid_class_info));
     798        if (dev_info == NULL) {
     799                printf(NAME ": " \
     800                    "out of memory, will not start hot-plug-watch fibril.\n");
     801                return;
     802        }
     803        int rc;
     804
     805        rc = asprintf(&dev_info->classname, "%s", classname);
     806        if (rc < 0) {
     807                printf(NAME ": failed to format classname: %s.\n",
     808                    str_error(rc));
     809                return;
     810        }
     811        dev_info->connection_func = connection_func;
     812
     813        fid_t fid = fibril_create(check_new_device_fibril, (void *)dev_info);
    836814        if (!fid) {
    837                 printf(NAME ": failed to create hot-plug-watch fibril.\n");
     815                printf(NAME
     816                    ": failed to create hot-plug-watch fibril for %s.\n",
     817                    classname);
    838818                return;
    839819        }
     
    849829        }
    850830
    851         /* Connect to mouse device */
    852         mouse_phone = -1;
    853         int mouse_fd = open("/dev/hid_in/mouse", O_RDONLY);
    854        
    855         if (mouse_fd < 0) {
    856                 printf(NAME ": Notice - failed opening %s\n", "/dev/hid_in/mouse");
    857                 goto skip_mouse;
    858         }
    859        
    860         mouse_phone = fd_phone(mouse_fd);
     831        mouse_phone = connect_mouse("/dev/hid_in/mouse");
    861832        if (mouse_phone < 0) {
    862                 printf(NAME ": Failed to connect to mouse device\n");
    863                 goto skip_mouse;
    864         }
    865        
    866         if (async_connect_to_me(mouse_phone, SERVICE_CONSOLE, 0, 0, mouse_events)
    867             != 0) {
    868                 printf(NAME ": Failed to create callback from mouse device\n");
    869                 mouse_phone = -1;
    870                 goto skip_mouse;
    871         }
    872        
    873 skip_mouse:
     833                printf(NAME ": Failed to connect to mouse device: %s.\n",
     834                    str_error(mouse_phone));
     835        }
    874836       
    875837        /* Connect to framebuffer driver */
     
    955917       
    956918        /* Start fibril for checking on hot-plugged keyboards. */
    957         check_new_keyboards_in_background();
     919        check_new_devices_in_background(connect_keyboard, "keyboard");
     920        check_new_devices_in_background(connect_mouse, "mouse");
    958921
    959922        return true;
Note: See TracChangeset for help on using the changeset viewer.