Changeset 8d6c1f1 in mainline


Ignore:
Timestamp:
2011-06-07T21:31:35Z (13 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
75608143
Parents:
ff4f073 (diff), eb522e8 (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 USB support.

Changes from bzr://helenos-usb.bzr.sourceforge.net/bzrroot/helenos-usb/mainline:

  • replaced '-' with '_' in new driver names
  • USB libs are built for each architecture
  • devman starts early
  • sys_thread_udelay() uses generic delay()
  • sys_as_create_area() now creates cacheable areas by default
Files:
254 added
44 edited

Legend:

Unmodified
Added
Removed
  • HelenOS.config

    rff4f073 r8d6c1f1  
    537537! [CONFIG_BUILD_SHARED_LIBS=n] CONFIG_USE_SHARED_LIBS (n)
    538538
    539 % Run devman on startup
    540 ! CONFIG_START_DEVMAN (y/n)
    541 
    542539% Launch (devman) test drivers
    543540! [CONFIG_START_DEVMAN=y&CONFIG_DEBUG=y] CONFIG_TEST_DRIVERS (y/n)
     
    563560% Line debugging information
    564561! [CONFIG_STRIP_BINARIES!=y] CONFIG_LINE_DEBUG (n/y)
     562
     563# USB settings
     564
     565% USB release build (less logging)
     566! CONFIG_USB_RELEASE_BUILD (y/n)
     567
     568% Start virtual USB host controller
     569! CONFIG_RUN_VIRTUAL_USB_HC (n/y)
     570
     571% Polling UHCI & OHCI (no interrupts)
     572! [PLATFORM=ia32|PLATFORM=amd64] CONFIG_USBHC_NO_INTERRUPTS (n/y)
     573
  • Makefile

    rff4f073 r8d6c1f1  
    106106        $(MAKE) -C uspace clean
    107107        $(MAKE) -C boot clean
     108
     109-include Makefile.local
  • boot/Makefile.common

    rff4f073 r8d6c1f1  
    146146        $(USPACE_PATH)/app/killall/killall \
    147147        $(USPACE_PATH)/app/mkfat/mkfat \
     148        $(USPACE_PATH)/app/lsusb/lsusb \
    148149        $(USPACE_PATH)/app/sbi/sbi \
    149150        $(USPACE_PATH)/app/redir/redir \
     
    158159        $(USPACE_PATH)/app/ping/ping \
    159160        $(USPACE_PATH)/app/stats/stats \
     161        $(USPACE_PATH)/app/sysinfo/sysinfo \
    160162        $(USPACE_PATH)/app/top/top \
    161         $(USPACE_PATH)/app/sysinfo/sysinfo \
     163        $(USPACE_PATH)/app/usbinfo/usbinfo \
     164        $(USPACE_PATH)/app/vuhid/vuh \
     165        $(USPACE_PATH)/app/mkbd/mkbd \
    162166        $(USPACE_PATH)/app/websrv/websrv
    163167
  • boot/arch/amd64/Makefile.inc

    rff4f073 r8d6c1f1  
    4242        pciintel \
    4343        isa \
    44         ns8250
     44        ns8250 \
     45        ehci_hcd \
     46        ohci \
     47        uhci_hcd \
     48        uhci_rhd \
     49        usbflbk \
     50        usbhub \
     51        usbhid \
     52        usbmast \
     53        usbmid \
     54        usbmouse \
     55        vhc
    4556
    4657RD_DRV_CFG += \
  • kernel/generic/include/ddi/irq.h

    rff4f073 r8d6c1f1  
    7777         */
    7878        CMD_PIO_WRITE_A_32,
    79        
     79
     80        /** Read 1 byte from the memory space. */
     81        CMD_MEM_READ_8,
     82        /** Read 2 bytes from the memory space. */
     83        CMD_MEM_READ_16,
     84        /** Read 4 bytes from the memory space. */
     85        CMD_MEM_READ_32,
     86
     87        /** Write 1 byte to the memory space. */
     88        CMD_MEM_WRITE_8,
     89        /** Write 2 bytes to the memory space. */
     90        CMD_MEM_WRITE_16,
     91        /** Write 4 bytes to the memory space. */
     92        CMD_MEM_WRITE_32,
     93
     94        /** Write 1 byte from the source argument to the memory space. */
     95        CMD_MEM_WRITE_A_8,
     96        /** Write 2 bytes from the source argument to the memory space. */
     97        CMD_MEM_WRITE_A_16,
     98        /** Write 4 bytes from the source argument to the memory space. */
     99        CMD_MEM_WRITE_A_32,
     100
    80101        /**
    81102         * Perform a bit masking on the source argument
     
    203224        /** Notification configuration structure. */
    204225        ipc_notif_cfg_t notif_cfg;
     226
     227        as_t *driver_as;
    205228} irq_t;
    206229
  • kernel/generic/include/mm/page.h

    rff4f073 r8d6c1f1  
    3737
    3838#include <typedefs.h>
     39#include <proc/task.h>
    3940#include <mm/as.h>
    4041#include <arch/mm/page.h>
     
    6566extern uintptr_t hw_map(uintptr_t, size_t);
    6667
     68extern sysarg_t sys_page_find_mapping(uintptr_t, uintptr_t *);
     69
    6770#endif
    6871
  • kernel/generic/include/proc/thread.h

    rff4f073 r8d6c1f1  
    258258extern sysarg_t sys_thread_get_id(thread_id_t *);
    259259extern sysarg_t sys_thread_usleep(uint32_t);
     260extern sysarg_t sys_thread_udelay(uint32_t);
    260261
    261262#endif
  • kernel/generic/include/syscall/syscall.h

    rff4f073 r8d6c1f1  
    4444        SYS_THREAD_GET_ID,
    4545        SYS_THREAD_USLEEP,
     46        SYS_THREAD_UDELAY,
    4647       
    4748        SYS_TASK_GET_ID,
     
    6061        SYS_AS_AREA_DESTROY,
    6162        SYS_AS_GET_UNMAPPED_AREA,
     63       
     64        SYS_PAGE_FIND_MAPPING,
    6265       
    6366        SYS_IPC_CALL_SYNC_FAST,
  • kernel/generic/src/ipc/irq.c

    rff4f073 r8d6c1f1  
    174174        irq->notif_cfg.code = code;
    175175        irq->notif_cfg.counter = 0;
     176        irq->driver_as = AS;
    176177       
    177178        /*
     
    364365                return IRQ_DECLINE;
    365366       
     367#define CMD_MEM_READ(target) \
     368do { \
     369        void *va = code->cmds[i].addr; \
     370        if (AS != irq->driver_as) \
     371                as_switch(AS, irq->driver_as); \
     372        memcpy_from_uspace(&target, va, (sizeof(target))); \
     373        if (dstarg) \
     374                scratch[dstarg] = target; \
     375} while(0)
     376
     377#define CMD_MEM_WRITE(val) \
     378do { \
     379        void *va = code->cmds[i].addr; \
     380        if (AS != irq->driver_as) \
     381                as_switch(AS, irq->driver_as); \
     382        memcpy_to_uspace(va, &val, sizeof(val)); \
     383} while (0)
     384
     385        as_t *current_as = AS;
    366386        size_t i;
    367387        for (i = 0; i < code->cmdcount; i++) {
     
    422442                        }
    423443                        break;
     444                case CMD_MEM_READ_8: {
     445                        uint8_t val;
     446                        CMD_MEM_READ(val);
     447                        break;
     448                        }
     449                case CMD_MEM_READ_16: {
     450                        uint16_t val;
     451                        CMD_MEM_READ(val);
     452                        break;
     453                        }
     454                case CMD_MEM_READ_32: {
     455                        uint32_t val;
     456                        CMD_MEM_READ(val);
     457                        break;
     458                        }
     459                case CMD_MEM_WRITE_8: {
     460                        uint8_t val = code->cmds[i].value;
     461                        CMD_MEM_WRITE(val);
     462                        break;
     463                        }
     464                case CMD_MEM_WRITE_16: {
     465                        uint16_t val = code->cmds[i].value;
     466                        CMD_MEM_WRITE(val);
     467                        break;
     468                        }
     469                case CMD_MEM_WRITE_32: {
     470                        uint32_t val = code->cmds[i].value;
     471                        CMD_MEM_WRITE(val);
     472                        break;
     473                        }
     474                case CMD_MEM_WRITE_A_8:
     475                        if (srcarg) {
     476                                uint8_t val = scratch[srcarg];
     477                                CMD_MEM_WRITE(val);
     478                        }
     479                        break;
     480                case CMD_MEM_WRITE_A_16:
     481                        if (srcarg) {
     482                                uint16_t val = scratch[srcarg];
     483                                CMD_MEM_WRITE(val);
     484                        }
     485                        break;
     486                case CMD_MEM_WRITE_A_32:
     487                        if (srcarg) {
     488                                uint32_t val = scratch[srcarg];
     489                                CMD_MEM_WRITE(val);
     490                        }
     491                        break;
    424492                case CMD_BTEST:
    425493                        if ((srcarg) && (dstarg)) {
     
    435503                        break;
    436504                case CMD_ACCEPT:
     505                        if (AS != current_as)
     506                                as_switch(AS, current_as);
    437507                        return IRQ_ACCEPT;
    438508                case CMD_DECLINE:
    439509                default:
     510                        if (AS != current_as)
     511                                as_switch(AS, current_as);
    440512                        return IRQ_DECLINE;
    441513                }
    442514        }
     515        if (AS != current_as)
     516                as_switch(AS, current_as);
    443517       
    444518        return IRQ_DECLINE;
  • kernel/generic/src/mm/page.c

    rff4f073 r8d6c1f1  
    6060
    6161#include <mm/page.h>
     62#include <genarch/mm/page_ht.h>
     63#include <genarch/mm/page_pt.h>
    6264#include <arch/mm/page.h>
    6365#include <arch/mm/asid.h>
     
    7072#include <debug.h>
    7173#include <arch.h>
     74#include <syscall/copy.h>
     75#include <errno.h>
    7276
    7377/** Virtual operations for page subsystem. */
     
    172176}
    173177
     178/** Syscall wrapper for getting mapping of a virtual page.
     179 *
     180 * @retval EOK Everything went find, @p uspace_frame and @p uspace_node
     181 *             contains correct values.
     182 * @retval ENOENT Virtual address has no mapping.
     183 */
     184sysarg_t sys_page_find_mapping(uintptr_t virt_address,
     185    uintptr_t *uspace_frame)
     186{
     187        mutex_lock(&AS->lock);
     188       
     189        pte_t *pte = page_mapping_find(AS, virt_address, false);
     190        if (!PTE_VALID(pte) || !PTE_PRESENT(pte)) {
     191                mutex_unlock(&AS->lock);
     192               
     193                return (sysarg_t) ENOENT;
     194        }
     195       
     196        uintptr_t phys_address = PTE_GET_FRAME(pte);
     197       
     198        mutex_unlock(&AS->lock);
     199       
     200        int rc = copy_to_uspace(uspace_frame,
     201            &phys_address, sizeof(phys_address));
     202        if (rc != EOK) {
     203                return (sysarg_t) rc;
     204        }
     205       
     206        return EOK;
     207}
     208
    174209/** @}
    175210 */
  • kernel/generic/src/proc/thread.c

    rff4f073 r8d6c1f1  
    5555#include <time/clock.h>
    5656#include <time/timeout.h>
     57#include <time/delay.h>
    5758#include <config.h>
    5859#include <arch/interrupt.h>
     
    912913}
    913914
     915sysarg_t sys_thread_udelay(uint32_t usec)
     916{
     917        delay(usec);
     918        return 0;
     919}
     920
    914921/** @}
    915922 */
  • kernel/generic/src/syscall/syscall.c

    rff4f073 r8d6c1f1  
    4141#include <proc/program.h>
    4242#include <mm/as.h>
     43#include <mm/page.h>
    4344#include <print.h>
    4445#include <arch.h>
     
    126127        (syshandler_t) sys_thread_get_id,
    127128        (syshandler_t) sys_thread_usleep,
     129        (syshandler_t) sys_thread_udelay,
    128130       
    129131        (syshandler_t) sys_task_get_id,
     
    144146        (syshandler_t) sys_as_area_destroy,
    145147        (syshandler_t) sys_as_get_unmapped_area,
     148       
     149        /* Page mapping related syscalls. */
     150        (syshandler_t) sys_page_find_mapping,
    146151       
    147152        /* IPC related syscalls. */
  • uspace/Makefile

    rff4f073 r8d6c1f1  
    4444        app/killall \
    4545        app/klog \
     46        app/lsusb \
    4647        app/mkfat \
    4748        app/redir \
     
    5455        app/trace \
    5556        app/top \
     57        app/usbinfo \
     58        app/vuhid \
    5659        app/netecho \
    5760        app/nettest1 \
     
    6063        app/websrv \
    6164        app/sysinfo \
     65        app/mkbd \
    6266        srv/clip \
    6367        srv/devmap \
     
    119123                drv/ns8250 \
    120124                srv/hw/irc/apic \
    121                 srv/hw/irc/i8259
     125                srv/hw/irc/i8259 \
     126                drv/ehci_hcd \
     127                drv/ohci \
     128                drv/uhci_hcd \
     129                drv/uhci_rhd \
     130                drv/usbflbk \
     131                drv/usbhid \
     132                drv/usbhub \
     133                drv/usbmast \
     134                drv/usbmid \
     135                drv/usbmouse \
     136                drv/vhc
    122137endif
    123138
     
    129144                drv/ns8250 \
    130145                srv/hw/irc/apic \
    131                 srv/hw/irc/i8259
     146                srv/hw/irc/i8259 \
     147                drv/ehci_hcd \
     148                drv/ohci \
     149                drv/uhci_hcd \
     150                drv/uhci_rhd \
     151                drv/usbflbk \
     152                drv/usbhid \
     153                drv/usbhub \
     154                drv/usbmast \
     155                drv/usbmid \
     156                drv/usbmouse \
     157                drv/vhc
    132158endif
    133159
     
    155181        lib/packet \
    156182        lib/net \
    157         lib/ext2
     183        lib/ext2 \
     184        lib/usb \
     185        lib/usbhost \
     186        lib/usbdev \
     187        lib/usbhid \
     188        lib/usbvirt
    158189
    159190LIBC_BUILD = $(addsuffix .build,$(LIBC))
  • uspace/Makefile.common

    rff4f073 r8d6c1f1  
    110110LIBEXT2_PREFIX = $(LIB_PREFIX)/ext2
    111111
     112LIBUSB_PREFIX = $(LIB_PREFIX)/usb
     113LIBUSBHOST_PREFIX = $(LIB_PREFIX)/usbhost
     114LIBUSBDEV_PREFIX = $(LIB_PREFIX)/usbdev
     115LIBUSBHID_PREFIX = $(LIB_PREFIX)/usbhid
     116LIBUSBVIRT_PREFIX = $(LIB_PREFIX)/usbvirt
     117
    112118LIBDRV_PREFIX = $(LIB_PREFIX)/drv
    113119LIBPACKET_PREFIX = $(LIB_PREFIX)/packet
     
    127133        endif
    128134endif
     135# Build static whenever we use libusb because that library uses
     136# thread local variables
     137ifneq ($(findstring usb, $(LIBS)),)
     138        STATIC_BUILD = y
     139endif
    129140
    130141ifeq ($(STATIC_BUILD), y)
  • uspace/app/init/init.c

    rff4f073 r8d6c1f1  
    272272        mount_tmpfs();
    273273       
    274 #ifdef CONFIG_START_DEVMAN
    275274        spawn("/srv/devman");
    276 #endif
    277275        spawn("/srv/apic");
    278276        spawn("/srv/i8259");
  • uspace/app/tester/Makefile

    rff4f073 r8d6c1f1  
    5555        mm/malloc2.c \
    5656        mm/malloc3.c \
     57        mm/mapping1.c \
    5758        devs/devman1.c \
    5859        devs/devman2.c \
  • uspace/app/tester/tester.c

    rff4f073 r8d6c1f1  
    6464#include "mm/malloc2.def"
    6565#include "mm/malloc3.def"
     66#include "mm/mapping1.def"
    6667#include "hw/serial/serial1.def"
    6768#include "hw/misc/virtchar1.def"
  • uspace/app/tester/tester.h

    rff4f073 r8d6c1f1  
    9797extern const char *test_malloc2(void);
    9898extern const char *test_malloc3(void);
     99extern const char *test_mapping1(void);
    99100extern const char *test_serial1(void);
    100101extern const char *test_virtchar1(void);
  • uspace/doc/doxygroups.h

    rff4f073 r8d6c1f1  
    150150         * @endcond
    151151         */
    152        
     152
    153153/**
    154154 * @defgroup emul Emulation Libraries
     
    165165         * @ingroup emul
    166166         */
     167
     168/**
     169 * @defgroup usb USB
     170 * @ingroup uspace
     171 * @brief USB support for HelenOS.
     172 */
     173        /**
     174         * @defgroup libusb Base USB library
     175         * @ingroup usb
     176         * @brief Common definitions for any driver or application
     177         * dealing with USB.
     178         */
     179
     180        /**
     181         * @defgroup libusbdev USB library for device drivers
     182         * @ingroup usb
     183         * @brief Library for writing drivers of endpoint devices (functions).
     184         */
     185
     186        /**
     187         * @defgroup libusbhost USB library for host controller drivers
     188         * @ingroup usb
     189         * @brief Library for writing host controller drivers.
     190         */
     191
     192        /**
     193         * @defgroup libusbhid USB library for HID devices
     194         * @ingroup usb
     195         * @brief Library for writing USB HID drivers.
     196         */
     197
     198        /**
     199         * @defgroup usbvirt USB virtualization
     200         * @ingroup usb
     201         * @brief Support for virtual USB devices.
     202         */
     203
     204                /**
     205                 * @defgroup libusbvirt USB virtualization library
     206                 * @ingroup usbvirt
     207                 * @brief Library for creating virtual USB devices.
     208                 */
     209
     210                /**
     211                 * @defgroup drvusbvhc Virtual USB host controller
     212                 * @ingroup usbvirt
     213                 * @brief Driver simulating work of USB host controller.
     214                 */
     215
     216                /**
     217                 * @defgroup usbvirthub Virtual USB hub
     218                 * @ingroup usbvirt
     219                 * @brief Extra virtual USB hub for virtual host controller.
     220                 * @details
     221                 * Some of the sources are shared with virtual host controller,
     222                 * see @ref drvusbvhc for the rest of the files.
     223                 */
     224
     225                /**
     226                 * @defgroup usbvirtkbd Virtual USB keybaord
     227                 * @ingroup usbvirt
     228                 * @brief Virtual USB keyboard for virtual host controller.
     229                 */
     230
     231        /**
     232         * @defgroup usbinfo USB info application
     233         * @ingroup usb
     234         * @brief Application for querying USB devices.
     235         * @details
     236         * The intended usage of this application is to query new USB devices
     237         * for their descriptors etc. to simplify driver writing.
     238         */
     239
     240        /**
     241         * @defgroup lsusb HelenOS version of lsusb command
     242         * @ingroup usb
     243         * @brief Application for listing USB host controllers.
     244         * @details
     245         * List all found host controllers.
     246         */
     247
     248        /**
     249         * @defgroup drvusbmid USB multi interface device driver
     250         * @ingroup usb
     251         * @brief USB multi interface device driver
     252         * @details
     253         * This driver serves as a mini hub (or bus) driver for devices
     254         * that have the class defined at interface level (those devices
     255         * usually have several interfaces).
     256         *
     257         * The term multi interface device driver (MID) was borrowed
     258         * Solaris operating system.
     259         */
     260
     261        /**
     262         * @defgroup drvusbhub USB hub driver
     263         * @ingroup usb
     264         * @brief USB hub driver.
     265         */
     266
     267        /**
     268         * @defgroup drvusbhid USB HID driver
     269         * @ingroup usb
     270         * @brief USB driver for HID devices.
     271         */
     272
     273        /**
     274         * @defgroup drvusbmouse USB mouse driver
     275         * @ingroup usb
     276         * @brief USB driver for mouse with boot protocol.
     277         */
     278
     279        /**
     280         * @defgroup drvusbmast USB mass storage driver
     281         * @ingroup usb
     282         * @brief USB driver for mass storage devices (bulk-only protocol).
     283         * This driver is a only a stub and is currently used only for
     284         * testing that bulk transfers work.
     285         */
     286
     287        /**
     288         * @defgroup drvusbuhci UHCI driver
     289         * @ingroup usb
     290         * @brief Drivers for USB UHCI host controller and root hub.
     291         */
     292
     293                /**
     294                 * @defgroup drvusbuhcirh UHCI root hub driver
     295                 * @ingroup drvusbuhci
     296                 * @brief Driver for UHCI complaint root hub.
     297                 */
     298
     299                /**
     300                 * @defgroup drvusbuhcihc UHCI host controller driver
     301                 * @ingroup drvusbuhci
     302                 * @brief Driver for UHCI complaint USB host controller.
     303                 */
     304
     305        /**
     306         * @defgroup drvusbohci OHCI driver
     307         * @ingroup usb
     308         * @brief Driver for OHCI host controller.
     309         */
     310
     311        /**
     312         * @defgroup drvusbehci EHCI driver
     313         * @ingroup usb
     314         * @brief Driver for EHCI host controller.
     315         */
     316
     317        /**
     318         * @defgroup drvusbfallback USB fallback driver
     319         * @ingroup usb
     320         * @brief Fallback driver for any USB device.
     321         * @details
     322         * The purpose of this driver is to simplify querying of unknown
     323         * devices from within HelenOS (without a driver, no node at all
     324         * may appear under /dev/devices).
     325         */
     326
     327
  • uspace/drv/pciintel/pci.c

    rff4f073 r8d6c1f1  
    5252#include <ipc/devman.h>
    5353#include <ipc/dev_iface.h>
     54#include <ipc/irc.h>
     55#include <ipc/ns.h>
     56#include <ipc/services.h>
     57#include <sysinfo.h>
    5458#include <ops/hw_res.h>
    5559#include <device/hw_res.h>
    5660#include <ddi.h>
    5761#include <libarch/ddi.h>
     62#include <pci_dev_iface.h>
    5863
    5964#include "pci.h"
     
    8489static bool pciintel_enable_interrupt(ddf_fun_t *fnode)
    8590{
    86         /* TODO */
    87        
    88         return false;
     91        /* This is an old ugly way, copied from ne2000 driver */
     92        assert(fnode);
     93        pci_fun_t *dev_data = (pci_fun_t *) fnode->driver_data;
     94
     95        sysarg_t apic;
     96        sysarg_t i8259;
     97
     98        int irc_phone = ENOTSUP;
     99
     100        if (((sysinfo_get_value("apic", &apic) == EOK) && (apic))
     101            || ((sysinfo_get_value("i8259", &i8259) == EOK) && (i8259))) {
     102                irc_phone = service_connect_blocking(SERVICE_IRC, 0, 0);
     103        }
     104
     105        if (irc_phone < 0) {
     106                return false;
     107        }
     108
     109        size_t i = 0;
     110        hw_resource_list_t *res = &dev_data->hw_resources;
     111        for (; i < res->count; i++) {
     112                if (res->resources[i].type == INTERRUPT) {
     113                        const int irq = res->resources[i].res.interrupt.irq;
     114                        const int rc =
     115                            async_req_1_0(irc_phone, IRC_ENABLE_INTERRUPT, irq);
     116                        if (rc != EOK) {
     117                                async_hangup(irc_phone);
     118                                return false;
     119                        }
     120                }
     121        }
     122
     123        async_hangup(irc_phone);
     124        return true;
     125}
     126
     127static int pci_config_space_write_32(
     128    ddf_fun_t *fun, uint32_t address, uint32_t data)
     129{
     130        if (address > 252)
     131                return EINVAL;
     132        pci_conf_write_32(PCI_FUN(fun), address, data);
     133        return EOK;
     134}
     135
     136static int pci_config_space_write_16(
     137    ddf_fun_t *fun, uint32_t address, uint16_t data)
     138{
     139        if (address > 254)
     140                return EINVAL;
     141        pci_conf_write_16(PCI_FUN(fun), address, data);
     142        return EOK;
     143}
     144
     145static int pci_config_space_write_8(
     146    ddf_fun_t *fun, uint32_t address, uint8_t data)
     147{
     148        if (address > 255)
     149                return EINVAL;
     150        pci_conf_write_8(PCI_FUN(fun), address, data);
     151        return EOK;
     152}
     153
     154static int pci_config_space_read_32(
     155    ddf_fun_t *fun, uint32_t address, uint32_t *data)
     156{
     157        if (address > 252)
     158                return EINVAL;
     159        *data = pci_conf_read_32(PCI_FUN(fun), address);
     160        return EOK;
     161}
     162
     163static int pci_config_space_read_16(
     164    ddf_fun_t *fun, uint32_t address, uint16_t *data)
     165{
     166        if (address > 254)
     167                return EINVAL;
     168        *data = pci_conf_read_16(PCI_FUN(fun), address);
     169        return EOK;
     170}
     171
     172static int pci_config_space_read_8(
     173    ddf_fun_t *fun, uint32_t address, uint8_t *data)
     174{
     175        if (address > 255)
     176                return EINVAL;
     177        *data = pci_conf_read_8(PCI_FUN(fun), address);
     178        return EOK;
    89179}
    90180
     
    94184};
    95185
    96 static ddf_dev_ops_t pci_fun_ops;
     186static pci_dev_iface_t pci_dev_ops = {
     187        .config_space_read_8 = &pci_config_space_read_8,
     188        .config_space_read_16 = &pci_config_space_read_16,
     189        .config_space_read_32 = &pci_config_space_read_32,
     190        .config_space_write_8 = &pci_config_space_write_8,
     191        .config_space_write_16 = &pci_config_space_write_16,
     192        .config_space_write_32 = &pci_config_space_write_32
     193};
     194
     195static ddf_dev_ops_t pci_fun_ops = {
     196        .interfaces[HW_RES_DEV_IFACE] = &pciintel_hw_res_ops,
     197        .interfaces[PCI_DEV_IFACE] = &pci_dev_ops
     198};
    97199
    98200static int pci_add_device(ddf_dev_t *);
     
    288390        /* Get the value of the BAR. */
    289391        val = pci_conf_read_32(fun, addr);
     392
     393#define IO_MASK  (~0x3)
     394#define MEM_MASK (~0xf)
    290395       
    291396        io = (bool) (val & 1);
    292397        if (io) {
    293398                addrw64 = false;
     399                mask = IO_MASK;
    294400        } else {
     401                mask = MEM_MASK;
    295402                switch ((val >> 1) & 3) {
    296403                case 0:
     
    308415        /* Get the address mask. */
    309416        pci_conf_write_32(fun, addr, 0xffffffff);
    310         mask = pci_conf_read_32(fun, addr);
     417        mask &= pci_conf_read_32(fun, addr);
    311418       
    312419        /* Restore the original value. */
     
    558665        ddf_log_init(NAME, LVL_ERROR);
    559666        pci_fun_ops.interfaces[HW_RES_DEV_IFACE] = &pciintel_hw_res_ops;
     667        pci_fun_ops.interfaces[PCI_DEV_IFACE] = &pci_dev_ops;
    560668}
    561669
     
    629737size_t pci_bar_mask_to_size(uint32_t mask)
    630738{
    631         return ((mask & 0xfffffff0) ^ 0xffffffff) + 1;
     739        size_t size = mask & ~(mask - 1);
     740        return size;
    632741}
    633742
  • uspace/drv/rootvirt/devices.def

    rff4f073 r8d6c1f1  
    2626},
    2727#endif
     28#ifdef CONFIG_RUN_VIRTUAL_USB_HC
     29/* Virtual USB host controller. */
     30{
     31        .name = "usbhc",
     32        .match_id = "usb&hc=vhc"
     33},
     34#endif
  • uspace/lib/c/Makefile

    rff4f073 r8d6c1f1  
    7676        generic/str.c \
    7777        generic/str_error.c \
     78        generic/l18n/langs.c \
    7879        generic/fibril.c \
    7980        generic/fibril_synch.c \
  • uspace/lib/c/generic/adt/hash_table.c

    rff4f073 r8d6c1f1  
    5454 *
    5555 */
    56 int hash_table_create(hash_table_t *h, hash_count_t m, hash_count_t max_keys,
     56bool hash_table_create(hash_table_t *h, hash_count_t m, hash_count_t max_keys,
    5757    hash_table_operations_t *op)
    5858{
  • uspace/lib/c/generic/as.c

    rff4f073 r8d6c1f1  
    3535#include <as.h>
    3636#include <libc.h>
     37#include <errno.h>
    3738#include <unistd.h>
    3839#include <align.h>
     
    114115}
    115116
     117/** Find mapping to physical address.
     118 *
     119 * @param address Virtual address in question (virtual).
     120 * @param[out] frame Frame address (physical).
     121 * @return Error code.
     122 * @retval EOK No error, @p frame holds the translation.
     123 * @retval ENOENT Mapping not found.
     124 */
     125int as_get_physical_mapping(void *address, uintptr_t *frame)
     126{
     127        uintptr_t tmp_frame;
     128        uintptr_t virt = (uintptr_t) address;
     129       
     130        int rc = (int) __SYSCALL2(SYS_PAGE_FIND_MAPPING,
     131            (sysarg_t) virt, (sysarg_t) &tmp_frame);
     132        if (rc != EOK) {
     133                return rc;
     134        }
     135       
     136        if (frame != NULL) {
     137                *frame = tmp_frame;
     138        }
     139       
     140        return EOK;
     141}
     142
    116143/** @}
    117144 */
  • uspace/lib/c/generic/async.c

    rff4f073 r8d6c1f1  
    15691569}
    15701570
     1571/** Start IPC_M_DATA_READ using the async framework.
     1572 *
     1573 * @param phoneid Phone that will be used to contact the receiving side.
     1574 * @param dst Address of the beginning of the destination buffer.
     1575 * @param size Size of the destination buffer (in bytes).
     1576 * @param dataptr Storage of call data (arg 2 holds actual data size).
     1577 * @return Hash of the sent message or 0 on error.
     1578 */
     1579aid_t async_data_read(int phoneid, void *dst, size_t size, ipc_call_t *dataptr)
     1580{
     1581        return async_send_2(phoneid, IPC_M_DATA_READ, (sysarg_t) dst,
     1582            (sysarg_t) size, dataptr);
     1583}
     1584
    15711585/** Wrapper for IPC_M_DATA_READ calls using the async framework.
    15721586 *
  • uspace/lib/c/generic/devman.c

    rff4f073 r8d6c1f1  
    374374}
    375375
     376int devman_get_device_path(devman_handle_t handle, char *path, size_t path_size)
     377{
     378        int phone = devman_get_phone(DEVMAN_CLIENT, 0);
     379
     380        if (phone < 0)
     381                return phone;
     382
     383        async_serialize_start();
     384
     385        ipc_call_t answer;
     386        aid_t req = async_send_1(phone, DEVMAN_DEVICE_GET_DEVICE_PATH,
     387            handle, &answer);
     388
     389        ipc_call_t data_request_call;
     390        aid_t data_request = async_data_read(phone, path, path_size,
     391            &data_request_call);
     392        if (data_request == 0) {
     393                async_wait_for(req, NULL);
     394                async_serialize_end();
     395                return ENOMEM;
     396        }
     397
     398        sysarg_t data_request_rc;
     399        sysarg_t opening_request_rc;
     400        async_wait_for(data_request, &data_request_rc);
     401        async_wait_for(req, &opening_request_rc);
     402
     403        async_serialize_end();
     404
     405        if (data_request_rc != EOK) {
     406                /* Prefer the return code of the opening request. */
     407                if (opening_request_rc != EOK) {
     408                        return (int) opening_request_rc;
     409                } else {
     410                        return (int) data_request_rc;
     411                }
     412        }
     413        if (opening_request_rc != EOK) {
     414                return (int) opening_request_rc;
     415        }
     416
     417        /* To be on the safe-side. */
     418        path[path_size - 1] = 0;
     419
     420        size_t transferred_size = IPC_GET_ARG2(data_request_call);
     421
     422        if (transferred_size >= path_size) {
     423                return ELIMIT;
     424        }
     425
     426        /* Terminate the string (trailing 0 not send over IPC). */
     427        path[transferred_size] = 0;
     428
     429        return EOK;
     430}
     431
    376432
    377433/** @}
  • uspace/lib/c/generic/str_error.c

    rff4f073 r8d6c1f1  
    3333 */
    3434
     35#include <errno.h>
    3536#include <str_error.h>
    3637#include <stdio.h>
     
    6364static fibril_local char noerr[NOERR_LEN];
    6465
    65 const char *str_error(const int errno)
     66const char *str_error(const int e)
    6667{
    67         if ((errno <= 0) && (errno >= MIN_ERRNO))
    68                 return err_desc[-errno];
     68        if ((e <= 0) && (e >= MIN_ERRNO))
     69                return err_desc[-e];
    6970       
    70         snprintf(noerr, NOERR_LEN, "Unkown error code %d", errno);
     71        /* Ad hoc descriptions of error codes interesting for USB. */
     72        switch (e) {
     73                case EBADCHECKSUM:
     74                        return "Bad checksum";
     75                case ESTALL:
     76                        return "Operation stalled";
     77                case EAGAIN:
     78                        return "Resource temporarily unavailable";
     79                case EEMPTY:
     80                        return "Resource is empty";
     81                default:
     82                        break;
     83        }
     84
     85        snprintf(noerr, NOERR_LEN, "Unkown error code %d", e);
    7186        return noerr;
    7287}
  • uspace/lib/c/generic/time.c

    rff4f073 r8d6c1f1  
    207207}
    208208
     209void udelay(useconds_t time)
     210{
     211        (void) __SYSCALL1(SYS_THREAD_UDELAY, (sysarg_t) time);
     212}
     213
     214
    209215/** Wait unconditionally for specified number of seconds
    210216 *
  • uspace/lib/c/include/adt/hash_table.h

    rff4f073 r8d6c1f1  
    3838#include <adt/list.h>
    3939#include <unistd.h>
     40#include <bool.h>
    4041
    4142typedef unsigned long hash_count_t;
     
    8384    list_get_instance((item), type, member)
    8485
    85 extern int hash_table_create(hash_table_t *, hash_count_t, hash_count_t,
     86extern bool hash_table_create(hash_table_t *, hash_count_t, hash_count_t,
    8687    hash_table_operations_t *);
    8788extern void hash_table_insert(hash_table_t *, unsigned long [], link_t *);
  • uspace/lib/c/include/as.h

    rff4f073 r8d6c1f1  
    6060extern void *set_maxheapsize(size_t);
    6161extern void *as_get_mappable_page(size_t);
     62extern int as_get_physical_mapping(void *, uintptr_t *);
    6263
    6364#endif
  • uspace/lib/c/include/async.h

    rff4f073 r8d6c1f1  
    340340            (arg4), (answer))
    341341
     342extern aid_t async_data_read(int, void *, size_t, ipc_call_t *);
    342343#define async_data_read_start(p, buf, len) \
    343344        async_data_read_start_generic((p), (buf), (len), IPC_XF_NONE)
  • uspace/lib/c/include/devman.h

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

    rff4f073 r8d6c1f1  
    5656#define EMLINK        (-266)
    5757
     58/** Bad checksum. */
     59#define EBADCHECKSUM  (-300)
     60
     61/** USB: stalled operation. */
     62#define ESTALL (-301)
     63
     64/** Empty resource (no data). */
     65#define EEMPTY (-302)
     66
     67/** Negative acknowledgment. */
     68#define ENAK (-303)
     69
    5870/** An API function is called while another blocking function is in progress. */
    5971#define EINPROGRESS  (-10036)
  • uspace/lib/c/include/ipc/dev_iface.h

    rff4f073 r8d6c1f1  
    3737        HW_RES_DEV_IFACE = 0,
    3838        CHAR_DEV_IFACE,
     39
     40        /** Interface provided by any PCI device. */
     41        PCI_DEV_IFACE,
     42
     43        /** Interface provided by any USB device. */
     44        USB_DEV_IFACE,
     45        /** Interface provided by USB host controller. */
     46        USBHC_DEV_IFACE,
     47        /** Interface provided by USB HID devices. */
     48        USBHID_DEV_IFACE,
     49
    3950        DEV_IFACE_MAX
    4051} dev_inferface_idx_t;
     
    4859        DEV_IFACE_ID(DEV_FIRST_CUSTOM_METHOD_IDX)
    4960
     61/*
     62 * The first argument is actually method (as the "real" method is used
     63 * for indexing into interfaces.
     64 */
     65
     66#define DEV_IPC_GET_ARG1(call) IPC_GET_ARG2((call))
     67#define DEV_IPC_GET_ARG2(call) IPC_GET_ARG3((call))
     68#define DEV_IPC_GET_ARG3(call) IPC_GET_ARG4((call))
     69#define DEV_IPC_GET_ARG4(call) IPC_GET_ARG5((call))
     70
    5071
    5172#endif
  • uspace/lib/c/include/ipc/devman.h

    rff4f073 r8d6c1f1  
    149149typedef enum {
    150150        DEVMAN_DEVICE_GET_HANDLE = IPC_FIRST_USER_METHOD,
    151         DEVMAN_DEVICE_GET_HANDLE_BY_CLASS
     151        DEVMAN_DEVICE_GET_HANDLE_BY_CLASS,
     152        DEVMAN_DEVICE_GET_DEVICE_PATH
    152153} client_to_devman_t;
    153154
  • uspace/lib/c/include/ipc/kbd.h

    rff4f073 r8d6c1f1  
    3939
    4040#include <ipc/common.h>
     41#include <ipc/dev_iface.h>
    4142
    4243typedef enum {
    43         KBD_YIELD = IPC_FIRST_USER_METHOD,
     44        KBD_YIELD = DEV_FIRST_CUSTOM_METHOD,
    4445        KBD_RECLAIM
    4546} kbd_request_t;
  • uspace/lib/c/include/sys/time.h

    rff4f073 r8d6c1f1  
    6262extern int gettimeofday(struct timeval *tv, struct timezone *tz);
    6363
     64extern void udelay(useconds_t);
     65
    6466#endif
    6567
  • uspace/lib/drv/Makefile

    rff4f073 r8d6c1f1  
    2929
    3030USPACE_PREFIX = ../..
    31 EXTRA_CFLAGS = -Iinclude
     31EXTRA_CFLAGS = -Iinclude -I$(LIBUSB_PREFIX)/include
    3232LIBRARY = libdrv
    3333
     
    3535        generic/driver.c \
    3636        generic/dev_iface.c \
     37        generic/remote_char_dev.c \
    3738        generic/log.c \
    3839        generic/remote_hw_res.c \
    39         generic/remote_char_dev.c
     40        generic/remote_usb.c \
     41        generic/remote_pci.c \
     42        generic/remote_usbhc.c \
     43        generic/remote_usbhid.c
    4044
    4145include $(USPACE_PREFIX)/Makefile.common
  • uspace/lib/drv/generic/dev_iface.c

    rff4f073 r8d6c1f1  
    4141#include "remote_hw_res.h"
    4242#include "remote_char_dev.h"
     43#include "remote_usb.h"
     44#include "remote_usbhc.h"
     45#include "remote_usbhid.h"
     46#include "remote_pci.h"
     47
     48#include <stdio.h>
    4349
    4450static iface_dipatch_table_t remote_ifaces = {
    4551        .ifaces = {
    4652                &remote_hw_res_iface,
    47                 &remote_char_dev_iface
     53                &remote_char_dev_iface,
     54                &remote_pci_iface,
     55                &remote_usb_iface,
     56                &remote_usbhc_iface,
     57                &remote_usbhid_iface
    4858        }
    4959};
     
    5262{
    5363        assert(is_valid_iface_idx(idx));
     64       
    5465        return remote_ifaces.ifaces[idx];
    5566}
  • uspace/lib/drv/generic/driver.c

    rff4f073 r8d6c1f1  
    405405                                /* The interface has not such method */
    406406                                printf("%s: driver_connection_gen error - "
    407                                     "invalid interface method.", driver->name);
     407                                    "invalid interface method "
     408                                    "(index %" PRIun ").\n",
     409                                    driver->name, iface_method_idx);
    408410                                async_answer_0(callid, ENOTSUP);
    409411                                break;
  • uspace/srv/devman/main.c

    rff4f073 r8d6c1f1  
    515515}
    516516
     517/** Find device path by its handle. */
     518static void devman_get_device_path_by_handle(ipc_callid_t iid,
     519    ipc_call_t *icall)
     520{
     521        devman_handle_t handle = IPC_GET_ARG1(*icall);
     522
     523        fun_node_t *fun = find_fun_node(&device_tree, handle);
     524        if (fun == NULL) {
     525                async_answer_0(iid, ENOMEM);
     526                return;
     527        }
     528
     529        ipc_callid_t data_callid;
     530        size_t data_len;
     531        if (!async_data_read_receive(&data_callid, &data_len)) {
     532                async_answer_0(iid, EINVAL);
     533                return;
     534        }
     535
     536        void *buffer = malloc(data_len);
     537        if (buffer == NULL) {
     538                async_answer_0(data_callid, ENOMEM);
     539                async_answer_0(iid, ENOMEM);
     540                return;
     541        }
     542
     543        size_t sent_length = str_size(fun->pathname);
     544        if (sent_length > data_len) {
     545                sent_length = data_len;
     546        }
     547
     548        async_data_read_finalize(data_callid, fun->pathname, sent_length);
     549        async_answer_0(iid, EOK);
     550
     551        free(buffer);
     552}
     553
    517554
    518555/** Function for handling connections from a client to the device manager. */
     
    537574                        devman_function_get_handle_by_class(callid, &call);
    538575                        break;
     576                case DEVMAN_DEVICE_GET_DEVICE_PATH:
     577                        devman_get_device_path_by_handle(callid, &call);
     578                        break;
    539579                default:
    540580                        async_answer_0(callid, ENOENT);
     
    595635        if (driver == NULL) {
    596636                log_msg(LVL_ERROR, "IPC forwarding refused - " \
    597                     "the device %" PRIun " is not in usable state.", handle);
     637                    "the device %" PRIun "(%s) is not in usable state.",
     638                    handle, dev->pfun->pathname);
    598639                async_answer_0(iid, ENOENT);
    599640                return;
  • uspace/srv/hid/console/console.c

    rff4f073 r8d6c1f1  
    4141#include <ipc/ns.h>
    4242#include <errno.h>
     43#include <str_error.h>
    4344#include <ipc/console.h>
    4445#include <unistd.h>
     
    5657#include <io/style.h>
    5758#include <io/screenbuffer.h>
     59#include <inttypes.h>
    5860
    5961#include "console.h"
     
    6466#define NAME       "console"
    6567#define NAMESPACE  "term"
     68/** Interval for checking for new keyboard (1/4s). */
     69#define HOTPLUG_WATCH_INTERVAL (1000 * 250)
     70
     71/* Kernel defines 32 but does not export it. */
     72#define MAX_IPC_OUTGOING_PHONES 128
     73/** To allow proper phone closing. */
     74static ipc_callid_t driver_phones[MAX_IPC_OUTGOING_PHONES] = { 0 };
    6675
    6776/** Phone to the keyboard driver. */
     
    8897} console_t;
    8998
     99
     100
    90101/** Array of data for virtual consoles */
    91102static console_t consoles[CONSOLE_COUNT];
     
    317328static void change_console(console_t *cons)
    318329{
    319         if (cons == active_console)
     330        if (cons == active_console) {
    320331                return;
     332        }
    321333       
    322334        fb_pending_flush();
     
    397409}
    398410
     411static void close_driver_phone(ipc_callid_t hash)
     412{
     413        int i;
     414        for (i = 0; i < MAX_IPC_OUTGOING_PHONES; i++) {
     415                if (driver_phones[i] == hash) {
     416                        printf("Device %" PRIxn " gone.\n", hash);
     417                        driver_phones[i] = 0;
     418                        async_hangup(i);
     419                        return;
     420                }
     421        }
     422}
     423
    399424/** Handler for keyboard */
    400425static void keyboard_events(ipc_callid_t iid, ipc_call_t *icall)
     
    411436                case IPC_M_PHONE_HUNGUP:
    412437                        /* TODO: Handle hangup */
     438                        close_driver_phone(iid);
    413439                        return;
    414440                case KBD_EVENT:
     
    454480                case IPC_M_PHONE_HUNGUP:
    455481                        /* TODO: Handle hangup */
     482                        close_driver_phone(iid);
    456483                        return;
    457484                case MEVENT_BUTTON:
    458485                        if (IPC_GET_ARG1(call) == 1) {
    459486                                int newcon = gcons_mouse_btn((bool) IPC_GET_ARG2(call));
    460                                 if (newcon != -1)
     487                                if (newcon != -1) {
    461488                                        change_console(&consoles[newcon]);
     489                                }
    462490                        }
    463491                        retval = 0;
     
    710738}
    711739
     740static int async_connect_to_me_hack(int phone, sysarg_t arg1, sysarg_t arg2,
     741sysarg_t arg3, async_client_conn_t client_receiver, ipc_callid_t *hash)
     742{
     743        sysarg_t task_hash;
     744        sysarg_t phone_hash;
     745        int rc = async_req_3_5(phone, IPC_M_CONNECT_TO_ME, arg1, arg2, arg3,
     746            NULL, NULL, NULL, &task_hash, &phone_hash);
     747        if (rc != EOK)
     748                return rc;
     749
     750        if (client_receiver != NULL)
     751                async_new_connection(task_hash, phone_hash, phone_hash, NULL,
     752                    client_receiver);
     753
     754        if (hash != NULL) {
     755                *hash = phone_hash;
     756        }
     757
     758        return EOK;
     759}
     760
     761static int connect_keyboard_or_mouse(const char *devname,
     762    async_client_conn_t handler, const char *path)
     763{
     764        int fd = open(path, O_RDONLY);
     765        if (fd < 0) {
     766                return fd;
     767        }
     768       
     769        int phone = fd_phone(fd);
     770        close(fd);
     771        if (phone < 0) {
     772                printf(NAME ": Failed to connect to input device\n");
     773                return phone;
     774        }
     775       
     776        ipc_callid_t hash;
     777        int rc = async_connect_to_me_hack(phone, SERVICE_CONSOLE, 0, phone,
     778            handler, &hash);
     779        if (rc != EOK) {
     780                async_hangup(phone);
     781                printf(NAME ": " \
     782                    "Failed to create callback from input device: %s.\n",
     783                    str_error(rc));
     784                return rc;
     785        }
     786       
     787        driver_phones[phone] = hash;
     788
     789        printf(NAME ": found %s \"%s\" (%" PRIxn ").\n", devname, path, hash);
     790
     791        return phone;
     792}
     793
     794static int connect_keyboard(const char *path)
     795{
     796        return connect_keyboard_or_mouse("keyboard", keyboard_events, path);
     797}
     798
     799static int connect_mouse(const char *path)
     800{
     801        return connect_keyboard_or_mouse("mouse", mouse_events, path);
     802}
     803
     804struct hid_class_info {
     805        char *classname;
     806        int (*connection_func)(const char *);
     807};
     808
     809/** Periodically check for new keyboards in /dev/class/.
     810 *
     811 * @param arg Class name.
     812 * @return This function should never exit.
     813 */
     814static int check_new_device_fibril(void *arg)
     815{
     816        struct hid_class_info *dev_info = arg;
     817
     818        size_t index = 1;
     819
     820        while (true) {
     821                async_usleep(HOTPLUG_WATCH_INTERVAL);
     822                char *path;
     823                int rc = asprintf(&path, "/dev/class/%s\\%zu",
     824                    dev_info->classname, index);
     825                if (rc < 0) {
     826                        continue;
     827                }
     828                rc = 0;
     829                rc = dev_info->connection_func(path);
     830                if (rc > 0) {
     831                        /* We do not allow unplug. */
     832                        index++;
     833                }
     834
     835                free(path);
     836        }
     837
     838        return EOK;
     839}
     840
     841
     842/** Start a fibril monitoring hot-plugged keyboards.
     843 */
     844static void check_new_devices_in_background(int (*connection_func)(const char *),
     845    const char *classname)
     846{
     847        struct hid_class_info *dev_info = malloc(sizeof(struct hid_class_info));
     848        if (dev_info == NULL) {
     849                printf(NAME ": " \
     850                    "out of memory, will not start hot-plug-watch fibril.\n");
     851                return;
     852        }
     853        int rc;
     854
     855        rc = asprintf(&dev_info->classname, "%s", classname);
     856        if (rc < 0) {
     857                printf(NAME ": failed to format classname: %s.\n",
     858                    str_error(rc));
     859                return;
     860        }
     861        dev_info->connection_func = connection_func;
     862
     863        fid_t fid = fibril_create(check_new_device_fibril, (void *)dev_info);
     864        if (!fid) {
     865                printf(NAME
     866                    ": failed to create hot-plug-watch fibril for %s.\n",
     867                    classname);
     868                return;
     869        }
     870        fibril_add_ready(fid);
     871}
     872
    712873static bool console_init(char *input)
    713874{
    714875        /* Connect to input device */
    715         int input_fd = open(input, O_RDONLY);
    716         if (input_fd < 0) {
    717                 printf(NAME ": Failed opening %s\n", input);
     876        kbd_phone = connect_keyboard(input);
     877        if (kbd_phone < 0) {
    718878                return false;
    719879        }
    720        
    721         kbd_phone = fd_phone(input_fd);
    722         if (kbd_phone < 0) {
    723                 printf(NAME ": Failed to connect to input device\n");
    724                 return false;
    725         }
    726        
    727         /* NB: The callback connection is slotted for removal */
    728         if (async_connect_to_me(kbd_phone, SERVICE_CONSOLE, 0, 0, keyboard_events)
    729             != 0) {
    730                 printf(NAME ": Failed to create callback from input device\n");
    731                 return false;
    732         }
    733        
    734         /* Connect to mouse device */
    735         mouse_phone = -1;
    736         int mouse_fd = open("/dev/hid_in/mouse", O_RDONLY);
    737        
    738         if (mouse_fd < 0) {
    739                 printf(NAME ": Notice - failed opening %s\n", "/dev/hid_in/mouse");
    740                 goto skip_mouse;
    741         }
    742        
    743         mouse_phone = fd_phone(mouse_fd);
     880
     881        mouse_phone = connect_mouse("/dev/hid_in/mouse");
    744882        if (mouse_phone < 0) {
    745                 printf(NAME ": Failed to connect to mouse device\n");
    746                 goto skip_mouse;
    747         }
    748        
    749         if (async_connect_to_me(mouse_phone, SERVICE_CONSOLE, 0, 0, mouse_events)
    750             != 0) {
    751                 printf(NAME ": Failed to create callback from mouse device\n");
    752                 mouse_phone = -1;
    753                 goto skip_mouse;
    754         }
    755        
    756 skip_mouse:
     883                printf(NAME ": Failed to connect to mouse device: %s.\n",
     884                    str_error(mouse_phone));
     885        }
    757886       
    758887        /* Connect to framebuffer driver */
     
    837966                printf(NAME ": Error registering kconsole notifications\n");
    838967       
     968        /* Start fibril for checking on hot-plugged keyboards. */
     969        check_new_devices_in_background(connect_keyboard, "keyboard");
     970        check_new_devices_in_background(connect_mouse, "mouse");
     971
    839972        return true;
    840973}
     
    856989        if (!console_init(argv[1]))
    857990                return -1;
    858        
     991
    859992        printf(NAME ": Accepting connections\n");
    860993        async_manager();
  • uspace/srv/hw/irc/apic/apic.c

    rff4f073 r8d6c1f1  
    8787                        async_answer_0(callid, EOK);
    8888                        break;
     89                case IPC_M_PHONE_HUNGUP:
     90                        /* The other side has hung up. */
     91                        async_answer_0(callid, EOK);
     92                        return;
    8993                default:
    9094                        async_answer_0(callid, EINVAL);
  • uspace/srv/hw/irc/i8259/i8259.c

    rff4f073 r8d6c1f1  
    121121                        async_answer_0(callid, EOK);
    122122                        break;
     123                case IPC_M_PHONE_HUNGUP:
     124                        /* The other side has hung up. */
     125                        async_answer_0(callid, EOK);
     126                        return;
    123127                default:
    124128                        async_answer_0(callid, EINVAL);
Note: See TracChangeset for help on using the changeset viewer.