Changeset 75732da in mainline for uspace


Ignore:
Timestamp:
2010-12-13T07:20:20Z (15 years ago)
Author:
Vojtech Horky <vojtechhorky@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
309dea52
Parents:
84439d7 (diff), 37f7cfe (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge development/ changes

Location:
uspace
Files:
29 added
2 deleted
65 edited
2 moved

Legend:

Unmodified
Added
Removed
  • uspace/Makefile

    r84439d7 r75732da  
    4949        app/trace \
    5050        app/top \
     51        app/usbinfo \
    5152        app/virtusbkbd \
    5253        app/netecho \
     
    8788        srv/net/net \
    8889        drv/root \
    89         drv/vhc
     90        drv/rootvirt \
     91        drv/test1 \
     92        drv/test2
    9093
    9194## Networking
     
    110113
    111114ifeq ($(UARCH),amd64)
    112 endif
    113 
    114 ifeq ($(UARCH),ia32)
    115         DIRS += drv/rootia32
     115        DIRS += drv/rootpc
    116116        DIRS += drv/pciintel
    117117        DIRS += drv/isa
     
    120120        DIRS += drv/usbhub
    121121        DIRS += drv/usbkbd
     122        DIRS += drv/vhc
     123endif
     124
     125ifeq ($(UARCH),ia32)
     126        DIRS += drv/rootpc
     127        DIRS += drv/pciintel
     128        DIRS += drv/isa
     129        DIRS += drv/ns8250
     130        DIRS += drv/uhci
     131        DIRS += drv/usbhub
     132        DIRS += drv/usbkbd
     133        DIRS += drv/vhc
    122134endif
    123135
  • uspace/app/netecho/print_error.c

    r84439d7 r75732da  
    164164        case EDESTADDRREQ:
    165165                fprintf(output, "Destination address required (%d) error", error_code);
    166         case TRY_AGAIN:
     166        case EAGAIN:
    167167                fprintf(output, "Try again (%d) error", error_code);
    168168        default:
  • uspace/app/tester/Makefile

    r84439d7 r75732da  
    3131BINARY = tester
    3232
     33LIBS += $(LIBUSB_PREFIX)/libusb.a
     34EXTRA_CFLAGS += -I$(LIBUSB_PREFIX)/include
     35
    3336SOURCES = \
    3437        tester.c \
     38        adt/usbaddrkeep.c \
    3539        thread/thread1.c \
    3640        print/print1.c \
  • uspace/app/tester/tester.c

    r84439d7 r75732da  
    6565#include "mm/malloc1.def"
    6666#include "hw/serial/serial1.def"
     67#include "adt/usbaddrkeep.def"
    6768        {NULL, NULL, NULL, false}
    6869};
  • uspace/app/tester/tester.h

    r84439d7 r75732da  
    8282extern const char *test_malloc1(void);
    8383extern const char *test_serial1(void);
     84extern const char *test_usbaddrkeep(void);
    8485
    8586extern test_t tests[];
  • uspace/app/virtusbkbd/Makefile

    r84439d7 r75732da  
    3333
    3434LIBS = $(LIBUSB_PREFIX)/libusb.a $(LIBUSBVIRT_PREFIX)/libusbvirt.a
    35 EXTRA_CFLAGS = -I$(LIBUSB_PREFIX)/include -I$(LIBUSBVIRT_PREFIX)/include
     35EXTRA_CFLAGS = -I$(LIBUSB_PREFIX)/include -I$(LIBUSBVIRT_PREFIX)/include -I$(LIBDRV_PREFIX)/include
    3636
    3737SOURCES = \
  • uspace/app/virtusbkbd/virtusbkbd.c

    r84439d7 r75732da  
    5555#include "stdreq.h"
    5656
    57 #define LOOPS 5
     57/** Pause between individual key-presses in seconds. */
     58#define KEY_PRESS_DELAY 2
    5859#define NAME "virt-usb-kbd"
    5960
     
    8384}
    8485
     86/** Compares current and last status of pressed keys.
     87 *
     88 * @warning Has side-efect - changes status_last field.
     89 *
     90 * @param status_now Status now.
     91 * @param status_last Last status.
     92 * @param len Size of status.
     93 * @return Whether they are the same.
     94 */
     95static bool keypress_check_with_last_request(uint8_t *status_now,
     96    uint8_t *status_last, size_t len)
     97{
     98        bool same = true;
     99        size_t i;
     100        for (i = 0; i < len; i++) {
     101                if (status_now[i] != status_last[i]) {
     102                        status_last[i] = status_now[i];
     103                        same = false;
     104                }
     105        }
     106        return same;
     107}
     108
    85109static int on_request_for_data(struct usbvirt_device *dev,
    86110    usb_endpoint_t endpoint, void *buffer, size_t size, size_t *actual_size)
    87111{
     112        static uint8_t last_data[2 + KB_MAX_KEYS_AT_ONCE];
     113
    88114        if (size < 2 + KB_MAX_KEYS_AT_ONCE) {
    89115                return EINVAL;
     
    101127        }
    102128       
     129        if (keypress_check_with_last_request(data, last_data,
     130            2 + KB_MAX_KEYS_AT_ONCE)) {
     131                *actual_size = 0;
     132                return EOK;
     133        }
     134
    103135        memcpy(buffer, &data, *actual_size);
    104136       
     
    153185        .ops = &keyboard_ops,
    154186        .descriptors = &descriptors,
     187        .lib_debug_level = 3,
     188        .lib_debug_enabled_tags = USBVIRT_DEBUGTAG_ALL,
    155189        .name = "keyboard"
    156190};
     
    178212        printf("\n");
    179213       
    180         fibril_sleep(1);
     214        fibril_sleep(KEY_PRESS_DELAY);
    181215}
    182216
     
    203237int main(int argc, char * argv[])
    204238{
    205         printf("Dump of report descriptor (%u bytes):\n", report_descriptor_size);
     239        printf("Dump of report descriptor (%zu bytes):\n", report_descriptor_size);
    206240        size_t i;
    207241        for (i = 0; i < report_descriptor_size; i++) {
     
    224258       
    225259        printf("%s: Simulating keyboard events...\n", NAME);
    226         kb_process_events(&status, keyboard_events, keyboard_events_count,
    227             on_keyboard_change);
     260        while (1) {
     261                kb_process_events(&status, keyboard_events, keyboard_events_count,
     262                        on_keyboard_change);
     263        }
    228264       
    229265        printf("%s: Terminating...\n", NAME);
  • uspace/drv/isa/isa.c

    r84439d7 r75732da  
    282282
    283283                printf(NAME ": added io range (addr=0x%x, size=0x%x) to "
    284                     "device %s\n", addr, len, dev->name);
     284                    "device %s\n", (unsigned int) addr, (unsigned int) len,
     285                    dev->name);
    285286        }
    286287}
     
    489490static int isa_add_device(device_t *dev)
    490491{
    491         printf(NAME ": isa_add_device, device handle = %d\n", dev->handle);
     492        printf(NAME ": isa_add_device, device handle = %d\n",
     493            (int) dev->handle);
    492494
    493495        /* Add child devices. */
  • uspace/drv/ns8250/ns8250.c

    r84439d7 r75732da  
    274274       
    275275        /* Gain control over port's registers. */
    276         if (pio_enable((void *) data->io_addr, REG_COUNT,
     276        if (pio_enable((void *)(uintptr_t) data->io_addr, REG_COUNT,
    277277            (void **) &data->port)) {
    278278                printf(NAME ": error - cannot gain the port %#" PRIx32 " for device "
     
    727727{
    728728        printf(NAME ": ns8250_add_device %s (handle = %d)\n",
    729             dev->name, dev->handle);
     729            dev->name, (int) dev->handle);
    730730       
    731731        int res = ns8250_dev_initialize(dev);
  • uspace/drv/pciintel/pci.c

    r84439d7 r75732da  
    324324                printf(NAME ": device %s : ", dev->name);
    325325                printf("address = %" PRIx64, range_addr);
    326                 printf(", size = %x\n", range_size);
     326                printf(", size = %x\n", (unsigned int) range_size);
    327327        }
    328328       
     
    489489            (uint32_t) hw_resources.resources[0].res.io_range.address;
    490490       
    491         if (pio_enable((void *)bus_data->conf_io_addr, 8,
     491        if (pio_enable((void *)(uintptr_t)bus_data->conf_io_addr, 8,
    492492            &bus_data->conf_addr_port)) {
    493493                printf(NAME ": failed to enable configuration ports.\n");
  • uspace/drv/root/root.c

    r84439d7 r75732da  
    11/*
    22 * Copyright (c) 2010 Lenka Trochtova
     3 * Copyright (c) 2010 Vojtech Horky
    34 * All rights reserved.
    45 *
     
    5354#define NAME "root"
    5455
     56#define PLATFORM_DEVICE_NAME "hw"
     57#define PLATFORM_DEVICE_MATCH_ID STRING(UARCH)
     58#define PLATFORM_DEVICE_MATCH_SCORE 100
     59
     60#define VIRTUAL_DEVICE_NAME "virt"
     61#define VIRTUAL_DEVICE_MATCH_ID "rootvirt"
     62#define VIRTUAL_DEVICE_MATCH_SCORE 100
     63
    5564static int root_add_device(device_t *dev);
    5665
     
    6675};
    6776
     77/** Create the device which represents the root of virtual device tree.
     78 *
     79 * @param parent Parent of the newly created device.
     80 * @return Error code.
     81 */
     82static int add_virtual_root_child(device_t *parent)
     83{
     84        printf(NAME ": adding new child for virtual devices.\n");
     85        printf(NAME ":   device node is `%s' (%d %s)\n", VIRTUAL_DEVICE_NAME,
     86            VIRTUAL_DEVICE_MATCH_SCORE, VIRTUAL_DEVICE_MATCH_ID);
     87
     88        int res = child_device_register_wrapper(parent, VIRTUAL_DEVICE_NAME,
     89            VIRTUAL_DEVICE_MATCH_ID, VIRTUAL_DEVICE_MATCH_SCORE,
     90            NULL);
     91
     92        return res;
     93}
     94
    6895/** Create the device which represents the root of HW device tree.
    6996 *
     
    74101{
    75102        printf(NAME ": adding new child for platform device.\n");
     103        printf(NAME ":   device node is `%s' (%d %s)\n", PLATFORM_DEVICE_NAME,
     104            PLATFORM_DEVICE_MATCH_SCORE, PLATFORM_DEVICE_MATCH_ID);
    76105       
    77         int res = EOK;
    78         device_t *platform = NULL;
    79         match_id_t *match_id = NULL;
    80        
    81         /* Create new device. */
    82         platform = create_device();
    83         if (NULL == platform) {
    84                 res = ENOMEM;
    85                 goto failure;
    86         }       
    87        
    88         platform->name = "hw";
    89         printf(NAME ": the new device's name is %s.\n", platform->name);
    90        
    91         /* Initialize match id list. */
    92         match_id = create_match_id();
    93         if (NULL == match_id) {
    94                 res = ENOMEM;
    95                 goto failure;
    96         }
    97        
    98         /* TODO - replace this with some better solution (sysinfo ?) */
    99         match_id->id = STRING(UARCH);
    100         match_id->score = 100;
    101         add_match_id(&platform->match_ids, match_id);
    102        
    103         /* Register child device. */
    104         res = child_device_register(platform, parent);
    105         if (EOK != res)
    106                 goto failure;
    107        
     106        int res = child_device_register_wrapper(parent, PLATFORM_DEVICE_NAME,
     107            PLATFORM_DEVICE_MATCH_ID, PLATFORM_DEVICE_MATCH_SCORE,
     108            NULL);
     109
    108110        return res;
    109        
    110 failure:
    111         if (NULL != match_id)
    112                 match_id->id = NULL;
    113        
    114         if (NULL != platform) {
    115                 platform->name = NULL;
    116                 delete_device(platform);
    117         }
    118        
    119         return res;
    120 }
    121 
    122 /** Create virtual USB host controller device.
    123  * Note that the virtual HC is actually device and driver in one
    124  * task.
    125  *
    126  * @param parent Parent device.
    127  * @return Error code.
    128  */
    129 static int add_virtual_usb_host_controller(device_t *parent)
    130 {
    131         printf(NAME ": adding virtual host contoller.\n");
    132 
    133         int rc;
    134         device_t *vhc = NULL;
    135         match_id_t *match_id = NULL;
    136 
    137         vhc = create_device();
    138         if (vhc == NULL) {
    139                 rc = ENOMEM;
    140                 goto failure;
    141         }
    142 
    143         vhc->name = "vhc";
    144         printf(NAME ": the new device's name is %s.\n", vhc->name);
    145 
    146         /* Initialize match id list. */
    147         match_id = create_match_id();
    148         if (match_id == NULL) {
    149                 rc = ENOMEM;
    150                 goto failure;
    151         }
    152 
    153         match_id->id = "usb&hc=vhc";
    154         match_id->score = 100;
    155         add_match_id(&vhc->match_ids, match_id);
    156 
    157         /* Register child device. */
    158         rc = child_device_register(vhc, parent);
    159         if (rc != EOK)
    160                 goto failure;
    161 
    162         return EOK;
    163 
    164 failure:
    165         if (match_id != NULL)
    166                 match_id->id = NULL;
    167 
    168         if (vhc != NULL) {
    169                 vhc->name = NULL;
    170                 delete_device(vhc);
    171         }
    172 
    173         return rc;
    174111}
    175112
     
    184121            dev->handle);
    185122       
     123        /*
     124         * Register virtual devices root.
     125         * We ignore error occurrence because virtual devices shall not be
     126         * vital for the system.
     127         */
     128        add_virtual_root_child(dev);
     129
    186130        /* Register root device's children. */
    187131        int res = add_platform_child(dev);
     
    189133                printf(NAME ": failed to add child device for platform.\n");
    190134       
    191         /* Register virtual USB host controller. */
    192         int rc = add_virtual_usb_host_controller(dev);
    193         if (EOK != rc) {
    194                 printf(NAME ": failed to add child device - virtual USB HC.\n");
    195         }
    196 
    197135        return res;
    198136}
  • uspace/drv/rootpc/Makefile

    r84439d7 r75732da  
    3030LIBS = $(LIBDRV_PREFIX)/libdrv.a
    3131EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include
    32 BINARY = rootia32
     32BINARY = rootpc
    3333
    3434SOURCES = \
    35         rootia32.c
     35        rootpc.c
    3636
    3737include $(USPACE_PREFIX)/Makefile.common
  • uspace/drv/rootpc/rootpc.c

    r84439d7 r75732da  
    2828
    2929/**
    30  * @defgroup root_ia32 Root HW device driver for ia32 platform.
    31  * @brief HelenOS root HW device driver for ia32 platform.
     30 * @defgroup root_pc Root HW device driver for ia32 and amd64 platform.
     31 * @brief HelenOS root HW device driver for ia32 and amd64 platform.
    3232 * @{
    3333 */
     
    5353#include <device/hw_res.h>
    5454
    55 #define NAME "rootia32"
    56 
    57 typedef struct rootia32_child_dev_data {
     55#define NAME "rootpc"
     56
     57typedef struct rootpc_child_dev_data {
    5858        hw_resource_list_t hw_resources;
    59 } rootia32_child_dev_data_t;
    60 
    61 static int rootia32_add_device(device_t *dev);
    62 static void root_ia32_init(void);
     59} rootpc_child_dev_data_t;
     60
     61static int rootpc_add_device(device_t *dev);
     62static void root_pc_init(void);
    6363
    6464/** The root device driver's standard operations. */
    65 static driver_ops_t rootia32_ops = {
    66         .add_device = &rootia32_add_device
     65static driver_ops_t rootpc_ops = {
     66        .add_device = &rootpc_add_device
    6767};
    6868
    6969/** The root device driver structure. */
    70 static driver_t rootia32_driver = {
     70static driver_t rootpc_driver = {
    7171        .name = NAME,
    72         .driver_ops = &rootia32_ops
     72        .driver_ops = &rootpc_ops
    7373};
    7474
     
    8282};
    8383
    84 static rootia32_child_dev_data_t pci_data = {
     84static rootpc_child_dev_data_t pci_data = {
    8585        .hw_resources = {
    8686                1,
     
    8989};
    9090
    91 static hw_resource_list_t *rootia32_get_child_resources(device_t *dev)
    92 {
    93         rootia32_child_dev_data_t *data;
    94        
    95         data = (rootia32_child_dev_data_t *) dev->driver_data;
     91static hw_resource_list_t *rootpc_get_child_resources(device_t *dev)
     92{
     93        rootpc_child_dev_data_t *data;
     94       
     95        data = (rootpc_child_dev_data_t *) dev->driver_data;
    9696        if (NULL == data)
    9797                return NULL;
     
    100100}
    101101
    102 static bool rootia32_enable_child_interrupt(device_t *dev)
     102static bool rootpc_enable_child_interrupt(device_t *dev)
    103103{
    104104        /* TODO */
     
    108108
    109109static resource_iface_t child_res_iface = {
    110         &rootia32_get_child_resources,
    111         &rootia32_enable_child_interrupt
    112 };
    113 
    114 /* Initialized in root_ia32_init() function. */
    115 static device_ops_t rootia32_child_ops;
     110        &rootpc_get_child_resources,
     111        &rootpc_enable_child_interrupt
     112};
     113
     114/* Initialized in root_pc_init() function. */
     115static device_ops_t rootpc_child_ops;
    116116
    117117static bool
    118 rootia32_add_child(device_t *parent, const char *name, const char *str_match_id,
    119     rootia32_child_dev_data_t *drv_data)
     118rootpc_add_child(device_t *parent, const char *name, const char *str_match_id,
     119    rootpc_child_dev_data_t *drv_data)
    120120{
    121121        printf(NAME ": adding new child device '%s'.\n", name);
     
    142142       
    143143        /* Set provided operations to the device. */
    144         child->ops = &rootia32_child_ops;
     144        child->ops = &rootpc_child_ops;
    145145       
    146146        /* Register child device. */
     
    164164}
    165165
    166 static bool rootia32_add_children(device_t *dev)
    167 {
    168         return rootia32_add_child(dev, "pci0", "intel_pci", &pci_data);
     166static bool rootpc_add_children(device_t *dev)
     167{
     168        return rootpc_add_child(dev, "pci0", "intel_pci", &pci_data);
    169169}
    170170
     
    175175 * @return              Zero on success, negative error number otherwise.
    176176 */
    177 static int rootia32_add_device(device_t *dev)
    178 {
    179         printf(NAME ": rootia32_add_device, device handle = %d\n", dev->handle);
     177static int rootpc_add_device(device_t *dev)
     178{
     179        printf(NAME ": rootpc_add_device, device handle = %d\n",
     180            (int)dev->handle);
    180181       
    181182        /* Register child devices. */
    182         if (!rootia32_add_children(dev)) {
     183        if (!rootpc_add_children(dev)) {
    183184                printf(NAME ": failed to add child devices for platform "
    184185                    "ia32.\n");
     
    188189}
    189190
    190 static void root_ia32_init(void)
    191 {
    192         rootia32_child_ops.interfaces[HW_RES_DEV_IFACE] = &child_res_iface;
     191static void root_pc_init(void)
     192{
     193        rootpc_child_ops.interfaces[HW_RES_DEV_IFACE] = &child_res_iface;
    193194}
    194195
    195196int main(int argc, char *argv[])
    196197{
    197         printf(NAME ": HelenOS rootia32 device driver\n");
    198         root_ia32_init();
    199         return driver_main(&rootia32_driver);
     198        printf(NAME ": HelenOS rootpc device driver\n");
     199        root_pc_init();
     200        return driver_main(&rootpc_driver);
    200201}
    201202
  • uspace/drv/uhci/main.c

    r84439d7 r75732da  
    2727 */
    2828#include <usb/hcdhubd.h>
     29#include <usb/debug.h>
    2930#include <errno.h>
     31#include <driver.h>
    3032#include "uhci.h"
    3133
     
    3638static int uhci_add_device(device_t *device)
    3739{
     40        usb_dprintf(NAME, 1, "uhci_add_device() called\n");
    3841        device->ops = &uhci_ops;
    3942
     
    4144         * We need to announce the presence of our root hub.
    4245         */
     46        usb_dprintf(NAME, 2, "adding root hub\n");
    4347        usb_hcd_add_root_hub(device);
    4448
     
    6165         */
    6266        sleep(5);
     67        usb_dprintf_enable(NAME, 5);
    6368
    6469        return driver_main(&uhci_driver);
  • uspace/drv/uhci/transfers.c

    r84439d7 r75732da  
    3636    usbhc_iface_transfer_out_callback_t callback, void *arg)
    3737{
    38         printf(NAME ": transfer OUT [%d.%d (%s); %u]\n",
     38        printf(NAME ": transfer OUT [%d.%d (%s); %zu]\n",
    3939            target.address, target.endpoint,
    4040            usb_str_transfer_type(transfer_type),
     
    4949    usbhc_iface_transfer_out_callback_t callback, void *arg)
    5050{
    51         printf(NAME ": transfer SETUP [%d.%d (%s); %u]\n",
     51        printf(NAME ": transfer SETUP [%d.%d (%s); %zu]\n",
    5252            target.address, target.endpoint,
    5353            usb_str_transfer_type(transfer_type),
     
    6262    usbhc_iface_transfer_in_callback_t callback, void *arg)
    6363{
    64         printf(NAME ": transfer IN [%d.%d (%s); %u]\n",
     64        printf(NAME ": transfer IN [%d.%d (%s); %zu]\n",
    6565            target.address, target.endpoint,
    6666            usb_str_transfer_type(transfer_type),
  • uspace/drv/usbhub/main.c

    r84439d7 r75732da  
    2626 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    2727 */
    28 #include <usb/usbdrv.h>
     28
    2929#include <driver.h>
    3030#include <errno.h>
     31#include <async.h>
     32
     33#include <usb/usbdrv.h>
    3134#include "usbhub.h"
     35#include "usbhub_private.h"
     36
     37
     38usb_general_list_t usb_hub_list;
    3239
    3340static driver_ops_t hub_driver_ops = {
     
    4047};
    4148
     49int usb_hub_control_loop(void * noparam){
     50        while(true){
     51                usb_hub_check_hub_changes();
     52                async_usleep(1000 * 1000);
     53        }
     54        return 0;
     55}
     56
     57
    4258int main(int argc, char *argv[])
    4359{
     60        usb_lst_init(&usb_hub_list);
     61        fid_t fid = fibril_create(usb_hub_control_loop, NULL);
     62        if (fid == 0) {
     63                printf("%s: failed to start fibril for HUB devices\n", NAME);
     64                return ENOMEM;
     65        }
     66        fibril_add_ready(fid);
     67
    4468        return driver_main(&hub_driver);
    4569}
  • uspace/drv/usbhub/usbhub.h

    r84439d7 r75732da  
    3838#define NAME "usbhub"
    3939
    40 int usb_add_hub_device(device_t *);
     40#include "usb/hcdhubd.h"
     41
     42/** basic information about device attached to hub */
     43typedef struct{
     44        usb_address_t address;
     45        devman_handle_t devman_handle;
     46}usb_hub_attached_device_t;
     47
     48/** Information about attached hub. */
     49typedef struct {
     50        /** Number of ports. */
     51        int port_count;
     52        /** attached device handles */
     53        usb_hub_attached_device_t * attached_devs;
     54        /** General usb device info. */
     55        usb_hcd_attached_device_info_t * usb_device;
     56        /** General device info*/
     57        device_t * device;
     58
     59} usb_hub_info_t;
     60
     61/**
     62 * function running the hub-controlling loop.
     63 * @param noparam fundtion does not need any parameters
     64 */
     65int usb_hub_control_loop(void * noparam);
     66
     67/** Callback when new hub device is detected.
     68 *
     69 * @param dev New device.
     70 * @return Error code.
     71 */
     72int usb_add_hub_device(device_t *dev);
     73
     74/**
     75 * check changes on all registered hubs
     76 */
     77void usb_hub_check_hub_changes(void);
     78
     79
     80//int usb_add_hub_device(device_t *);
     81
     82
    4183
    4284#endif
  • uspace/drv/usbhub/usbhub.ma

    r84439d7 r75732da  
    1110 usb&hub
     210 usb&class=hub
  • uspace/drv/usbhub/utils.c

    r84439d7 r75732da  
    3434 */
    3535#include <driver.h>
    36 #include <usb/devreq.h>
     36#include <bool.h>
     37#include <errno.h>
     38
    3739#include <usbhc_iface.h>
    3840#include <usb/usbdrv.h>
    3941#include <usb/descriptor.h>
    40 #include <driver.h>
    41 #include <bool.h>
    42 #include <errno.h>
     42#include <usb/devreq.h>
    4343#include <usb/classes/hub.h>
     44
    4445#include "usbhub.h"
    45 
    46 static void check_hub_changes(void);
     46#include "usbhub_private.h"
     47#include "port_status.h"
     48
    4749
    4850size_t USB_HUB_MAX_DESCRIPTOR_SIZE = 71;
     
    5355//
    5456//*********************************************
     57
     58//hub descriptor utils
    5559
    5660void * usb_serialize_hub_descriptor(usb_hub_descriptor_t * descriptor) {
     
    8488usb_hub_descriptor_t * usb_deserialize_hub_desriptor(void * serialized_descriptor) {
    8589        uint8_t * sdescriptor = (uint8_t*) serialized_descriptor;
    86         if (sdescriptor[1] != USB_DESCTYPE_HUB) return NULL;
    87         usb_hub_descriptor_t * result = (usb_hub_descriptor_t*) malloc(sizeof (usb_hub_descriptor_t));
    88         //uint8_t size = sdescriptor[0];
     90
     91        if (sdescriptor[1] != USB_DESCTYPE_HUB) {
     92                printf("[usb_hub] wrong descriptor %x\n",sdescriptor[1]);
     93                return NULL;
     94        }
     95
     96        usb_hub_descriptor_t * result = usb_new(usb_hub_descriptor_t);
     97       
     98
    8999        result->ports_count = sdescriptor[2];
    90100        /// @fixme handling of endianness??
     
    94104        size_t var_size = result->ports_count / 8 + ((result->ports_count % 8 > 0) ? 1 : 0);
    95105        result->devices_removable = (uint8_t*) malloc(var_size);
    96 
     106        //printf("[usb_hub] getting removable devices data \n");
    97107        size_t i;
    98108        for (i = 0; i < var_size; ++i) {
     
    102112}
    103113
     114//control transactions
     115
     116int usb_drv_sync_control_read(
     117                int phone, usb_target_t target,
     118                usb_device_request_setup_packet_t * request,
     119                void * rcvd_buffer, size_t rcvd_size, size_t * actual_size
     120                ) {
     121        usb_handle_t handle;
     122        int opResult;
     123        //setup
     124        opResult = usb_drv_async_control_read_setup(phone, target,
     125                        request, sizeof (usb_device_request_setup_packet_t),
     126                        &handle);
     127        if (opResult != EOK) {
     128                return opResult;
     129        }
     130        opResult = usb_drv_async_wait_for(handle);
     131        if (opResult != EOK) {
     132                return opResult;
     133        }
     134        //read
     135        opResult = usb_drv_async_control_read_data(phone, target,
     136                        rcvd_buffer, rcvd_size, actual_size,
     137                        &handle);
     138        if (opResult != EOK) {
     139                return opResult;
     140        }
     141        opResult = usb_drv_async_wait_for(handle);
     142        if (opResult != EOK) {
     143                return opResult;
     144        }
     145        //finalize
     146        opResult = usb_drv_async_control_read_status(phone, target,
     147                        &handle);
     148        if (opResult != EOK) {
     149                return opResult;
     150        }
     151        opResult = usb_drv_async_wait_for(handle);
     152        if (opResult != EOK) {
     153                return opResult;
     154        }
     155        return EOK;
     156}
     157
     158int usb_drv_sync_control_write(
     159                int phone, usb_target_t target,
     160                usb_device_request_setup_packet_t * request,
     161                void * sent_buffer, size_t sent_size
     162                ) {
     163        usb_handle_t handle;
     164        int opResult;
     165        //setup
     166        opResult = usb_drv_async_control_write_setup(phone, target,
     167                        request, sizeof (usb_device_request_setup_packet_t),
     168                        &handle);
     169        if (opResult != EOK) {
     170                return opResult;
     171        }
     172        opResult = usb_drv_async_wait_for(handle);
     173        if (opResult != EOK) {
     174                return opResult;
     175        }
     176        //write
     177        opResult = usb_drv_async_control_write_data(phone, target,
     178                        sent_buffer, sent_size,
     179                        &handle);
     180        if (opResult != EOK) {
     181                return opResult;
     182        }
     183        opResult = usb_drv_async_wait_for(handle);
     184        if (opResult != EOK) {
     185                return opResult;
     186        }
     187        //finalize
     188        opResult = usb_drv_async_control_write_status(phone, target,
     189                        &handle);
     190        if (opResult != EOK) {
     191                return opResult;
     192        }
     193        opResult = usb_drv_async_wait_for(handle);
     194        if (opResult != EOK) {
     195                return opResult;
     196        }
     197        return EOK;
     198}
     199
     200//list implementation
     201
     202usb_general_list_t * usb_lst_create(void) {
     203        usb_general_list_t* result = usb_new(usb_general_list_t);
     204        usb_lst_init(result);
     205        return result;
     206}
     207
     208void usb_lst_init(usb_general_list_t * lst) {
     209        lst->prev = lst;
     210        lst->next = lst;
     211        lst->data = NULL;
     212}
     213
     214void usb_lst_prepend(usb_general_list_t* item, void* data) {
     215        usb_general_list_t* appended = usb_new(usb_general_list_t);
     216        appended->data = data;
     217        appended->next = item;
     218        appended->prev = item->prev;
     219        item->prev->next = appended;
     220        item->prev = appended;
     221}
     222
     223void usb_lst_append(usb_general_list_t* item, void* data) {
     224        usb_general_list_t* appended = usb_new(usb_general_list_t);
     225        appended->data = data;
     226        appended->next = item->next;
     227        appended->prev = item;
     228        item->next->prev = appended;
     229        item->next = appended;
     230}
     231
     232void usb_lst_remove(usb_general_list_t* item) {
     233        item->next->prev = item->prev;
     234        item->prev->next = item->next;
     235}
     236
     237static void usb_hub_test_port_status(void) {
     238        printf("[usb_hub] -------------port status test---------\n");
     239        usb_port_status_t status = 0;
     240
     241        //printf("original status %d (should be 0)\n",(uint32_t)status);
     242        usb_port_set_bit(&status, 1, 1);
     243        //printf("%d =?= 2\n",(uint32_t)status);
     244        if (status != 2) {
     245                printf("[usb_port_status] test failed: wrong set of bit 1\n");
     246                return;
     247        }
     248        usb_port_set_bit(&status, 3, 1);
     249        if (status != 10) {
     250                printf("[usb_port_status] test failed: wrong set of bit 3\n");
     251                return;
     252        }
     253
     254        usb_port_set_bit(&status, 15, 1);
     255        if (status != 10 + (1 << 15)) {
     256                printf("[usb_port_status] test failed: wrong set of bit 15\n");
     257                return;
     258        }
     259        usb_port_set_bit(&status, 1, 0);
     260        if (status != 8 + (1 << 15)) {
     261                printf("[usb_port_status] test failed: wrong unset of bit 1\n");
     262                return;
     263        }
     264        int i;
     265        for (i = 0; i < 32; ++i) {
     266                if (i == 3 || i == 15) {
     267                        if (!usb_port_get_bit(&status, i)) {
     268                                printf("[usb_port_status] test failed: wrong bit at %d\n", i);
     269                        }
     270                } else {
     271                        if (usb_port_get_bit(&status, i)) {
     272                                printf("[usb_port_status] test failed: wrong bit at %d\n", i);
     273                        }
     274                }
     275        }
     276
     277        printf("test ok\n");
     278
     279
     280        //printf("%d =?= 10\n",(uint32_t)status);
     281
     282        //printf("this should be 0: %d \n",usb_port_get_bit(&status,0));
     283        //printf("this should be 1: %d \n",usb_port_get_bit(&status,1));
     284        //printf("this should be 0: %d \n",usb_port_get_bit(&status,2));
     285        //printf("this should be 1: %d \n",usb_port_get_bit(&status,3));
     286        //printf("this should be 0: %d \n",usb_port_get_bit(&status,4));
     287
     288
     289
     290
     291}
    104292
    105293//*********************************************
    106294//
    107 //  hub driver code
     295//  hub driver code, initialization
    108296//
    109297//*********************************************
    110298
    111 usb_hcd_hub_info_t * usb_create_hub_info(device_t * device) {
    112         usb_hcd_hub_info_t* result = (usb_hcd_hub_info_t*) malloc(sizeof (usb_hcd_hub_info_t));
     299usb_hub_info_t * usb_create_hub_info(device_t * device, int hc) {
     300        usb_hub_info_t* result = usb_new(usb_hub_info_t);
     301        //result->device = device;
     302        result->port_count = -1;
     303        /// \TODO is this correct? is the device stored?
     304        result->device = device;
     305
     306
     307        //printf("[usb_hub] phone to hc = %d\n", hc);
     308        if (hc < 0) {
     309                return result;
     310        }
     311        //get some hub info
     312        usb_address_t addr = usb_drv_get_my_address(hc, device);
     313        printf("[usb_hub] addres of newly created hub = %d\n", addr);
     314        /*if(addr<0){
     315                //return result;
     316               
     317        }*/
     318
     319        result->usb_device = usb_new(usb_hcd_attached_device_info_t);
     320        result->usb_device->address = addr;
     321
     322        // get hub descriptor
     323        usb_target_t target;
     324        target.address = addr;
     325        target.endpoint = 0;
     326        usb_device_request_setup_packet_t request;
     327        //printf("[usb_hub] creating descriptor request\n");
     328        usb_hub_set_descriptor_request(&request);
     329
     330        //printf("[usb_hub] creating serialized descriptor\n");
     331        void * serialized_descriptor = malloc(USB_HUB_MAX_DESCRIPTOR_SIZE);
     332        usb_hub_descriptor_t * descriptor;
     333        size_t received_size;
     334        int opResult;
     335        //printf("[usb_hub] starting control transaction\n");
     336        opResult = usb_drv_sync_control_read(
     337                        hc, target, &request, serialized_descriptor,
     338                        USB_HUB_MAX_DESCRIPTOR_SIZE, &received_size);
     339        if (opResult != EOK) {
     340                printf("[usb_hub] failed when receiving hub descriptor, badcode = %d\n",opResult);
     341                ///\TODO memory leak will occur here!
     342                return result;
     343        }
     344        //printf("[usb_hub] deserializing descriptor\n");
     345        descriptor = usb_deserialize_hub_desriptor(serialized_descriptor);
     346        if(descriptor==NULL){
     347                printf("[usb_hub] could not deserialize descriptor \n");
     348                result->port_count = 1;///\TODO this code is only for debug!!!
     349                return result;
     350        }
     351        //printf("[usb_hub] setting port count to %d\n",descriptor->ports_count);
     352        result->port_count = descriptor->ports_count;
     353        result->attached_devs = (usb_hub_attached_device_t*)
     354            malloc((result->port_count+1) * sizeof(usb_hub_attached_device_t));
     355        int i;
     356        for(i=0;i<result->port_count+1;++i){
     357                result->attached_devs[i].devman_handle=0;
     358                result->attached_devs[i].address=0;
     359        }
     360        //printf("[usb_hub] freeing data\n");
     361        free(serialized_descriptor);
     362        free(descriptor->devices_removable);
     363        free(descriptor);
     364
     365        //finish
     366
     367        printf("[usb_hub] hub info created\n");
    113368
    114369        return result;
    115370}
    116371
    117 /** Callback when new hub device is detected.
    118  *
    119  * @param dev New device.
    120  * @return Error code.
    121  */
    122372int usb_add_hub_device(device_t *dev) {
    123373        printf(NAME ": add_hub_device(handle=%d)\n", (int) dev->handle);
    124 
    125         check_hub_changes();
     374        printf("[usb_hub] hub device\n");
    126375
    127376        /*
     
    132381
    133382        //create the hub structure
    134         usb_hcd_hub_info_t * hub_info = usb_create_hub_info(dev);
    135         (void)hub_info;
     383        //get hc connection
     384        /// \TODO correct params
     385        int hc = usb_drv_hc_connect(dev, 0);
     386
     387        usb_hub_info_t * hub_info = usb_create_hub_info(dev, hc);
     388        int port;
     389        int opResult;
     390        usb_device_request_setup_packet_t request;
     391        usb_target_t target;
     392        target.address = hub_info->usb_device->address;
     393        target.endpoint = 0;
     394
     395        //get configuration descriptor
     396        // this is not fully correct - there are more configurations
     397        // and all should be checked
     398        usb_standard_device_descriptor_t std_descriptor;
     399        opResult = usb_drv_req_get_device_descriptor(hc, target.address,
     400    &std_descriptor);
     401        if(opResult!=EOK){
     402                printf("[usb_hub] could not get device descriptor, %d\n",opResult);
     403                return 1;///\TODO some proper error code needed
     404        }
     405        printf("[usb_hub] hub has %d configurations\n",std_descriptor.configuration_count);
     406        if(std_descriptor.configuration_count<1){
     407                printf("[usb_hub] THERE ARE NO CONFIGURATIONS AVAILABLE\n");
     408        }
     409        usb_standard_configuration_descriptor_t config_descriptor;
     410        opResult = usb_drv_req_get_bare_configuration_descriptor(hc,
     411        target.address, 0,
     412        &config_descriptor);
     413        if(opResult!=EOK){
     414                printf("[usb_hub] could not get configuration descriptor, %d\n",opResult);
     415                return 1;///\TODO some proper error code needed
     416        }
     417        //set configuration
     418        request.request_type = 0;
     419        request.request = USB_DEVREQ_SET_CONFIGURATION;
     420        request.index=0;
     421        request.length=0;
     422        request.value_high=0;
     423        request.value_low = config_descriptor.configuration_number;
     424        opResult = usb_drv_sync_control_write(hc, target, &request, NULL, 0);
     425        if (opResult != EOK) {
     426                printf("[usb_hub]something went wrong when setting hub`s configuration, %d\n", opResult);
     427        }
     428
     429
     430        for (port = 1; port < hub_info->port_count+1; ++port) {
     431                usb_hub_set_power_port_request(&request, port);
     432                opResult = usb_drv_sync_control_write(hc, target, &request, NULL, 0);
     433                printf("[usb_hub] powering port %d\n",port);
     434                if (opResult != EOK) {
     435                        printf("[usb_hub]something went wrong when setting hub`s %dth port\n", port);
     436                }
     437        }
     438        //ports powered, hub seems to be enabled
     439       
     440
     441        ipc_hangup(hc);
     442
     443        //add the hub to list
     444        usb_lst_append(&usb_hub_list, hub_info);
     445        printf("[usb_hub] hub info added to list\n");
     446        //(void)hub_info;
     447        usb_hub_check_hub_changes();
     448
     449        /// \TODO start the check loop, if not already started...
     450
     451        //this is just a test for port status bitmap type
     452        usb_hub_test_port_status();
     453
     454        printf("[usb_hub] hub dev added\n");
     455        printf("\taddress %d, has %d ports \n",
     456                        hub_info->usb_device->address,
     457                        hub_info->port_count);
     458        printf("\tused configuration %d\n",config_descriptor.configuration_number);
    136459
    137460        return EOK;
     
    139462}
    140463
     464//*********************************************
     465//
     466//  hub driver code, main loop
     467//
     468//*********************************************
     469
     470/**
     471 * reset the port with new device and reserve the default address
     472 * @param hc
     473 * @param port
     474 * @param target
     475 */
     476static void usb_hub_init_add_device(int hc, uint16_t port, usb_target_t target) {
     477        usb_device_request_setup_packet_t request;
     478        int opResult;
     479        printf("[usb_hub] some connection changed\n");
     480        //get default address
     481        opResult = usb_drv_reserve_default_address(hc);
     482        if (opResult != EOK) {
     483                printf("[usb_hub] cannot assign default address, it is probably used\n");
     484                return;
     485        }
     486        //reset port
     487        usb_hub_set_reset_port_request(&request, port);
     488        opResult = usb_drv_sync_control_write(
     489                        hc, target,
     490                        &request,
     491                        NULL, 0
     492                        );
     493        if (opResult != EOK) {
     494                //continue;
     495                printf("[usb_hub] something went wrong when reseting a port\n");
     496        }
     497}
     498
     499/**
     500 * finalize adding new device after port reset
     501 * @param hc
     502 * @param port
     503 * @param target
     504 */
     505static void usb_hub_finalize_add_device( usb_hub_info_t * hub,
     506                int hc, uint16_t port, usb_target_t target) {
     507
     508        int opResult;
     509        printf("[usb_hub] finalizing add device\n");
     510        opResult = usb_hub_clear_port_feature(hc, target.address,
     511            port, USB_HUB_FEATURE_C_PORT_RESET);
     512        if (opResult != EOK) {
     513                goto release;
     514        }
     515
     516        /* Request address at from host controller. */
     517        usb_address_t new_device_address = usb_drv_request_address(hc);
     518        if (new_device_address < 0) {
     519                printf("[usb_hub] failed to get free USB address\n");
     520                opResult = new_device_address;
     521                goto release;
     522        }
     523        printf("[usb_hub] setting new address\n");
     524        opResult = usb_drv_req_set_address(hc, USB_ADDRESS_DEFAULT,
     525            new_device_address);
     526
     527        if (opResult != EOK) {
     528                printf("[usb_hub] could not set address for new device\n");
     529                goto release;
     530        }
     531
     532release:
     533        printf("[usb_hub] releasing default address\n");
     534        usb_drv_release_default_address(hc);
     535        if (opResult != EOK) {
     536                return;
     537        }
     538
     539        devman_handle_t child_handle;
     540        opResult = usb_drv_register_child_in_devman(hc, hub->device,
     541            new_device_address, &child_handle);
     542        if (opResult != EOK) {
     543                printf("[usb_hub] could not start driver for new device \n");
     544                return;
     545        }
     546        hub->attached_devs[port].devman_handle = child_handle;
     547        hub->attached_devs[port].address = new_device_address;
     548
     549        opResult = usb_drv_bind_address(hc, new_device_address, child_handle);
     550        if (opResult != EOK) {
     551                printf("[usb_hub] could not assign address of device in hcd \n");
     552                return;
     553        }
     554        printf("[usb_hub] new device address %d, handle %d\n",
     555            new_device_address, child_handle);
     556       
     557}
     558
     559/**
     560 * unregister device address in hc, close the port
     561 * @param hc
     562 * @param port
     563 * @param target
     564 */
     565static void usb_hub_removed_device(
     566    usb_hub_info_t * hub, int hc, uint16_t port, usb_target_t target) {
     567        //usb_device_request_setup_packet_t request;
     568        int opResult;
     569        //disable port
     570        /*usb_hub_set_disable_port_request(&request, port);
     571        opResult = usb_drv_sync_control_write(
     572                        hc, target,
     573                        &request,
     574                        NULL, 0
     575                        );
     576        if (opResult != EOK) {
     577                //continue;
     578                printf("[usb_hub] something went wrong when disabling a port\n");
     579        }*/
     580        /// \TODO remove device
     581
     582        hub->attached_devs[port].devman_handle=0;
     583        //close address
     584        if(hub->attached_devs[port].address!=0){
     585                opResult = usb_drv_release_address(hc,hub->attached_devs[port].address);
     586                if(opResult != EOK) {
     587                        printf("[usb_hub] could not release address of removed device: %d\n",opResult);
     588                }
     589                hub->attached_devs[port].address = 0;
     590        }else{
     591                printf("[usb_hub] this is strange, disconnected device had no address\n");
     592                //device was disconnected before it`s port was reset - return default address
     593                usb_drv_release_default_address(hc);
     594        }
     595}
     596
     597/**
     598 * process interrupts on given hub port
     599 * @param hc
     600 * @param port
     601 * @param target
     602 */
     603static void usb_hub_process_interrupt(usb_hub_info_t * hub, int hc,
     604        uint16_t port, usb_address_t address) {
     605        printf("[usb_hub] interrupt at port %d\n", port);
     606        //determine type of change
     607        usb_target_t target;
     608        target.address=address;
     609        target.endpoint=0;
     610        usb_port_status_t status;
     611        size_t rcvd_size;
     612        usb_device_request_setup_packet_t request;
     613        int opResult;
     614        usb_hub_set_port_status_request(&request, port);
     615        //endpoint 0
     616
     617        opResult = usb_drv_sync_control_read(
     618                        hc, target,
     619                        &request,
     620                        &status, 4, &rcvd_size
     621                        );
     622        if (opResult != EOK) {
     623                printf("[usb_hub] ERROR: could not get port status\n");
     624                return;
     625        }
     626        if (rcvd_size != sizeof (usb_port_status_t)) {
     627                printf("[usb_hub] ERROR: received status has incorrect size\n");
     628                return;
     629        }
     630        //something connected/disconnected
     631        if (usb_port_connect_change(&status)) {
     632                opResult = usb_hub_clear_port_feature(hc, target.address,
     633                    port, USB_HUB_FEATURE_C_PORT_CONNECTION);
     634                // TODO: check opResult
     635                if (usb_port_dev_connected(&status)) {
     636                        printf("[usb_hub] some connection changed\n");
     637                        usb_hub_init_add_device(hc, port, target);
     638                } else {
     639                        usb_hub_removed_device(hub, hc, port, target);
     640                }
     641        }
     642        //port reset
     643        if (usb_port_reset_completed(&status)) {
     644                printf("[usb_hub] port reset complete\n");
     645                if (usb_port_enabled(&status)) {
     646                        usb_hub_finalize_add_device(hub, hc, port, target);
     647                } else {
     648                        printf("[usb_hub] ERROR: port reset, but port still not enabled\n");
     649                }
     650        }
     651
     652        usb_port_set_connect_change(&status, false);
     653        usb_port_set_reset(&status, false);
     654        usb_port_set_reset_completed(&status, false);
     655        usb_port_set_dev_connected(&status, false);
     656        if (status) {
     657                printf("[usb_hub]there was some unsupported change on port %d\n",port);
     658        }
     659        /// \TODO handle other changes
     660        /// \TODO debug log for various situations
     661
     662
     663
     664        /*
     665        //configure device
     666        usb_drv_reserve_default_address(hc);
     667
     668        usb_address_t new_device_address = usb_drv_request_address(hc);
     669
     670
     671        usb_drv_release_default_address(hc);
     672         * */
     673}
    141674
    142675/** Check changes on all known hubs.
    143676 */
    144 static void check_hub_changes(void) {
     677void usb_hub_check_hub_changes(void) {
    145678        /*
    146679         * Iterate through all hubs.
    147680         */
    148         for (; false; ) {
     681        usb_general_list_t * lst_item;
     682        for (lst_item = usb_hub_list.next;
     683                        lst_item != &usb_hub_list;
     684                        lst_item = lst_item->next) {
     685                usb_hub_info_t * hub_info = ((usb_hub_info_t*)lst_item->data);
    149686                /*
    150687                 * Check status change pipe of this hub.
    151688                 */
    152                 usb_target_t target = {
    153                         .address = 5,
    154                         .endpoint = 1
    155                 };
    156 
    157                 size_t port_count = 7;
     689
     690                usb_target_t target;
     691                target.address = hub_info->usb_device->address;
     692                target.endpoint = 1;/// \TODO get from endpoint descriptor
     693                printf("[usb_hub] checking changes for hub at addr %d\n",
     694                    target.address);
     695
     696                size_t port_count = hub_info->port_count;
    158697
    159698                /*
    160699                 * Connect to respective HC.
    161700                 */
    162                 int hc = usb_drv_hc_connect(NULL, 0);
     701                int hc = usb_drv_hc_connect(hub_info->device, 0);
    163702                if (hc < 0) {
    164703                        continue;
     
    166705
    167706                // FIXME: count properly
    168                 size_t byte_length = (port_count / 8) + 1;
     707                size_t byte_length = ((port_count+1) / 8) + 1;
    169708
    170709                void *change_bitmap = malloc(byte_length);
     
    174713                /*
    175714                 * Send the request.
    176                  * FIXME: check returned value for possible errors
    177                  */
    178                 usb_drv_async_interrupt_in(hc, target,
     715                 */
     716                int opResult = usb_drv_async_interrupt_in(hc, target,
    179717                                change_bitmap, byte_length, &actual_size,
    180718                                &handle);
    181719
    182720                usb_drv_async_wait_for(handle);
     721
     722                if (opResult != EOK) {
     723                        printf("[usb_hub] something went wrong while getting status of hub\n");
     724                        continue;
     725                }
     726                unsigned int port;
     727                for (port = 1; port < port_count+1; ++port) {
     728                        bool interrupt = (((uint8_t*) change_bitmap)[port / 8] >> (port % 8)) % 2;
     729                        if (interrupt) {
     730                                usb_hub_process_interrupt(
     731                                        hub_info, hc, port, hub_info->usb_device->address);
     732                        }
     733                }
     734
    183735
    184736                /*
  • uspace/drv/usbkbd/main.c

    r84439d7 r75732da  
    2828#include <usb/usbdrv.h>
    2929#include <driver.h>
     30#include <ipc/driver.h>
    3031#include <errno.h>
     32#include <fibril.h>
     33#include <usb/classes/hid.h>
     34#include <usb/classes/hidparser.h>
     35#include <usb/devreq.h>
     36#include <usb/descriptor.h>
    3137
    3238#define BUFFER_SIZE 32
    33 
    34 /* Call this periodically to check keyboard status changes. */
    35 static void poll_keyboard(device_t *dev)
     39#define NAME "usbkbd"
     40
     41#define GUESSED_POLL_ENDPOINT 1
     42
     43/*
     44 * Callbacks for parser
     45 */
     46static void usbkbd_process_keycodes(const uint16_t *key_codes, size_t count,
     47                                    void *arg)
     48{
     49
     50}
     51
     52/*
     53 * Kbd functions
     54 */
     55static int usbkbd_parse_descriptors(usb_hid_dev_kbd_t *kbd_dev,
     56                                    const uint8_t *data, size_t size)
     57{
     58//      const uint8_t *pos = data;
     59       
     60//      // get the configuration descriptor (should be first)
     61//      if (*pos != sizeof(usb_standard_configuration_descriptor_t)
     62//          || *(pos + 1) != USB_DESCTYPE_CONFIGURATION) {
     63//              fprintf(stderr, "Wrong format of configuration descriptor");
     64//              return EINVAL;
     65//      }
     66       
     67//      usb_standard_configuration_descriptor_t config_descriptor;
     68//      memcpy(&config_descriptor, pos,
     69//          sizeof(usb_standard_configuration_descriptor_t));
     70//      pos += sizeof(usb_standard_configuration_descriptor_t);
     71       
     72//      // parse other descriptors
     73//      while (pos - data < size) {
     74//              //uint8_t desc_size = *pos;
     75//              uint8_t desc_type = *(pos + 1);
     76//              switch (desc_type) {
     77//              case USB_DESCTYPE_INTERFACE:
     78//                      break;
     79//              case USB_DESCTYPE_ENDPOINT:
     80//                      break;
     81//              case USB_DESCTYPE_HID:
     82//                      break;
     83//              case USB_DESCTYPE_HID_REPORT:
     84//                      break;
     85//              case USB_DESCTYPE_HID_PHYSICAL:
     86//                      break;
     87//              }
     88//      }
     89       
     90        return EOK;
     91}
     92
     93static int usbkbd_get_descriptors(usb_hid_dev_kbd_t *kbd_dev)
     94{
     95        // get the first configuration descriptor (TODO: or some other??)
     96        usb_standard_configuration_descriptor_t config_desc;
     97       
     98        int rc = usb_drv_req_get_bare_configuration_descriptor(
     99            kbd_dev->device->parent_phone, kbd_dev->address, 0, &config_desc);
     100       
     101        if (rc != EOK) {
     102                return rc;
     103        }
     104       
     105        // prepare space for all underlying descriptors
     106        uint8_t *descriptors = (uint8_t *)malloc(config_desc.total_length);
     107        if (descriptors == NULL) {
     108                return ENOMEM;
     109        }
     110       
     111        size_t transferred = 0;
     112        // get full configuration descriptor
     113        rc = usb_drv_req_get_full_configuration_descriptor(
     114            kbd_dev->device->parent_phone, kbd_dev->address, 0, descriptors,
     115            config_desc.total_length, &transferred);
     116       
     117        if (rc != EOK) {
     118                return rc;
     119        }
     120        if (transferred != config_desc.total_length) {
     121                return ELIMIT;
     122        }
     123       
     124        rc = usbkbd_parse_descriptors(kbd_dev, descriptors, transferred);
     125        free(descriptors);
     126       
     127        return rc;
     128}
     129
     130static usb_hid_dev_kbd_t *usbkbd_init_device(device_t *dev)
     131{
     132        usb_hid_dev_kbd_t *kbd_dev = (usb_hid_dev_kbd_t *)malloc(
     133                        sizeof(usb_hid_dev_kbd_t));
     134
     135        if (kbd_dev == NULL) {
     136                fprintf(stderr, NAME ": No memory!\n");
     137                return NULL;
     138        }
     139
     140        kbd_dev->device = dev;
     141
     142        // get phone to my HC and save it as my parent's phone
     143        // TODO: maybe not a good idea if DDF will use parent_phone
     144        kbd_dev->device->parent_phone = usb_drv_hc_connect(dev, 0);
     145
     146        kbd_dev->address = usb_drv_get_my_address(dev->parent_phone,
     147            dev);
     148
     149        // doesn't matter now that we have no address
     150//      if (kbd_dev->address < 0) {
     151//              fprintf(stderr, NAME ": No device address!\n");
     152//              free(kbd_dev);
     153//              return NULL;
     154//      }
     155
     156        // default endpoint
     157        kbd_dev->poll_endpoint = GUESSED_POLL_ENDPOINT;
     158       
     159        /*
     160         * will need all descriptors:
     161         * 1) choose one configuration from configuration descriptors
     162         *    (set it to the device)
     163         * 2) set endpoints from endpoint descriptors
     164         */
     165
     166        // TODO: get descriptors
     167        usbkbd_get_descriptors(kbd_dev);
     168        // TODO: parse descriptors and save endpoints
     169
     170        return kbd_dev;
     171}
     172
     173static void usbkbd_process_interrupt_in(usb_hid_dev_kbd_t *kbd_dev,
     174                                        uint8_t *buffer, size_t actual_size)
     175{
     176        /*
     177         * here, the parser will be called, probably with some callbacks
     178         * now only take last 6 bytes and process, i.e. send to kbd
     179         */
     180
     181        usb_hid_report_in_callbacks_t *callbacks =
     182            (usb_hid_report_in_callbacks_t *)malloc(
     183                sizeof(usb_hid_report_in_callbacks_t));
     184        callbacks->keyboard = usbkbd_process_keycodes;
     185
     186        usb_hid_parse_report(kbd_dev->parser, buffer, actual_size, callbacks,
     187            NULL);
     188}
     189
     190static void usbkbd_poll_keyboard(usb_hid_dev_kbd_t *kbd_dev)
    36191{
    37192        int rc;
    38193        usb_handle_t handle;
    39         char buffer[BUFFER_SIZE];
     194        uint8_t buffer[BUFFER_SIZE];
    40195        size_t actual_size;
    41         usb_endpoint_t poll_endpoint = 1;
    42 
    43         usb_address_t my_address = usb_drv_get_my_address(dev->parent_phone,
    44             dev);
    45         if (my_address < 0) {
    46                 return;
    47         }
     196        //usb_endpoint_t poll_endpoint = 1;
     197
     198//      usb_address_t my_address = usb_drv_get_my_address(dev->parent_phone,
     199//          dev);
     200//      if (my_address < 0) {
     201//              return;
     202//      }
    48203
    49204        usb_target_t poll_target = {
    50                 .address = my_address,
    51                 .endpoint = poll_endpoint
     205                .address = kbd_dev->address,
     206                .endpoint = kbd_dev->poll_endpoint
    52207        };
    53208
    54         rc = usb_drv_async_interrupt_in(dev->parent_phone, poll_target,
    55             buffer, BUFFER_SIZE, &actual_size, &handle);
    56         if (rc != EOK) {
    57                 return;
    58         }
    59 
    60         rc = usb_drv_async_wait_for(handle);
    61         if (rc != EOK) {
    62                 return;
    63         }
    64 
    65         /*
    66          * If the keyboard answered with NAK, it returned no data.
    67          * This implies that no change happened since last query.
    68          */
    69         if (actual_size == 0) {
    70                 return;
    71         }
    72 
    73         /*
    74          * Process pressed keys.
    75          */
    76 }
    77 
    78 static int add_kbd_device(device_t *dev)
     209        while (true) {
     210                async_usleep(1000 * 1000);
     211                rc = usb_drv_async_interrupt_in(kbd_dev->device->parent_phone,
     212                    poll_target, buffer, BUFFER_SIZE, &actual_size, &handle);
     213
     214                if (rc != EOK) {
     215                        continue;
     216                }
     217
     218                rc = usb_drv_async_wait_for(handle);
     219                if (rc != EOK) {
     220                        continue;
     221                }
     222
     223                /*
     224                 * If the keyboard answered with NAK, it returned no data.
     225                 * This implies that no change happened since last query.
     226                 */
     227                if (actual_size == 0) {
     228                        continue;
     229                }
     230
     231                /*
     232                 * TODO: Process pressed keys.
     233                 */
     234                usbkbd_process_interrupt_in(kbd_dev, buffer, actual_size);
     235        }
     236
     237        // not reached
     238        assert(0);
     239}
     240
     241static int usbkbd_fibril_device(void *arg)
     242{
     243        printf("!!! USB device fibril\n");
     244
     245        if (arg == NULL) {
     246                printf("No device!\n");
     247                return -1;
     248        }
     249
     250        device_t *dev = (device_t *)arg;
     251
     252        // initialize device (get and process descriptors, get address, etc.)
     253        usb_hid_dev_kbd_t *kbd_dev = usbkbd_init_device(dev);
     254
     255        usbkbd_poll_keyboard(kbd_dev);
     256
     257        return EOK;
     258}
     259
     260static int usbkbd_add_device(device_t *dev)
    79261{
    80262        /* For now, fail immediately. */
    81         return ENOTSUP;
     263        //return ENOTSUP;
    82264
    83265        /*
    84266         * When everything is okay, connect to "our" HC.
    85          */
    86         int phone = usb_drv_hc_connect(dev, 0);
    87         if (phone < 0) {
    88                 /*
    89                  * Connecting to HC failed, roll-back and announce
    90                  * failure.
    91                  */
    92                 return phone;
    93         }
    94 
    95         dev->parent_phone = phone;
    96 
    97         /*
    98          * Just for fun ;-).
    99          */
    100         poll_keyboard(dev);
     267         *
     268         * Not supported yet, skip..
     269         */
     270//      int phone = usb_drv_hc_connect(dev, 0);
     271//      if (phone < 0) {
     272//              /*
     273//               * Connecting to HC failed, roll-back and announce
     274//               * failure.
     275//               */
     276//              return phone;
     277//      }
     278
     279//      dev->parent_phone = phone;
     280
     281        /*
     282         * Create new fibril for handling this keyboard
     283         */
     284        fid_t fid = fibril_create(usbkbd_fibril_device, dev);
     285        if (fid == 0) {
     286                printf("%s: failed to start fibril for HID device\n", NAME);
     287                return ENOMEM;
     288        }
     289        fibril_add_ready(fid);
    101290
    102291        /*
     
    107296
    108297static driver_ops_t kbd_driver_ops = {
    109         .add_device = add_kbd_device,
     298        .add_device = usbkbd_add_device,
    110299};
    111300
    112301static driver_t kbd_driver = {
    113         .name = "usbkbd",
     302        .name = NAME,
    114303        .driver_ops = &kbd_driver_ops
    115304};
  • uspace/drv/usbkbd/usbkbd.ma

    r84439d7 r75732da  
    1110 usb&class=hid
     210 usb&class=HID
     310 usb&interface&class=HID
    2410 usb&hid
  • uspace/drv/vhc/Makefile

    r84439d7 r75732da  
    3939
    4040SOURCES = \
    41         addrmgm.c \
    4241        conndev.c \
    4342        connhost.c \
  • uspace/drv/vhc/conn.h

    r84439d7 r75732da  
    4848
    4949void address_init(void);
    50 int reserve_default_address(device_t *);
    51 int release_default_address(device_t *);
    52 int request_address(device_t *, usb_address_t *);
    53 int release_address(device_t *, usb_address_t);
    54 int bind_address(device_t *, usb_address_t, devman_handle_t);
    5550
    56 int tell_address(device_t *, devman_handle_t, usb_address_t *);
    5751
    5852void default_connection_handler(device_t *, ipc_callid_t, ipc_call_t *);
  • uspace/drv/vhc/connhost.c

    r84439d7 r75732da  
    3636#include <errno.h>
    3737#include <usb/usb.h>
     38#include <usb/hcd.h>
    3839
    3940#include "vhcd.h"
     
    5758                case USB_DIRECTION_IN:
    5859                        transfer->in_callback(transfer->dev,
    59                             size, outcome,
     60                            outcome, size,
    6061                            transfer->arg);
    6162                        break;
     
    9293    usbhc_iface_transfer_out_callback_t callback, void *arg)
    9394{
    94         printf(NAME ": transfer OUT [%d.%d (%s); %u]\n",
     95        dprintf(3, "transfer OUT [%d.%d (%s); %zu]",
    9596            target.address, target.endpoint,
    9697            usb_str_transfer_type(transfer_type),
     
    112113    usbhc_iface_transfer_out_callback_t callback, void *arg)
    113114{
    114         printf(NAME ": transfer SETUP [%d.%d (%s); %u]\n",
     115        dprintf(3, "transfer SETUP [%d.%d (%s); %zu]",
    115116            target.address, target.endpoint,
    116117            usb_str_transfer_type(transfer_type),
     
    132133    usbhc_iface_transfer_in_callback_t callback, void *arg)
    133134{
    134         printf(NAME ": transfer IN [%d.%d (%s); %u]\n",
     135        dprintf(3, "transfer IN [%d.%d (%s); %zu]",
    135136            target.address, target.endpoint,
    136137            usb_str_transfer_type(transfer_type),
     
    218219}
    219220
     221static usb_address_keeping_t addresses;
     222
     223
     224static int reserve_default_address(device_t *dev)
     225{
     226        usb_address_keeping_reserve_default(&addresses);
     227        return EOK;
     228}
     229
     230static int release_default_address(device_t *dev)
     231{
     232        usb_address_keeping_release_default(&addresses);
     233        return EOK;
     234}
     235
     236static int request_address(device_t *dev, usb_address_t *address)
     237{
     238        usb_address_t addr = usb_address_keeping_request(&addresses);
     239        if (addr < 0) {
     240                return (int)addr;
     241        }
     242
     243        *address = addr;
     244        return EOK;
     245}
     246
     247static int release_address(device_t *dev, usb_address_t address)
     248{
     249        return usb_address_keeping_release(&addresses, address);
     250}
     251
     252static int bind_address(device_t *dev, usb_address_t address,
     253    devman_handle_t handle)
     254{
     255        usb_address_keeping_devman_bind(&addresses, address, handle);
     256        return EOK;
     257}
     258
     259static int tell_address(device_t *dev, devman_handle_t handle,
     260    usb_address_t *address)
     261{
     262        usb_address_t addr = usb_address_keeping_find(&addresses, handle);
     263        if (addr < 0) {
     264                return addr;
     265        }
     266
     267        *address = addr;
     268        return EOK;
     269}
     270
     271void address_init(void)
     272{
     273        usb_address_keeping_init(&addresses, 50);
     274}
    220275
    221276usbhc_iface_t vhc_iface = {
  • uspace/drv/vhc/debug.c

    r84439d7 r75732da  
    3535#include <stdio.h>
    3636#include <ipc/ipc.h>
     37#include <usb/debug.h>
    3738
    3839#include "vhcd.h"
    3940
    40 /** Current debug level. */
    41 int debug_level = 0;
    42 
    43 /** Debugging printf.
    44  * This function is intended for single-line messages as it
    45  * automatically prints debugging prefix at the beginning of the
    46  * line.
    47  *
    48  * @see printf
    49  * @param level Debugging level.
    50  */
    51 void dprintf(int level, const char *format, ...)
    52 {
    53         if (level > debug_level) {
    54                 return;
    55         }
    56        
    57         printf("%s(%d): ", NAME, level);
    58         va_list args;
    59         va_start(args, format);
    60         vprintf(format, args);
    61         va_end(args);
    62         printf("\n");
    63 }
    6441
    6542/** Debug print informing of invalid call.
  • uspace/drv/vhc/devices.c

    r84439d7 r75732da  
    147147        if (virthub_dev.address == transaction->target.address) {
    148148                size_t tmp;
    149                 dprintf(3, "sending `%s' transaction to hub",
     149                dprintf(1, "sending `%s' transaction to hub",
    150150                    usbvirt_str_transaction_type(transaction->type));
    151151                switch (transaction->type) {
  • uspace/drv/vhc/hc.c

    r84439d7 r75732da  
    5050#include "hub.h"
    5151
    52 #define USLEEP_BASE (500 * 1000)
     52#define USLEEP_BASE (0 * 5 * 1000)
    5353
    54 #define USLEEP_VAR 5000
     54#define USLEEP_VAR 50
    5555
    5656#define SHORTENING_VAR 15
     
    8989    usb_transaction_outcome_t outcome)
    9090{
    91         dprintf(3, "processing transaction " TRANSACTION_FORMAT ", outcome: %s",
     91        dprintf(3, "transaction " TRANSACTION_FORMAT " done, outcome: %s",
    9292            TRANSACTION_PRINTF(*transaction),
    9393            usb_str_transaction_outcome(outcome));
     
    116116                char ports[HUB_PORT_COUNT + 2];
    117117                hub_get_port_statuses(ports, HUB_PORT_COUNT + 1);
    118                 dprintf(3, "virtual hub: addr=%d ports=%s",
     118                dprintf(4, "virtual hub: addr=%d ports=%s",
    119119                    virthub_dev.address, ports);
    120120               
     
    124124                list_remove(first_transaction_link);
    125125               
     126
     127                dprintf(0, "about to process " TRANSACTION_FORMAT " (vhub:%s)",
     128                    TRANSACTION_PRINTF(*transaction), ports);
     129
    126130                dprintf(3, "processing transaction " TRANSACTION_FORMAT "",
    127131                    TRANSACTION_PRINTF(*transaction));
     
    153157        transaction->callback_arg = arg;
    154158       
    155         dprintf(1, "creating transaction " TRANSACTION_FORMAT,
     159        dprintf(3, "creating transaction " TRANSACTION_FORMAT,
    156160            TRANSACTION_PRINTF(*transaction));
    157161       
  • uspace/drv/vhc/hcd.c

    r84439d7 r75732da  
    7979         * Initialize our hub and announce its presence.
    8080         */
    81         hub_init();
    82         usb_hcd_add_root_hub(dev);
     81        hub_init(dev);
    8382
    8483        printf("%s: virtual USB host controller ready.\n", NAME);
     
    111110        printf("%s: virtual USB host controller driver.\n", NAME);
    112111
    113         debug_level = 10;
     112        usb_dprintf_enable(NAME, 0);
    114113
    115114        fid_t fid = fibril_create(hc_manager_fibril, NULL);
  • uspace/drv/vhc/hub.c

    r84439d7 r75732da  
    3737#include <usbvirt/device.h>
    3838#include <errno.h>
     39#include <str_error.h>
    3940#include <stdlib.h>
     41#include <driver.h>
    4042
    4143#include "vhcd.h"
    4244#include "hub.h"
    4345#include "hubintern.h"
     46#include "conn.h"
    4447
    4548
     
    141144        .ops = &hub_ops,
    142145        .descriptors = &descriptors,
    143         .lib_debug_level = 4,
     146        .lib_debug_level = 0,
    144147        .lib_debug_enabled_tags = USBVIRT_DEBUGTAG_ALL
    145148};
     
    148151hub_device_t hub_dev;
    149152
     153static usb_address_t hub_set_address(usbvirt_device_t *hub)
     154{
     155        usb_address_t new_address;
     156        int rc = vhc_iface.request_address(NULL, &new_address);
     157        if (rc != EOK) {
     158                return rc;
     159        }
     160       
     161        usb_device_request_setup_packet_t setup_packet = {
     162                .request_type = 0,
     163                .request = USB_DEVREQ_SET_ADDRESS,
     164                .index = 0,
     165                .length = 0,
     166        };
     167        setup_packet.value = new_address;
     168
     169        hub->transaction_setup(hub, 0, &setup_packet, sizeof(setup_packet));
     170        hub->transaction_in(hub, 0, NULL, 0, NULL);
     171       
     172        return new_address;
     173}
     174
    150175/** Initialize virtual hub. */
    151 void hub_init(void)
    152 {
    153         size_t i;
     176void hub_init(device_t *hc_dev)
     177{
     178        size_t i;
     179       
    154180        for (i = 0; i < HUB_PORT_COUNT; i++) {
    155181                hub_port_t *port = &hub_dev.ports[i];
    156182               
     183                port->index = (int) i + 1;
    157184                port->device = NULL;
    158185                port->state = HUB_PORT_STATE_NOT_CONFIGURED;
    159186                port->status_change = 0;
     187                fibril_mutex_initialize(&port->guard);
    160188        }
    161189       
     
    163191       
    164192        dprintf(1, "virtual hub (%d ports) created", HUB_PORT_COUNT);
     193
     194        usb_address_t hub_address = hub_set_address(&virthub_dev);
     195        if (hub_address < 0) {
     196                dprintf(1, "problem changing hub address (%s)",
     197                    str_error(hub_address));
     198        }
     199
     200        dprintf(2, "virtual hub address changed to %d", hub_address);
     201
     202        char *id;
     203        int rc = asprintf(&id, "usb&hub");
     204        if (rc <= 0) {
     205                return;
     206        }
     207        devman_handle_t hub_handle;
     208        rc = child_device_register_wrapper(hc_dev, "hub", id, 10, &hub_handle);
     209        if (rc != EOK) {
     210                free(id);
     211        }
     212
     213        vhc_iface.bind_address(NULL, hub_address, hub_handle); 
     214
     215        dprintf(2, "virtual hub has devman handle %d", (int) hub_handle);
    165216}
    166217
     
    175226        for (i = 0; i < HUB_PORT_COUNT; i++) {
    176227                hub_port_t *port = &hub_dev.ports[i];
     228                fibril_mutex_lock(&port->guard);
    177229               
    178230                if (port->device != NULL) {
     231                        fibril_mutex_unlock(&port->guard);
    179232                        continue;
    180233                }
     
    191244                //if (port->state == HUB_PORT_STATE_DISCONNECTED) {
    192245                        port->state = HUB_PORT_STATE_DISABLED;
    193                         set_port_status_change(port, HUB_STATUS_C_PORT_CONNECTION);
     246                        set_port_status_change_nl(port, HUB_STATUS_C_PORT_CONNECTION);
    194247                //}
    195248               
     249                fibril_mutex_unlock(&port->guard);
     250
    196251                return i;
    197252        }
  • uspace/drv/vhc/hub.h

    r84439d7 r75732da  
    3737
    3838#include <usbvirt/device.h>
     39#include <driver.h>
    3940
    4041#include "devices.h"
    4142
    42 #define HUB_PORT_COUNT 6
     43#define HUB_PORT_COUNT 2
    4344
    4445#define BITS2BYTES(bits) \
     
    4748extern usbvirt_device_t virthub_dev;
    4849
    49 void hub_init(void);
     50void hub_init(device_t *);
    5051size_t hub_add_device(virtdev_connection_t *);
    5152void hub_remove_device(virtdev_connection_t *);
  • uspace/drv/vhc/hubintern.h

    r84439d7 r75732da  
    3737
    3838#include "hub.h"
     39#include <fibril_synch.h>
    3940
    4041/** Endpoint number for status change pipe. */
     
    121122typedef struct {
    122123        virtdev_connection_t *device;
     124        int index;
    123125        hub_port_state_t state;
    124126        uint16_t status_change;
     127        fibril_mutex_t guard;
    125128} hub_port_t;
    126129
     
    138141void clear_port_status_change(hub_port_t *, uint16_t);
    139142void set_port_status_change(hub_port_t *, uint16_t);
     143void set_port_status_change_nl(hub_port_t *, uint16_t);
    140144
    141145
  • uspace/drv/vhc/hubops.c

    r84439d7 r75732da  
    5959static int on_get_descriptor(struct usbvirt_device *dev,
    6060    usb_device_request_setup_packet_t *request, uint8_t *data);
     61static int on_set_configuration(struct usbvirt_device *dev,
     62    usb_device_request_setup_packet_t *request, uint8_t *data);
    6163static int on_class_request(struct usbvirt_device *dev,
    6264    usb_device_request_setup_packet_t *request, uint8_t *data);
     
    6466    usb_endpoint_t endpoint,
    6567    void *buffer, size_t size, size_t *actual_size);
     68static void set_port_state(hub_port_t *, hub_port_state_t);
     69static void clear_port_status_change_nl(hub_port_t *, uint16_t);
     70static void set_port_state_nl(hub_port_t *, hub_port_state_t);
    6671
    6772/** Hub operations. */
    6873usbvirt_device_ops_t hub_ops = {
    6974        .on_standard_request[USB_DEVREQ_GET_DESCRIPTOR] = on_get_descriptor,
     75        .on_standard_request[USB_DEVREQ_SET_CONFIGURATION] = on_set_configuration,
    7076        .on_class_device_request = on_class_request,
    7177        .on_data = NULL,
     
    8793}
    8894
     95/** Callback for SET_CONFIGURATION request. */
     96int on_set_configuration(struct usbvirt_device *dev,
     97    usb_device_request_setup_packet_t *request, uint8_t *data)
     98{
     99        /* We must suspend power source to all ports. */
     100        size_t i;
     101        for (i = 0; i < HUB_PORT_COUNT; i++) {
     102                hub_port_t *port = &hub_dev.ports[i];
     103               
     104                set_port_state(port, HUB_PORT_STATE_POWERED_OFF);
     105        }
     106       
     107        /* Let the framework handle the rest of the job. */
     108        return EFORWARD;
     109}
     110
     111struct delay_port_state_change {
     112        suseconds_t delay;
     113        hub_port_state_t old_state;
     114        hub_port_state_t new_state;
     115        hub_port_t *port;
     116};
     117
     118static int set_port_state_delayed_fibril(void *arg)
     119{
     120        struct delay_port_state_change *change
     121            = (struct delay_port_state_change *) arg;
     122       
     123        async_usleep(change->delay);
     124       
     125        fibril_mutex_lock(&change->port->guard);
     126        if (change->port->state == change->old_state) {
     127                set_port_state_nl(change->port, change->new_state);
     128        }
     129        fibril_mutex_unlock(&change->port->guard);
     130       
     131        free(change);
     132       
     133        return EOK;
     134}
     135
     136static void set_port_state_delayed(hub_port_t *port,
     137    suseconds_t delay_time,
     138    hub_port_state_t old_state, hub_port_state_t new_state)
     139{
     140        struct delay_port_state_change *change
     141            = malloc(sizeof(struct delay_port_state_change));
     142        change->port = port;
     143        change->delay = delay_time;
     144        change->old_state = old_state;
     145        change->new_state = new_state;
     146        fid_t fibril = fibril_create(set_port_state_delayed_fibril, change);
     147        if (fibril == 0) {
     148                printf("Failed to create fibril\n");
     149                return;
     150        }
     151        fibril_add_ready(fibril);
     152}
     153
    89154/** Change port status and updates status change status fields.
    90155 */
    91 static void set_port_state(hub_port_t *port, hub_port_state_t state)
    92 {
     156void set_port_state(hub_port_t *port, hub_port_state_t state)
     157{
     158        fibril_mutex_lock(&port->guard);
     159        set_port_state_nl(port, state);
     160        fibril_mutex_unlock(&port->guard);
     161}
     162
     163void set_port_state_nl(hub_port_t *port, hub_port_state_t state)
     164{
     165
     166        dprintf(2, "setting port %d state to %d (%c) from %c (change=%u)",
     167            port->index,
     168            state, hub_port_state_as_char(state),
     169            hub_port_state_as_char(port->state),
     170            (unsigned int) port->status_change);
     171       
     172        if (state == HUB_PORT_STATE_POWERED_OFF) {
     173                clear_port_status_change_nl(port, HUB_STATUS_C_PORT_CONNECTION);
     174                clear_port_status_change_nl(port, HUB_STATUS_C_PORT_ENABLE);
     175                clear_port_status_change_nl(port, HUB_STATUS_C_PORT_RESET);
     176        }
     177        if (state == HUB_PORT_STATE_RESUMING) {
     178                set_port_state_delayed(port, 10*1000,
     179                    HUB_PORT_STATE_RESUMING, HUB_PORT_STATE_ENABLED);
     180        }
     181        if (state == HUB_PORT_STATE_RESETTING) {
     182                set_port_state_delayed(port, 10*1000,
     183                    HUB_PORT_STATE_RESETTING, HUB_PORT_STATE_ENABLED);
     184        }
     185        if ((port->state == HUB_PORT_STATE_RESETTING)
     186            && (state == HUB_PORT_STATE_ENABLED)) {
     187                set_port_status_change_nl(port, HUB_STATUS_C_PORT_RESET);
     188        }
     189       
    93190        port->state = state;
    94         if (state == HUB_PORT_STATE_POWERED_OFF) {
    95                 clear_port_status_change(port, HUB_STATUS_C_PORT_CONNECTION);
    96                 clear_port_status_change(port, HUB_STATUS_C_PORT_ENABLE);
    97                 clear_port_status_change(port, HUB_STATUS_C_PORT_RESET);
    98         }
    99         if (state == HUB_PORT_STATE_RESUMING) {
    100                 async_usleep(10*1000);
    101                 if (port->state == state) {
    102                         set_port_state(port, HUB_PORT_STATE_ENABLED);
    103                 }
    104         }
    105         if (state == HUB_PORT_STATE_RESETTING) {
    106                 async_usleep(10*1000);
    107                 if (port->state == state) {
    108                         set_port_status_change(port, HUB_STATUS_C_PORT_RESET);
    109                         set_port_state(port, HUB_PORT_STATE_ENABLED);
    110                 }
    111         }
    112191}
    113192
     
    122201                } \
    123202        } while (false); \
    124         hub_port_t *portvar = &hub_dev.ports[index]
     203        hub_port_t *portvar = &hub_dev.ports[index-1]
    125204
    126205
     
    134213        _GET_PORT(port, portindex);
    135214       
     215        fibril_mutex_lock(&port->guard);
     216        int rc = ENOTSUP;
     217
    136218        switch (feature) {
    137219                case USB_HUB_FEATURE_PORT_ENABLE:
    138220                        if ((port->state != HUB_PORT_STATE_NOT_CONFIGURED)
    139221                            && (port->state != HUB_PORT_STATE_POWERED_OFF)) {
    140                                 set_port_state(port, HUB_PORT_STATE_DISABLED);
    141                         }
    142                         return EOK;
     222                                set_port_state_nl(port, HUB_PORT_STATE_DISABLED);
     223                        }
     224                        rc = EOK;
     225                        break;
    143226               
    144227                case USB_HUB_FEATURE_PORT_SUSPEND:
    145228                        if (port->state != HUB_PORT_STATE_SUSPENDED) {
    146                                 return EOK;
    147                         }
    148                         set_port_state(port, HUB_PORT_STATE_RESUMING);
    149                         return EOK;
     229                                rc = EOK;
     230                                break;
     231                        }
     232                        set_port_state_nl(port, HUB_PORT_STATE_RESUMING);
     233                        rc = EOK;
     234                        break;
    150235                       
    151236                case USB_HUB_FEATURE_PORT_POWER:
    152237                        if (port->state != HUB_PORT_STATE_NOT_CONFIGURED) {
    153                                 set_port_state(port, HUB_PORT_STATE_POWERED_OFF);
    154                         }
    155                         return EOK;
     238                                set_port_state_nl(port, HUB_PORT_STATE_POWERED_OFF);
     239                        }
     240                        rc = EOK;
     241                        break;
    156242               
    157243                case USB_HUB_FEATURE_C_PORT_CONNECTION:
    158                         clear_port_status_change(port, HUB_STATUS_C_PORT_CONNECTION);
    159                         return EOK;
     244                        clear_port_status_change_nl(port, HUB_STATUS_C_PORT_CONNECTION);
     245                        rc = EOK;
     246                        break;
    160247               
    161248                case USB_HUB_FEATURE_C_PORT_ENABLE:
    162                         clear_port_status_change(port, HUB_STATUS_C_PORT_ENABLE);
    163                         return EOK;
     249                        clear_port_status_change_nl(port, HUB_STATUS_C_PORT_ENABLE);
     250                        rc = EOK;
     251                        break;
    164252               
    165253                case USB_HUB_FEATURE_C_PORT_SUSPEND:
    166                         clear_port_status_change(port, HUB_STATUS_C_PORT_SUSPEND);
    167                         return EOK;
     254                        clear_port_status_change_nl(port, HUB_STATUS_C_PORT_SUSPEND);
     255                        rc = EOK;
     256                        break;
    168257                       
    169258                case USB_HUB_FEATURE_C_PORT_OVER_CURRENT:
    170                         clear_port_status_change(port, HUB_STATUS_C_PORT_OVER_CURRENT);
    171                         return EOK;
    172         }
    173        
     259                        clear_port_status_change_nl(port, HUB_STATUS_C_PORT_OVER_CURRENT);
     260                        rc = EOK;
     261                        break;
     262
     263                case USB_HUB_FEATURE_C_PORT_RESET:
     264                        clear_port_status_change_nl(port, HUB_STATUS_C_PORT_RESET);
     265                        rc = EOK;
     266                        break;
     267        }
     268       
     269        fibril_mutex_unlock(&port->guard);
     270
     271        return rc;
     272}
     273
     274static int get_bus_state(uint16_t portindex)
     275{
    174276        return ENOTSUP;
    175277}
    176278
    177 static int get_bus_state(uint16_t portindex)
    178 {
    179         return ENOTSUP;
    180 }
    181 
    182 static int get_hub_descriptor(uint8_t descriptor_type,
    183     uint8_t descriptor_index, uint16_t length)
    184 {
     279static int get_hub_descriptor(struct usbvirt_device *dev,
     280    uint8_t descriptor_index,
     281    uint8_t descriptor_type, uint16_t length)
     282{
     283        if (descriptor_type == USB_DESCTYPE_HUB) {
     284                int rc = dev->control_transfer_reply(dev, 0,
     285                    &hub_descriptor, hub_descriptor.length);
     286
     287                return rc;
     288
     289        }
     290
    185291        return ENOTSUP;
    186292}
     
    198304        _GET_PORT(port, portindex);
    199305       
     306        fibril_mutex_lock(&port->guard);
     307
    200308        uint32_t status;
    201309        status = MAKE_BYTE(
     
    225333        status |= (port->status_change << 16);
    226334       
     335        fibril_mutex_unlock(&port->guard);
     336
     337        dprintf(2, "GetPortStatus(port=%d, status=%u)\n", (int)portindex,
     338            (unsigned int) status);
    227339        return virthub_dev.control_transfer_reply(&virthub_dev, 0, &status, 4);
    228340}
     
    238350        _GET_PORT(port, portindex);
    239351       
     352        fibril_mutex_lock(&port->guard);
     353
     354        int rc = ENOTSUP;
     355
    240356        switch (feature) {
    241357                case USB_HUB_FEATURE_PORT_RESET:
    242358                        if (port->state != HUB_PORT_STATE_POWERED_OFF) {
    243                                 set_port_state(port, HUB_PORT_STATE_RESETTING);
    244                         }
    245                         return EOK;
     359                                set_port_state_nl(port, HUB_PORT_STATE_RESETTING);
     360                        }
     361                        rc = EOK;
     362                        break;
    246363               
    247364                case USB_HUB_FEATURE_PORT_SUSPEND:
    248365                        if (port->state == HUB_PORT_STATE_ENABLED) {
    249                                 set_port_state(port, HUB_PORT_STATE_SUSPENDED);
    250                         }
    251                         return EOK;
     366                                set_port_state_nl(port, HUB_PORT_STATE_SUSPENDED);
     367                        }
     368                        rc = EOK;
     369                        break;
    252370               
    253371                case USB_HUB_FEATURE_PORT_POWER:
    254372                        if (port->state == HUB_PORT_STATE_POWERED_OFF) {
    255                                 set_port_state(port, HUB_PORT_STATE_DISCONNECTED);
    256                         }
    257                         return EOK;
    258         }
    259         return ENOTSUP;
     373                                set_port_state_nl(port, HUB_PORT_STATE_DISCONNECTED);
     374                        }
     375                        rc = EOK;
     376                        break;
     377        }
     378
     379        fibril_mutex_unlock(&port->guard);
     380        return rc;
    260381}
    261382
     
    267388    usb_device_request_setup_packet_t *request, uint8_t *data)
    268389{       
    269         dprintf(2, "hub class request (%d)\n", (int) request->request);
     390        dprintf(2, "hub class request (%d)", (int) request->request);
    270391       
    271392        uint8_t recipient = request->request_type & 31;
     
    298419                       
    299420                case USB_HUB_REQUEST_GET_DESCRIPTOR:
    300                         return get_hub_descriptor(request->value_low,
     421                        return get_hub_descriptor(dev, request->value_low,
    301422                            request->value_high, request->length);
    302423                       
     
    316437                       
    317438                default:
     439                        dprintf(0, "WARN: unknown request (%d)!\n",
     440                            request->request);
    318441                        break;
    319442        }
     
    325448}
    326449
     450void clear_port_status_change_nl(hub_port_t *port, uint16_t change)
     451{
     452        port->status_change &= (~change);
     453        dprintf(2, "cleared port %d status change %d (%u)", port->index,
     454            (int)change, (unsigned int) port->status_change);
     455}
     456
     457void set_port_status_change_nl(hub_port_t *port, uint16_t change)
     458{
     459        port->status_change |= change;
     460        dprintf(2, "set port %d status change %d (%u)", port->index,
     461            (int)change, (unsigned int) port->status_change);
     462
     463}
     464
    327465void clear_port_status_change(hub_port_t *port, uint16_t change)
    328466{
    329         port->status_change &= (~change);
     467        fibril_mutex_lock(&port->guard);
     468        clear_port_status_change_nl(port, change);
     469        fibril_mutex_unlock(&port->guard);
    330470}
    331471
    332472void set_port_status_change(hub_port_t *port, uint16_t change)
    333473{
    334         port->status_change |= change;
     474        fibril_mutex_lock(&port->guard);
     475        set_port_status_change_nl(port, change);
     476        fibril_mutex_unlock(&port->guard);
    335477}
    336478
     
    350492                hub_port_t *port = &hub_dev.ports[i];
    351493               
     494                fibril_mutex_lock(&port->guard);
    352495                if (port->status_change != 0) {
    353496                        change_map |= (1 << (i + 1));
    354497                }
     498                fibril_mutex_unlock(&port->guard);
    355499        }
    356500       
  • uspace/drv/vhc/vhcd.h

    r84439d7 r75732da  
    3636#define VHCD_VHCD_H_
    3737
     38#include <usb/debug.h>
     39
    3840#define NAME "vhc"
    3941#define NAME_DEV "hcd-virt-dev"
     
    4345#define DEVMAP_PATH_DEV NAMESPACE "/" NAME_DEV
    4446
    45 extern int debug_level;
    46 void dprintf(int, const char *, ...);
     47#define dprintf(level, format, ...) \
     48        usb_dprintf(NAME, (level), format "\n", ##__VA_ARGS__)
    4749void dprintf_inval_call(int, ipc_call_t, ipcarg_t);
    4850
  • uspace/lib/c/generic/adt/char_map.c

    r84439d7 r75732da  
    9090        }
    9191
    92         map->items[map->next]->c = * identifier;
    93         ++ identifier;
    94         ++ map->next;
    95         if ((length > 1) || ((length == 0) && (*identifier))) {
     92        map->items[map->next]->c = *identifier;
     93        identifier++;
     94        map->next++;
     95        if ((length > 1) || ((length == 0) && *identifier)) {
    9696                map->items[map->next - 1]->value = CHAR_MAP_NULL;
    9797                return char_map_add_item(map->items[map->next - 1], identifier,
     
    142142    const int value)
    143143{
    144         if (char_map_is_valid(map) && (identifier) &&
    145             ((length) || (*identifier))) {
     144        if (char_map_is_valid(map) && identifier && (length || *identifier)) {
    146145                int index;
    147146
    148                 for (index = 0; index < map->next; ++ index) {
     147                for (index = 0; index < map->next; index++) {
    149148                        if (map->items[index]->c != *identifier)
    150149                                continue;
    151150                               
    152                         ++ identifier;
    153                         if((length > 1) || ((length == 0) && (*identifier))) {
     151                        identifier++;
     152                        if((length > 1) || ((length == 0) && *identifier)) {
    154153                                return char_map_add(map->items[index],
    155154                                    identifier, length ? length - 1 : 0, value);
     
    178177
    179178                map->magic = 0;
    180                 for (index = 0; index < map->next; ++index)
     179                for (index = 0; index < map->next; index++)
    181180                        char_map_destroy(map->items[index]);
    182181
     
    207206                return NULL;
    208207
    209         if (length || (*identifier)) {
     208        if (length || *identifier) {
    210209                int index;
    211210
    212                 for (index = 0; index < map->next; ++index) {
     211                for (index = 0; index < map->next; index++) {
    213212                        if (map->items[index]->c == *identifier) {
    214                                 ++identifier;
     213                                identifier++;
    215214                                if (length == 1)
    216215                                        return map->items[index];
  • uspace/lib/c/generic/devman.c

    r84439d7 r75732da  
    116116{
    117117        ipc_call_t answer;
    118         async_send_1(phone, DEVMAN_ADD_MATCH_ID, match_id->score, &answer);
     118        aid_t req = async_send_1(phone, DEVMAN_ADD_MATCH_ID, match_id->score, &answer);
    119119        int retval = async_data_write_start(phone, match_id->id, str_size(match_id->id));
    120         return retval; 
     120        async_wait_for(req, NULL);
     121        return retval;
    121122}
    122123
  • uspace/lib/c/include/adt/generic_field.h

    r84439d7 r75732da  
    9191                        } \
    9292                        field->items[field->next] = value; \
    93                         ++field->next; \
     93                        field->next++; \
    9494                        field->items[field->next] = NULL; \
    9595                        return field->next - 1; \
     
    108108                        int index; \
    109109                        field->magic = 0; \
    110                         for (index = 0; index < field->next; ++ index) { \
     110                        for (index = 0; index < field->next; index++) { \
    111111                                if (field->items[index]) \
    112112                                        free(field->items[index]); \
  • uspace/lib/c/include/errno.h

    r84439d7 r75732da  
    8383#define ENOTCONN        (-10057)
    8484
    85 /** The requested operation was not performed.
    86  *  Try again later.
    87  */
    88 #define TRY_AGAIN       (-11002)
     85/** The requested operation was not performed. Try again later. */
     86#define EAGAIN          (-11002)
    8987
    9088/** No data.
  • uspace/lib/c/include/ipc/dev_iface.h

    r84439d7 r75732da  
    5454        DEV_IFACE_ID(DEV_FIRST_CUSTOM_METHOD_IDX)
    5555
     56/*
     57 * The first argument is actually method (as the "real" method is used
     58 * for indexing into interfaces.
     59 */
     60
     61#define DEV_IPC_GET_ARG1(call) IPC_GET_ARG2((call))
     62#define DEV_IPC_GET_ARG2(call) IPC_GET_ARG3((call))
     63#define DEV_IPC_GET_ARG3(call) IPC_GET_ARG4((call))
     64#define DEV_IPC_GET_ARG4(call) IPC_GET_ARG5((call))
     65
    5666
    5767#endif
  • uspace/lib/c/include/ipc/vfs.h

    r84439d7 r75732da  
    3636#define LIBC_IPC_VFS_H_
    3737
     38#include <ipc/ipc.h>
    3839#include <sys/types.h>
    39 #include <ipc/ipc.h>
     40#include <bool.h>
    4041
    4142#define FS_NAME_MAXLEN  20
     
    5556        /** Unique identifier of the fs. */
    5657        char name[FS_NAME_MAXLEN + 1];
     58        bool concurrent_read_write;
     59        bool write_retains_size;
    5760} vfs_info_t;
    5861
  • uspace/lib/drv/generic/driver.c

    r84439d7 r75732da  
    381381}
    382382
     383/** Wrapper for child_device_register for devices with single match id.
     384 *
     385 * @param parent Parent device.
     386 * @param child_name Child device name.
     387 * @param child_match_id Child device match id.
     388 * @param child_match_score Child device match score.
     389 * @return Error code.
     390 */
     391int child_device_register_wrapper(device_t *parent, const char *child_name,
     392    const char *child_match_id, int child_match_score,
     393    devman_handle_t *child_handle)
     394{
     395        device_t *child = NULL;
     396        match_id_t *match_id = NULL;
     397        int rc;
     398
     399        child = create_device();
     400        if (child == NULL) {
     401                rc = ENOMEM;
     402                goto failure;
     403        }
     404
     405        child->name = child_name;
     406
     407        match_id = create_match_id();
     408        if (match_id == NULL) {
     409                rc = ENOMEM;
     410                goto failure;
     411        }
     412
     413        match_id->id = child_match_id;
     414        match_id->score = child_match_score;
     415        add_match_id(&child->match_ids, match_id);
     416
     417        rc = child_device_register(child, parent);
     418        if (EOK != rc)
     419                goto failure;
     420
     421        if (child_handle != NULL) {
     422                *child_handle = child->handle;
     423        }
     424        return EOK;
     425
     426failure:
     427        if (match_id != NULL) {
     428                match_id->id = NULL;
     429                delete_match_id(match_id);
     430        }
     431
     432        if (child != NULL) {
     433                child->name = NULL;
     434                delete_device(child);
     435        }
     436
     437        return rc;
     438}
     439
    383440int driver_main(driver_t *drv)
    384441{
  • uspace/lib/drv/generic/remote_usbhc.c

    r84439d7 r75732da  
    108108        }
    109109
    110         devman_handle_t handle = IPC_GET_ARG1(*call);
     110        devman_handle_t handle = DEV_IPC_GET_ARG1(*call);
    111111
    112112        usb_address_t address;
     
    122122    ipc_callid_t callid, ipc_call_t *call)
    123123{
    124         ipcarg_t buffer_hash = IPC_GET_ARG1(*call);
     124        ipcarg_t buffer_hash = DEV_IPC_GET_ARG1(*call);
    125125        async_transaction_t * trans = (async_transaction_t *)buffer_hash;
    126126        if (trans == NULL) {
     
    144144                accepted_size = trans->size;
    145145        }
    146         async_data_read_finalize(callid, trans->buffer, accepted_size);
     146        async_data_read_finalize(cid, trans->buffer, accepted_size);
    147147
    148148        ipc_answer_1(callid, EOK, accepted_size);
     
    211211        }
    212212
    213         usb_address_t address = (usb_address_t) IPC_GET_ARG1(*call);
    214         devman_handle_t handle = (devman_handle_t) IPC_GET_ARG2(*call);
     213        usb_address_t address = (usb_address_t) DEV_IPC_GET_ARG1(*call);
     214        devman_handle_t handle = (devman_handle_t) DEV_IPC_GET_ARG2(*call);
    215215
    216216        int rc = usb_iface->bind_address(device, address, handle);
     
    229229        }
    230230
    231         usb_address_t address = (usb_address_t) IPC_GET_ARG1(*call);
     231        usb_address_t address = (usb_address_t) DEV_IPC_GET_ARG1(*call);
    232232
    233233        int rc = usb_iface->release_address(device, address);
     
    275275        }
    276276
    277         size_t expected_len = IPC_GET_ARG3(*call);
     277        size_t expected_len = DEV_IPC_GET_ARG3(*call);
    278278        usb_target_t target = {
    279                 .address = IPC_GET_ARG1(*call),
    280                 .endpoint = IPC_GET_ARG2(*call)
     279                .address = DEV_IPC_GET_ARG1(*call),
     280                .endpoint = DEV_IPC_GET_ARG2(*call)
    281281        };
    282282
     
    327327        }
    328328
    329         size_t len = IPC_GET_ARG3(*call);
     329        size_t len = DEV_IPC_GET_ARG3(*call);
    330330        usb_target_t target = {
    331                 .address = IPC_GET_ARG1(*call),
    332                 .endpoint = IPC_GET_ARG2(*call)
     331                .address = DEV_IPC_GET_ARG1(*call),
     332                .endpoint = DEV_IPC_GET_ARG2(*call)
    333333        };
    334334
     
    384384
    385385        usb_target_t target = {
    386                 .address = IPC_GET_ARG1(*call),
    387                 .endpoint = IPC_GET_ARG2(*call)
     386                .address = DEV_IPC_GET_ARG1(*call),
     387                .endpoint = DEV_IPC_GET_ARG2(*call)
    388388        };
    389389
  • uspace/lib/drv/include/driver.h

    r84439d7 r75732da  
    199199
    200200int child_device_register(device_t *, device_t *);
     201int child_device_register_wrapper(device_t *, const char *, const char *, int,
     202    devman_handle_t *);
    201203
    202204
  • uspace/lib/usb/Makefile

    r84439d7 r75732da  
    3333
    3434SOURCES = \
     35        src/addrkeep.c \
     36        src/class.c \
     37        src/debug.c \
     38        src/drvpsync.c \
    3539        src/hcdhubd.c \
    3640        src/hcdrv.c \
     41        src/hidparser.c \
    3742        src/localdrv.c \
     43        src/recognise.c \
    3844        src/remotedrv.c \
    3945        src/usb.c \
     46        src/usbdrvreq.c \
    4047        src/usbdrv.c
    4148
  • uspace/lib/usb/include/usb/classes/classes.h

    r84439d7 r75732da  
    6060} usb_class_t;
    6161
     62const char *usb_str_class(usb_class_t);
    6263
    6364#endif
  • uspace/lib/usb/include/usb/classes/hid.h

    r84439d7 r75732da  
    3636#define LIBUSB_HID_H_
    3737
     38#include <usb/usb.h>
     39#include <driver.h>
     40#include <usb/classes/hidparser.h>
     41
    3842/** USB/HID device requests. */
    3943typedef enum {
     
    5458} usb_hid_protocol_t;
    5559
     60/** Part of standard USB HID descriptor specifying one class descriptor.
     61 *
     62 * (See HID Specification, p.22)
     63 */
     64typedef struct {
     65        /** Type of class descriptor (Report or Physical). */
     66        uint8_t class_descriptor_type;
     67        /** Length of class descriptor. */
     68        uint16_t class_descriptor_length;
     69} __attribute__ ((packed)) usb_standard_hid_descriptor_class_item_t;
     70
     71/** Standard USB HID descriptor.
     72 *
     73 * (See HID Specification, p.22)
     74 *
     75 * It is actually only the "header" of the descriptor, as it may have arbitrary
     76 * length if more than one class descritor is provided.
     77 */
     78typedef struct {
     79        /** Size of this descriptor in bytes. */
     80        uint8_t length;
     81        /** Descriptor type (USB_DESCTYPE_HID). */
     82        uint8_t descriptor_type;
     83        /** HID Class Specification release. */
     84        uint16_t spec_release;
     85        /** Country code of localized hardware. */
     86        uint8_t country_code;
     87        /** Total number of class (i.e. Report and Physical) descriptors. */
     88        uint8_t class_count;
     89        /** First mandatory class descriptor info. */
     90        usb_standard_hid_descriptor_class_item_t class_descriptor;
     91} __attribute__ ((packed)) usb_standard_hid_descriptor_t;
     92
     93
     94/**
     95 * @brief USB/HID keyboard device type.
     96 *
     97 * Quite dummy right now.
     98 */
     99typedef struct {
     100        device_t *device;
     101        usb_address_t address;
     102        usb_endpoint_t poll_endpoint;
     103        usb_hid_report_parser_t *parser;
     104} usb_hid_dev_kbd_t;
     105
    56106#endif
    57107/**
  • uspace/lib/usb/include/usb/classes/hub.h

    r84439d7 r75732da  
    177177
    178178/** @brief hub class request codes*/
     179/// \TODO these are duplicit to standart descriptors
    179180typedef enum {
    180181    /**  */
     
    213214usb_hub_descriptor_t * usb_deserialize_hub_desriptor(void * sdescriptor);
    214215
    215 /**
    216  * @brief create hub structure instance
    217  *
    218  * @param device
    219  * @return
    220  */
    221 usb_hcd_hub_info_t * usb_create_hub_info(device_t * device);
    222216
    223217
  • uspace/lib/usb/include/usb/devreq.h

    r84439d7 r75732da  
    3838#include <ipc/ipc.h>
    3939#include <async.h>
     40#include <usb/usb.h>
     41#include <usb/descriptor.h>
    4042
    4143/** Standard device request. */
     
    8385} __attribute__ ((packed)) usb_device_request_setup_packet_t;
    8486
     87int usb_drv_req_set_address(int, usb_address_t, usb_address_t);
     88int usb_drv_req_get_device_descriptor(int, usb_address_t,
     89    usb_standard_device_descriptor_t *);
     90int usb_drv_req_get_bare_configuration_descriptor(int, usb_address_t, int,
     91    usb_standard_configuration_descriptor_t *);
     92int usb_drv_req_get_full_configuration_descriptor(int, usb_address_t, int,
     93    void *, size_t, size_t *);
     94
     95
    8596#endif
    8697/**
  • uspace/lib/usb/include/usb/hcdhubd.h

    r84439d7 r75732da  
    6565} usb_hcd_attached_device_info_t;
    6666
    67 /** Information about attached hub. */
    68 typedef struct {
    69         /** Number of ports. */
    70         size_t port_count;
    71         /** General device info. */
    72         usb_hcd_attached_device_info_t *device;
    73         /** Link to other hubs. */
    74         link_t link;
    75 } usb_hcd_hub_info_t;
    7667
    7768/** Host controller device. */
  • uspace/lib/usb/include/usb/usb.h

    r84439d7 r75732da  
    6969typedef int usb_address_t;
    7070
     71/** Default USB address. */
     72#define USB_ADDRESS_DEFAULT 0
     73/** Maximum address number in USB 1.1. */
     74#define USB11_ADDRESS_MAX 128
     75
    7176/** USB endpoint number type.
    7277 * Negative values could be used to indicate error.
  • uspace/lib/usb/include/usb/usbdrv.h

    r84439d7 r75732da  
    3636#define LIBUSB_USBDRV_H_
    3737
    38 #include "usb.h"
     38#include <usb/usb.h>
    3939#include <driver.h>
     40#include <usb/devreq.h>
     41#include <usb/descriptor.h>
    4042
    4143int usb_drv_hc_connect(device_t *, unsigned int);
     
    5456    void *, size_t, size_t *, usb_handle_t *);
    5557
     58int usb_drv_psync_interrupt_out(int, usb_target_t, void *, size_t);
     59int usb_drv_psync_interrupt_in(int, usb_target_t, void *, size_t, size_t *);
     60
     61
     62
    5663int usb_drv_async_control_write_setup(int, usb_target_t,
    5764    void *, size_t, usb_handle_t *);
     
    6067int usb_drv_async_control_write_status(int, usb_target_t,
    6168    usb_handle_t *);
     69
     70int usb_drv_psync_control_write_setup(int, usb_target_t, void *, size_t);
     71int usb_drv_psync_control_write_data(int, usb_target_t, void *, size_t);
     72int usb_drv_psync_control_write_status(int, usb_target_t);
     73
     74int usb_drv_psync_control_write(int, usb_target_t,
     75    void *, size_t, void *, size_t);
     76
    6277
    6378int usb_drv_async_control_read_setup(int, usb_target_t,
     
    6883    usb_handle_t *);
    6984
     85int usb_drv_psync_control_read_setup(int, usb_target_t, void *, size_t);
     86int usb_drv_psync_control_read_data(int, usb_target_t, void *, size_t, size_t *);
     87int usb_drv_psync_control_read_status(int, usb_target_t);
     88
     89int usb_drv_psync_control_read(int, usb_target_t,
     90    void *, size_t, void *, size_t, size_t *);
     91
     92
     93
    7094int usb_drv_async_wait_for(usb_handle_t);
     95
     96int usb_drv_create_device_match_ids(int, match_id_list_t *, usb_address_t);
     97int usb_drv_register_child_in_devman(int, device_t *, usb_address_t,
     98    devman_handle_t *);
     99
    71100
    72101#endif
  • uspace/lib/usb/src/remotedrv.c

    r84439d7 r75732da  
    300300 */
    301301static void remote_in_callback(usb_hc_device_t *hc,
    302     usb_transaction_outcome_t outcome, size_t actual_size, void *arg)
     302    size_t actual_size, usb_transaction_outcome_t outcome, void *arg)
    303303{
    304304        transfer_info_t *transfer = (transfer_info_t *) arg;
  • uspace/lib/usb/src/usbdrv.c

    r84439d7 r75732da  
    3636#include <usbhc_iface.h>
    3737#include <errno.h>
     38#include <str_error.h>
    3839
    3940/** Information about pending transaction on HC. */
     
    7172        devman_handle_t handle;
    7273
    73         rc = devman_device_get_handle("/vhc", &handle, 0);
     74        rc = devman_device_get_handle("/virt/usbhc", &handle, 0);
    7475        if (rc != EOK) {
    7576                return rc;
     
    9091{
    9192        ipcarg_t address;
    92         int rc = async_req_1_1(phone, IPC_M_USBHC_GET_ADDRESS,
     93        int rc = async_req_2_1(phone, DEV_IFACE_ID(USBHC_DEV_IFACE),
     94            IPC_M_USBHC_GET_ADDRESS,
    9395            dev->handle, &address);
    9496
    9597        if (rc != EOK) {
     98                printf("usb_drv_get_my_address over %d failed: %s\n", phone, str_error(rc));
    9699                return rc;
    97100        }
     
    107110int usb_drv_reserve_default_address(int phone)
    108111{
    109         return async_req_0_0(phone, IPC_M_USBHC_RESERVE_DEFAULT_ADDRESS);
     112        return async_req_1_0(phone, DEV_IFACE_ID(USBHC_DEV_IFACE),
     113            IPC_M_USBHC_RESERVE_DEFAULT_ADDRESS);
    110114}
    111115
     
    117121int usb_drv_release_default_address(int phone)
    118122{
    119         return async_req_0_0(phone, IPC_M_USBHC_RELEASE_DEFAULT_ADDRESS);
     123        return async_req_1_0(phone, DEV_IFACE_ID(USBHC_DEV_IFACE),
     124            IPC_M_USBHC_RELEASE_DEFAULT_ADDRESS);
    120125}
    121126
     
    128133{
    129134        ipcarg_t address;
    130         int rc = async_req_0_1(phone, IPC_M_USBHC_REQUEST_ADDRESS, &address);
     135        int rc = async_req_1_1(phone, DEV_IFACE_ID(USBHC_DEV_IFACE),
     136            IPC_M_USBHC_REQUEST_ADDRESS, &address);
    131137        if (rc != EOK) {
    132138                return rc;
     
    146152    devman_handle_t handle)
    147153{
    148         int rc = async_req_2_0(phone, IPC_M_USBHC_BIND_ADDRESS,
     154        int rc = async_req_3_0(phone, DEV_IFACE_ID(USBHC_DEV_IFACE),
     155            IPC_M_USBHC_BIND_ADDRESS,
    149156            address, handle);
    150157
     
    160167int usb_drv_release_address(int phone, usb_address_t address)
    161168{
    162         return async_req_1_0(phone, IPC_M_USBHC_RELEASE_ADDRESS, address);
     169        return async_req_2_0(phone, DEV_IFACE_ID(USBHC_DEV_IFACE),
     170            IPC_M_USBHC_RELEASE_ADDRESS, address);
    163171}
    164172
  • uspace/lib/usbvirt/src/callback.c

    r84439d7 r75732da  
    153153         * If the request was processed, we will send data back.
    154154         */
    155         if (rc == EOK) {
     155        if ((rc == EOK) && (expected_len > 0)) {
    156156                size_t receive_len;
    157157                ipc_callid_t callid;
  • uspace/lib/usbvirt/src/main.c

    r84439d7 r75732da  
    183183/** Create necessary phones for communication with virtual HCD.
    184184 * This function wraps following calls:
    185  * -# open <code>/dev/devices/\\vhc</code> for reading
     185 * -# open <code>/dev/devices/\\virt\\usbhc for reading
    186186 * -# access phone of file opened in previous step
    187187 * -# create callback through just opened phone
     
    203203        }
    204204       
    205         const char *vhc_path = "/vhc";
     205        const char *vhc_path = "/virt/usbhc";
    206206        int rc;
    207207        devman_handle_t handle;
  • uspace/lib/usbvirt/src/transaction.c

    r84439d7 r75732da  
    183183                                actual_size = size;
    184184                        }
     185                        device->lib_debug(device, 1, USBVIRT_DEBUGTAG_TRANSACTION,
     186                            "in transaction: will copy %zu bytes", actual_size);
    185187                        if (actual_size > 0) {
    186188                                memcpy(buffer, transfer->data, actual_size);
  • uspace/srv/devman/devman.c

    r84439d7 r75732da  
    516516/** Notify driver about the devices to which it was assigned.
    517517 *
    518  * The driver's mutex must be locked.
    519  *
    520518 * @param driver        The driver to which the devices are passed.
    521519 */
     
    526524        int phone;
    527525
    528         printf(NAME ": pass_devices_to_driver\n");
    529 
    530         phone = ipc_connect_me_to(driver->phone, DRIVER_DEVMAN, 0, 0);
    531         if (phone > 0) {
    532                
     526        printf(NAME ": pass_devices_to_driver(`%s')\n", driver->name);
     527
     528        fibril_mutex_lock(&driver->driver_mutex);
     529
     530        phone = async_connect_me_to(driver->phone, DRIVER_DEVMAN, 0, 0);
     531
     532        if (phone < 0) {
     533                fibril_mutex_unlock(&driver->driver_mutex);
     534                return;
     535        }
     536
     537        /*
     538         * Go through devices list as long as there is some device
     539         * that has not been passed to the driver.
     540         */
     541        link = driver->devices.next;
     542        while (link != &driver->devices) {
     543                dev = list_get_instance(link, node_t, driver_devices);
     544                if (dev->passed_to_driver) {
     545                        link = link->next;
     546                        continue;
     547                }
     548
     549                /*
     550                 * We remove the device from the list to allow safe adding
     551                 * of new devices (no one will touch our item this way).
     552                 */
     553                list_remove(link);
     554
     555                /*
     556                 * Unlock to avoid deadlock when adding device
     557                 * handled by itself.
     558                 */
     559                fibril_mutex_unlock(&driver->driver_mutex);
     560
     561                add_device(phone, driver, dev, tree);
     562
     563                /*
     564                 * Lock again as we will work with driver's
     565                 * structure.
     566                 */
     567                fibril_mutex_lock(&driver->driver_mutex);
     568
     569                /*
     570                 * Insert the device back.
     571                 * The order is not relevant here so no harm is done
     572                 * (actually, the order would be preserved in most cases).
     573                 */
     574                list_append(link, &driver->devices);
     575
     576                /*
     577                 * Restart the cycle to go through all devices again.
     578                 */
    533579                link = driver->devices.next;
    534                 while (link != &driver->devices) {
    535                         dev = list_get_instance(link, node_t, driver_devices);
    536                         add_device(phone, driver, dev, tree);
    537                         link = link->next;
    538                 }
    539                
    540                 ipc_hangup(phone);
    541         }
     580        }
     581
     582        ipc_hangup(phone);
     583
     584        /*
     585         * Once we passed all devices to the driver, we need to mark the
     586         * driver as running.
     587         * It is vital to do it here and inside critical section.
     588         *
     589         * If we would change the state earlier, other devices added to
     590         * the driver would be added to the device list and started
     591         * immediately and possibly started here as well.
     592         */
     593        printf(NAME ": driver %s goes into running state.\n", driver->name);
     594        driver->state = DRIVER_RUNNING;
     595
     596        fibril_mutex_unlock(&driver->driver_mutex);
    542597}
    543598
     
    553608void initialize_running_driver(driver_t *driver, dev_tree_t *tree)
    554609{
    555         printf(NAME ": initialize_running_driver\n");
    556         fibril_mutex_lock(&driver->driver_mutex);
     610        printf(NAME ": initialize_running_driver (`%s')\n", driver->name);
    557611       
    558612        /*
     
    561615         */
    562616        pass_devices_to_driver(driver, tree);
    563        
    564         /* Change driver's state to running. */
    565         driver->state = DRIVER_RUNNING;
    566        
    567         fibril_mutex_unlock(&driver->driver_mutex);
    568617}
    569618
     
    637686}
    638687
    639 
    640688/** Pass a device to running driver.
    641689 *
     
    645693void add_device(int phone, driver_t *drv, node_t *node, dev_tree_t *tree)
    646694{
    647         printf(NAME ": add_device\n");
     695        /*
     696         * We do not expect to have driver's mutex locked as we do not
     697         * access any structures that would affect driver_t.
     698         */
     699        printf(NAME ": add_device (driver `%s', device `%s')\n", drv->name,
     700            node->name);
    648701       
    649702        ipcarg_t rc;
     
    657710                parent_handle = 0;
    658711        }
     712
    659713        aid_t req = async_send_2(phone, DRIVER_ADD_DEVICE, node->handle,
    660714            parent_handle, &answer);
     
    666720                /* TODO handle error */
    667721        }
    668        
     722
    669723        /* Wait for answer from the driver. */
    670724        async_wait_for(req, &rc);
     725
    671726        switch(rc) {
    672727        case EOK:
     
    681736        }
    682737       
     738        node->passed_to_driver = true;
     739
    683740        return;
    684741}
     
    706763        attach_driver(node, drv);
    707764       
     765        fibril_mutex_lock(&drv->driver_mutex);
    708766        if (drv->state == DRIVER_NOT_STARTED) {
    709767                /* Start the driver. */
    710768                start_driver(drv);
    711769        }
    712        
    713         if (drv->state == DRIVER_RUNNING) {
     770        bool is_running = drv->state == DRIVER_RUNNING;
     771        fibril_mutex_unlock(&drv->driver_mutex);
     772
     773        if (is_running) {
    714774                /* Notify the driver about the new device. */
    715                 int phone = ipc_connect_me_to(drv->phone, DRIVER_DEVMAN, 0, 0);
     775                int phone = async_connect_me_to(drv->phone, DRIVER_DEVMAN, 0, 0);
    716776                if (phone > 0) {
    717777                        add_device(phone, drv, node, tree);
     
    875935        node->name = dev_name;
    876936        if (!set_dev_path(node, parent)) {
    877                 fibril_rwlock_write_unlock(&tree->rwlock);
    878937                return false;
    879938        }
     
    10971156        while (link != &class_list->classes) {
    10981157                cl = list_get_instance(link, dev_class_t, link);
    1099                 if (str_cmp(cl->name, class_name) == 0)
     1158                if (str_cmp(cl->name, class_name) == 0) {
    11001159                        return cl;
     1160                }
     1161                link = link->next;
    11011162        }
    11021163       
  • uspace/srv/devman/devman.h

    r84439d7 r75732da  
    168168         */
    169169        link_t devmap_link;
     170
     171        /**
     172         * Whether this device was already passed to the driver.
     173         */
     174        bool passed_to_driver;
    170175};
    171176
  • uspace/srv/devman/main.c

    r84439d7 r75732da  
    197197}
    198198
     199static int assign_driver_fibril(void *arg)
     200{
     201        node_t *node = (node_t *) arg;
     202        assign_driver(node, &drivers_list, &device_tree);
     203        return EOK;
     204}
     205
    199206/** Handle child device registration.
    200207 *
     
    237244       
    238245        devman_receive_match_ids(match_count, &node->match_ids);
    239        
     246
     247        /*
     248         * Try to find a suitable driver and assign it to the device.  We do
     249         * not want to block the current fibril that is used for processing
     250         * incoming calls: we will launch a separate fibril to handle the
     251         * driver assigning. That is because assign_driver can actually include
     252         * task spawning which could take some time.
     253         */
     254        fid_t assign_fibril = fibril_create(assign_driver_fibril, node);
     255        if (assign_fibril == 0) {
     256                /*
     257                 * Fallback in case we are out of memory.
     258                 * Probably not needed as we will die soon anyway ;-).
     259                 */
     260                (void) assign_driver_fibril(node);
     261        } else {
     262                fibril_add_ready(assign_fibril);
     263        }
     264
    240265        /* Return device handle to parent's driver. */
    241266        ipc_answer_1(callid, EOK, node->handle);
    242        
    243         /* Try to find suitable driver and assign it to the device. */
    244         assign_driver(node, &drivers_list, &device_tree);
    245267}
    246268
     
    297319        printf(NAME ": device '%s' added to class '%s', class name '%s' was "
    298320            "asigned to it\n", dev->pathname, class_name, class_info->dev_name);
    299        
     321
    300322        ipc_answer_0(callid, EOK);
    301323}
  • uspace/srv/devman/match.c

    r84439d7 r75732da  
    4646        if (str_cmp(driver->id, device->id) == 0) {
    4747                /*
    48                  * The strings matches, return their score multiplied.
     48                 * The strings match, return the product of their scores.
    4949                 */
    5050                return driver->score * device->score;
     
    6666       
    6767        /*
    68          * Go through all pairs, return the highest score obtainetd.
     68         * Go through all pairs, return the highest score obtained.
    6969         */
    7070        int highest_score = 0;
  • uspace/srv/fs/devfs/devfs.c

    r84439d7 r75732da  
    5353static vfs_info_t devfs_vfs_info = {
    5454        .name = NAME,
     55        .concurrent_read_write = false,
     56        .write_retains_size = false,
    5557};
    5658
  • uspace/srv/fs/fat/fat.c

    r84439d7 r75732da  
    5252vfs_info_t fat_vfs_info = {
    5353        .name = NAME,
     54        .concurrent_read_write = false,
     55        .write_retains_size = false,   
    5456};
    5557
  • uspace/srv/fs/tmpfs/tmpfs.c

    r84439d7 r75732da  
    5757vfs_info_t tmpfs_vfs_info = {
    5858        .name = NAME,
     59        .concurrent_read_write = false,
     60        .write_retains_size = false,
    5961};
    6062
  • uspace/srv/net/il/arp/arp.c

    r84439d7 r75732da  
    7272#define NAME  "arp"
    7373
     74/** Number of microseconds to wait for an ARP reply. */
     75#define ARP_TRANS_WAIT  1000000
     76
    7477/** ARP global data. */
    7578arp_globals_t arp_globals;
     
    7780DEVICE_MAP_IMPLEMENT(arp_cache, arp_device_t);
    7881INT_MAP_IMPLEMENT(arp_protos, arp_proto_t);
    79 GENERIC_CHAR_MAP_IMPLEMENT(arp_addr, measured_string_t);
     82GENERIC_CHAR_MAP_IMPLEMENT(arp_addr, arp_trans_t);
     83
     84static void arp_clear_trans(arp_trans_t *trans)
     85{
     86        if (trans->hw_addr) {
     87                free(trans->hw_addr);
     88                trans->hw_addr = NULL;
     89        }
     90        fibril_condvar_broadcast(&trans->cv);
     91}
     92
     93static void arp_clear_addr(arp_addr_t *addresses)
     94{
     95        int count;
     96        arp_trans_t *trans;
     97
     98        for (count = arp_addr_count(addresses) - 1; count >= 0; count--) {
     99                trans = arp_addr_items_get_index(&addresses->values, count);
     100                if (trans)
     101                        arp_clear_trans(trans);
     102        }
     103}
     104
    80105
    81106/** Clears the device specific data.
     
    96121                        if (proto->addr_data)
    97122                                free(proto->addr_data);
     123                        arp_clear_addr(&proto->addresses);
    98124                        arp_addr_destroy(&proto->addresses);
    99125                }
     
    107133        arp_device_t *device;
    108134
    109         fibril_rwlock_write_lock(&arp_globals.lock);
     135        fibril_mutex_lock(&arp_globals.lock);
    110136        for (count = arp_cache_count(&arp_globals.cache) - 1; count >= 0;
    111137            count--) {
     
    120146        }
    121147        arp_cache_clear(&arp_globals.cache);
    122         fibril_rwlock_write_unlock(&arp_globals.lock);
     148        fibril_mutex_unlock(&arp_globals.lock);
    123149        printf("Cache cleaned\n");
    124150        return EOK;
     
    130156        arp_device_t *device;
    131157        arp_proto_t *proto;
    132 
    133         fibril_rwlock_write_lock(&arp_globals.lock);
     158        arp_trans_t *trans;
     159
     160        fibril_mutex_lock(&arp_globals.lock);
    134161        device = arp_cache_find(&arp_globals.cache, device_id);
    135162        if (!device) {
    136                 fibril_rwlock_write_unlock(&arp_globals.lock);
     163                fibril_mutex_unlock(&arp_globals.lock);
    137164                return ENOENT;
    138165        }
    139166        proto = arp_protos_find(&device->protos, protocol);
    140167        if (!proto) {
    141                 fibril_rwlock_write_unlock(&arp_globals.lock);
     168                fibril_mutex_unlock(&arp_globals.lock);
    142169                return ENOENT;
    143170        }
     171        trans = arp_addr_find(&proto->addresses, address->value, address->length);
     172        if (trans)
     173                arp_clear_trans(trans);
    144174        arp_addr_exclude(&proto->addresses, address->value, address->length);
    145         fibril_rwlock_write_unlock(&arp_globals.lock);
     175        fibril_mutex_unlock(&arp_globals.lock);
    146176        return EOK;
    147177}
     
    152182        arp_device_t *device;
    153183
    154         fibril_rwlock_write_lock(&arp_globals.lock);
     184        fibril_mutex_lock(&arp_globals.lock);
    155185        device = arp_cache_find(&arp_globals.cache, device_id);
    156186        if (!device) {
    157                 fibril_rwlock_write_unlock(&arp_globals.lock);
     187                fibril_mutex_unlock(&arp_globals.lock);
    158188                return ENOENT;
    159189        }
    160190        arp_clear_device(device);
    161191        printf("Device %d cleared\n", device_id);
    162         fibril_rwlock_write_unlock(&arp_globals.lock);
     192        fibril_mutex_unlock(&arp_globals.lock);
    163193        return EOK;
    164194}
     
    221251        int rc;
    222252
    223         fibril_rwlock_write_lock(&arp_globals.lock);
     253        fibril_mutex_lock(&arp_globals.lock);
    224254
    225255        /* An existing device? */
     
    229259                if (device->service != service) {
    230260                        printf("Device %d already exists\n", device->device_id);
    231                         fibril_rwlock_write_unlock(&arp_globals.lock);
     261                        fibril_mutex_unlock(&arp_globals.lock);
    232262                        return EEXIST;
    233263                }
     
    241271                        rc = arp_proto_create(&proto, protocol, address);
    242272                        if (rc != EOK) {
    243                                 fibril_rwlock_write_unlock(&arp_globals.lock);
     273                                fibril_mutex_unlock(&arp_globals.lock);
    244274                                return rc;
    245275                        }
     
    247277                            proto);
    248278                        if (index < 0) {
    249                                 fibril_rwlock_write_unlock(&arp_globals.lock);
     279                                fibril_mutex_unlock(&arp_globals.lock);
    250280                                free(proto);
    251281                                return index;
     
    262292                device = (arp_device_t *) malloc(sizeof(arp_device_t));
    263293                if (!device) {
    264                         fibril_rwlock_write_unlock(&arp_globals.lock);
     294                        fibril_mutex_unlock(&arp_globals.lock);
    265295                        return ENOMEM;
    266296                }
     
    269299                rc = arp_protos_initialize(&device->protos);
    270300                if (rc != EOK) {
    271                         fibril_rwlock_write_unlock(&arp_globals.lock);
     301                        fibril_mutex_unlock(&arp_globals.lock);
    272302                        free(device);
    273303                        return rc;
     
    275305                rc = arp_proto_create(&proto, protocol, address);
    276306                if (rc != EOK) {
    277                         fibril_rwlock_write_unlock(&arp_globals.lock);
     307                        fibril_mutex_unlock(&arp_globals.lock);
    278308                        free(device);
    279309                        return rc;
     
    281311                index = arp_protos_add(&device->protos, proto->service, proto);
    282312                if (index < 0) {
    283                         fibril_rwlock_write_unlock(&arp_globals.lock);
     313                        fibril_mutex_unlock(&arp_globals.lock);
    284314                        arp_protos_destroy(&device->protos);
    285315                        free(device);
     
    293323                    arp_globals.client_connection);
    294324                if (device->phone < 0) {
    295                         fibril_rwlock_write_unlock(&arp_globals.lock);
     325                        fibril_mutex_unlock(&arp_globals.lock);
    296326                        arp_protos_destroy(&device->protos);
    297327                        free(device);
     
    303333                    &device->packet_dimension);
    304334                if (rc != EOK) {
    305                         fibril_rwlock_write_unlock(&arp_globals.lock);
     335                        fibril_mutex_unlock(&arp_globals.lock);
    306336                        arp_protos_destroy(&device->protos);
    307337                        free(device);
     
    313343                    &device->addr_data);
    314344                if (rc != EOK) {
    315                         fibril_rwlock_write_unlock(&arp_globals.lock);
     345                        fibril_mutex_unlock(&arp_globals.lock);
    316346                        arp_protos_destroy(&device->protos);
    317347                        free(device);
     
    323353                    &device->broadcast_addr, &device->broadcast_data);
    324354                if (rc != EOK) {
    325                         fibril_rwlock_write_unlock(&arp_globals.lock);
     355                        fibril_mutex_unlock(&arp_globals.lock);
    326356                        free(device->addr);
    327357                        free(device->addr_data);
     
    334364                    device);
    335365                if (rc != EOK) {
    336                         fibril_rwlock_write_unlock(&arp_globals.lock);
     366                        fibril_mutex_unlock(&arp_globals.lock);
    337367                        free(device->addr);
    338368                        free(device->addr_data);
     
    347377                    device->service, protocol);
    348378        }
    349         fibril_rwlock_write_unlock(&arp_globals.lock);
     379        fibril_mutex_unlock(&arp_globals.lock);
    350380       
    351381        return EOK;
     
    363393        int rc;
    364394
    365         fibril_rwlock_initialize(&arp_globals.lock);
    366         fibril_rwlock_write_lock(&arp_globals.lock);
     395        fibril_mutex_initialize(&arp_globals.lock);
     396        fibril_mutex_lock(&arp_globals.lock);
    367397        arp_globals.client_connection = client_connection;
    368398        rc = arp_cache_initialize(&arp_globals.cache);
    369         fibril_rwlock_write_unlock(&arp_globals.lock);
     399        fibril_mutex_unlock(&arp_globals.lock);
    370400       
    371401        return rc;
     
    383413        arp_device_t *device;
    384414
    385         fibril_rwlock_write_lock(&arp_globals.lock);
     415        fibril_mutex_lock(&arp_globals.lock);
    386416        device = arp_cache_find(&arp_globals.cache, device_id);
    387417        if (!device) {
    388                 fibril_rwlock_write_unlock(&arp_globals.lock);
     418                fibril_mutex_unlock(&arp_globals.lock);
    389419                return ENOENT;
    390420        }
    391421        device->packet_dimension.content = mtu;
    392         fibril_rwlock_write_unlock(&arp_globals.lock);
     422        fibril_mutex_unlock(&arp_globals.lock);
    393423        printf("arp - device %d changed mtu to %zu\n\n", device_id, mtu);
    394424        return EOK;
     
    421451        arp_device_t *device;
    422452        arp_proto_t *proto;
    423         measured_string_t *hw_source;
     453        arp_trans_t *trans;
    424454        uint8_t *src_hw;
    425455        uint8_t *src_proto;
     
    452482        des_hw = src_proto + header->protocol_length;
    453483        des_proto = des_hw + header->hardware_length;
    454         hw_source = arp_addr_find(&proto->addresses, (char *) src_proto,
     484        trans = arp_addr_find(&proto->addresses, (char *) src_proto,
    455485            CONVERT_SIZE(uint8_t, char, header->protocol_length));
    456486        /* Exists? */
    457         if (hw_source) {
    458                 if (hw_source->length != CONVERT_SIZE(uint8_t, char,
     487        if (trans && trans->hw_addr) {
     488                if (trans->hw_addr->length != CONVERT_SIZE(uint8_t, char,
    459489                    header->hardware_length)) {
    460490                        return EINVAL;
    461491                }
    462                 memcpy(hw_source->value, src_hw, hw_source->length);
     492                memcpy(trans->hw_addr->value, src_hw, trans->hw_addr->length);
    463493        }
    464494        /* Is my protocol address? */
     
    470500            proto->addr->length)) {
    471501                /* Not already updated? */
    472                 if (!hw_source) {
    473                         hw_source = measured_string_create_bulk((char *) src_hw,
    474                             CONVERT_SIZE(uint8_t, char,
     502                if (!trans) {
     503                        trans = (arp_trans_t *) malloc(sizeof(arp_trans_t));
     504                        if (!trans)
     505                                return ENOMEM;
     506                        trans->hw_addr = NULL;
     507                        fibril_condvar_initialize(&trans->cv);
     508                        rc = arp_addr_add(&proto->addresses, (char *) src_proto,
     509                            CONVERT_SIZE(uint8_t, char, header->protocol_length),
     510                            trans);
     511                        if (rc != EOK) {
     512                                /* The generic char map has already freed trans! */
     513                                return rc;
     514                        }
     515                }
     516                if (!trans->hw_addr) {
     517                        trans->hw_addr = measured_string_create_bulk(
     518                            (char *) src_hw, CONVERT_SIZE(uint8_t, char,
    475519                            header->hardware_length));
    476                         if (!hw_source)
     520                        if (!trans->hw_addr)
    477521                                return ENOMEM;
    478522
    479                         rc = arp_addr_add(&proto->addresses, (char *) src_proto,
    480                             CONVERT_SIZE(uint8_t, char,
    481                             header->protocol_length), hw_source);
    482                         if (rc != EOK)
    483                                 return rc;
     523                        /* Notify the fibrils that wait for the translation. */
     524                        fibril_condvar_broadcast(&trans->cv);
    484525                }
    485526                if (ntohs(header->operation) == ARPOP_REQUEST) {
     
    490531                        memcpy(src_hw, device->addr->value,
    491532                            device->packet_dimension.addr_len);
    492                         memcpy(des_hw, hw_source->value,
     533                        memcpy(des_hw, trans->hw_addr->value,
    493534                            header->hardware_length);
    494535                       
     
    516557 * @param[in] protocol  The protocol service.
    517558 * @param[in] target    The target protocol address.
    518  * @return              The hardware address of the target.
    519  * @return              NULL if the target parameter is NULL.
    520  * @return              NULL if the device is not found.
    521  * @return              NULL if the device packet is too small to send a
    522  *                      request.
    523  * @return              NULL if the hardware address is not found in the cache.
    524  */
    525 static measured_string_t *
     559 * @param[out] translation Where the hardware address of the target is stored.
     560 * @return              EOK on success.
     561 * @return              EAGAIN if the caller should try again.
     562 * @return              Other error codes in case of error.
     563 */
     564static int
    526565arp_translate_message(device_id_t device_id, services_t protocol,
    527     measured_string_t *target)
     566    measured_string_t *target, measured_string_t **translation)
    528567{
    529568        arp_device_t *device;
    530569        arp_proto_t *proto;
    531         measured_string_t *addr;
     570        arp_trans_t *trans;
    532571        size_t length;
    533572        packet_t *packet;
    534573        arp_header_t *header;
    535 
    536         if (!target)
    537                 return NULL;
     574        bool retry = false;
     575        int rc;
     576
     577restart:
     578        if (!target || !translation)
     579                return EBADMEM;
    538580
    539581        device = arp_cache_find(&arp_globals.cache, device_id);
    540582        if (!device)
    541                 return NULL;
     583                return ENOENT;
    542584
    543585        proto = arp_protos_find(&device->protos, protocol);
    544586        if (!proto || (proto->addr->length != target->length))
    545                 return NULL;
    546 
    547         addr = arp_addr_find(&proto->addresses, target->value, target->length);
    548         if (addr)
    549                 return addr;
     587                return ENOENT;
     588
     589        trans = arp_addr_find(&proto->addresses, target->value, target->length);
     590        if (trans) {
     591                if (trans->hw_addr) {
     592                        *translation = trans->hw_addr;
     593                        return EOK;
     594                }
     595                if (retry)
     596                        return EAGAIN;
     597                rc = fibril_condvar_wait_timeout(&trans->cv, &arp_globals.lock,
     598                    ARP_TRANS_WAIT);
     599                if (rc == ETIMEOUT)
     600                        return ENOENT;
     601                retry = true;
     602                goto restart;
     603        }
     604        if (retry)
     605                return EAGAIN;
    550606
    551607        /* ARP packet content size = header + (address + translation) * 2 */
     
    553609            CONVERT_SIZE(char, uint8_t, device->addr->length));
    554610        if (length > device->packet_dimension.content)
    555                 return NULL;
     611                return ELIMIT;
    556612
    557613        packet = packet_get_4_remote(arp_globals.net_phone,
     
    559615            length, device->packet_dimension.suffix);
    560616        if (!packet)
    561                 return NULL;
     617                return ENOMEM;
    562618
    563619        header = (arp_header_t *) packet_suffix(packet, length);
    564620        if (!header) {
    565621                pq_release_remote(arp_globals.net_phone, packet_get_id(packet));
    566                 return NULL;
     622                return ENOMEM;
    567623        }
    568624
     
    583639        memcpy(((uint8_t *) header) + length, target->value, target->length);
    584640
    585         if (packet_set_addr(packet, (uint8_t *) device->addr->value,
     641        rc = packet_set_addr(packet, (uint8_t *) device->addr->value,
    586642            (uint8_t *) device->broadcast_addr->value,
    587             CONVERT_SIZE(char, uint8_t, device->addr->length)) != EOK) {
     643            CONVERT_SIZE(char, uint8_t, device->addr->length));
     644        if (rc != EOK) {
    588645                pq_release_remote(arp_globals.net_phone, packet_get_id(packet));
    589                 return NULL;
     646                return rc;
    590647        }
    591648
    592649        nil_send_msg(device->phone, device_id, packet, SERVICE_ARP);
    593         return NULL;
     650
     651        trans = (arp_trans_t *) malloc(sizeof(arp_trans_t));
     652        if (!trans)
     653                return ENOMEM;
     654        trans->hw_addr = NULL;
     655        fibril_condvar_initialize(&trans->cv);
     656        rc = arp_addr_add(&proto->addresses, target->value, target->length,
     657            trans);
     658        if (rc != EOK) {
     659                /* The generic char map has already freed trans! */
     660                return rc;
     661        }
     662       
     663        rc = fibril_condvar_wait_timeout(&trans->cv, &arp_globals.lock,
     664            ARP_TRANS_WAIT);
     665        if (rc == ETIMEOUT)
     666                return ENOENT;
     667        retry = true;
     668        goto restart;
    594669}
    595670
     
    642717                        return rc;
    643718               
    644                 fibril_rwlock_read_lock(&arp_globals.lock);
    645                 translation = arp_translate_message(IPC_GET_DEVICE(call),
    646                     IPC_GET_SERVICE(call), address);
     719                fibril_mutex_lock(&arp_globals.lock);
     720                rc = arp_translate_message(IPC_GET_DEVICE(call),
     721                    IPC_GET_SERVICE(call), address, &translation);
    647722                free(address);
    648723                free(data);
     724                if (rc != EOK) {
     725                        fibril_mutex_unlock(&arp_globals.lock);
     726                        return rc;
     727                }
    649728                if (!translation) {
    650                         fibril_rwlock_read_unlock(&arp_globals.lock);
     729                        fibril_mutex_unlock(&arp_globals.lock);
    651730                        return ENOENT;
    652731                }
    653732                rc = measured_strings_reply(translation, 1);
    654                 fibril_rwlock_read_unlock(&arp_globals.lock);
     733                fibril_mutex_unlock(&arp_globals.lock);
    655734                return rc;
    656735
     
    682761                        return rc;
    683762               
    684                 fibril_rwlock_read_lock(&arp_globals.lock);
     763                fibril_mutex_lock(&arp_globals.lock);
    685764                do {
    686765                        next = pq_detach(packet);
     
    692771                        packet = next;
    693772                } while (packet);
    694                 fibril_rwlock_read_unlock(&arp_globals.lock);
     773                fibril_mutex_unlock(&arp_globals.lock);
    695774               
    696775                return EOK;
  • uspace/srv/net/il/arp/arp.h

    r84439d7 r75732da  
    6565typedef struct arp_proto arp_proto_t;
    6666
     67/** Type definition of the ARP address translation record.
     68 * @see arp_trans
     69 */
     70typedef struct arp_trans arp_trans_t;
     71
    6772/** ARP address map.
    6873 *
     
    7075 * @see generic_char_map.h
    7176 */
    72 GENERIC_CHAR_MAP_DECLARE(arp_addr, measured_string_t);
     77GENERIC_CHAR_MAP_DECLARE(arp_addr, arp_trans_t);
    7378
    7479/** ARP address cache.
     
    8994struct arp_device {
    9095        /** Actual device hardware address. */
    91         measured_string_t * addr;
     96        measured_string_t *addr;
    9297        /** Actual device hardware address data. */
    9398        char *addr_data;
    9499        /** Broadcast device hardware address. */
    95         measured_string_t * broadcast_addr;
     100        measured_string_t *broadcast_addr;
    96101        /** Broadcast device hardware address data. */
    97102        char *broadcast_data;
     
    129134        int net_phone;
    130135        /** Safety lock. */
    131         fibril_rwlock_t lock;
     136        fibril_mutex_t lock;
    132137};
    133138
     
    144149};
    145150
     151/** ARP address translation record. */
     152struct arp_trans {
     153        /**
     154         * Hardware address for the translation. NULL denotes an incomplete
     155         * record with possible waiters.
     156         */
     157        measured_string_t *hw_addr;
     158        /** Condition variable used for waiting for completion of the record. */
     159        fibril_condvar_t cv;
     160};
     161
    146162#endif
    147163
    148164/** @}
    149165 */
     166
  • uspace/srv/vfs/vfs.h

    r84439d7 r75732da  
    172172
    173173extern fs_handle_t fs_name_to_handle(char *, bool);
     174extern vfs_info_t *fs_handle_to_info(fs_handle_t);
    174175
    175176extern int vfs_lookup_internal(char *, int, vfs_lookup_res_t *,
  • uspace/srv/vfs/vfs_ops.c

    r84439d7 r75732da  
    781781static void vfs_rdwr(ipc_callid_t rid, ipc_call_t *request, bool read)
    782782{
     783        vfs_info_t *vi;
    783784
    784785        /*
     
    807808        fibril_mutex_lock(&file->lock);
    808809
     810        vi = fs_handle_to_info(file->node->fs_handle);
     811        assert(vi);
     812
    809813        /*
    810814         * Lock the file's node so that no other client can read/write to it at
    811          * the same time.
    812          */
    813         if (read)
     815         * the same time unless the FS supports concurrent reads/writes and its
     816         * write implementation does not modify the file size.
     817         */
     818        if (read || (vi->concurrent_read_write && vi->write_retains_size))
    814819                fibril_rwlock_read_lock(&file->node->contents_rwlock);
    815820        else
     
    857862       
    858863        /* Unlock the VFS node. */
    859         if (read)
     864        if (read || (vi->concurrent_read_write && vi->write_retains_size))
    860865                fibril_rwlock_read_unlock(&file->node->contents_rwlock);
    861866        else {
  • uspace/srv/vfs/vfs_register.c

    r84439d7 r75732da  
    333333}
    334334
     335/** Find the VFS info structure.
     336 *
     337 * @param handle        FS handle for which the VFS info structure is sought.
     338 * @return              VFS info structure on success or NULL otherwise.
     339 */
     340vfs_info_t *fs_handle_to_info(fs_handle_t handle)
     341{
     342        vfs_info_t *info = NULL;
     343        link_t *cur;
     344
     345        fibril_mutex_lock(&fs_head_lock);
     346        for (cur = fs_head.next; cur != &fs_head; cur = cur->next) {
     347                fs_info_t *fs = list_get_instance(cur, fs_info_t, fs_link);
     348                if (fs->fs_handle == handle) {
     349                        info = &fs->vfs_info;
     350                        break;
     351                }
     352        }
     353        fibril_mutex_unlock(&fs_head_lock);
     354
     355        return info;
     356}
     357
    335358/**
    336359 * @}
Note: See TracChangeset for help on using the changeset viewer.