Changeset 243cb86 in mainline for uspace


Ignore:
Timestamp:
2010-12-12T10:50:19Z (15 years ago)
Author:
Lubos Slovak <lubos.slovak@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
8365533
Parents:
101ef25c (diff), ebb98c5 (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 from development + several changes to hid driver.

Changes to hid driver:

  • copied some code to usbkbd_get_descriptors() function
  • base structure for hid descriptor and report parser (files uspace/lib/usb/include/usb/classes/hidparser.h

and uspace/lib/usb/src/hidparser.c)

Location:
uspace
Files:
31 added
1 deleted
60 edited
3 moved

Legend:

Unmodified
Added
Removed
  • uspace/Makefile

    r101ef25c r243cb86  
    4949        app/trace \
    5050        app/top \
     51        app/usbinfo \
    5152        app/virtusbkbd \
    5253        app/netecho \
     
    8788        srv/net/net \
    8889        drv/root \
     90        drv/rootvirt \
     91        drv/test1 \
     92        drv/test2 \
    8993        drv/vhc
    9094
     
    110114
    111115ifeq ($(UARCH),amd64)
     116        DIRS += drv/rootpc
     117        DIRS += drv/pciintel
     118        DIRS += drv/isa
     119        DIRS += drv/ns8250
    112120endif
    113121
    114122ifeq ($(UARCH),ia32)
    115         DIRS += drv/rootia32
     123        DIRS += drv/rootpc
    116124        DIRS += drv/pciintel
    117125        DIRS += drv/isa
    118126        DIRS += drv/ns8250
    119127        DIRS += drv/uhci
     128        DIRS += drv/usbhub
    120129        DIRS += drv/usbkbd
    121130endif
  • uspace/app/netecho/print_error.c

    r101ef25c r243cb86  
    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

    r101ef25c r243cb86  
    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

    r101ef25c r243cb86  
    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

    r101ef25c r243cb86  
    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/virtusbkbd.c

    r101ef25c r243cb86  
    202202int main(int argc, char * argv[])
    203203{
    204         printf("Dump of report descriptor (%u bytes):\n", report_descriptor_size);
     204        printf("Dump of report descriptor (%zu bytes):\n", report_descriptor_size);
    205205        size_t i;
    206206        for (i = 0; i < report_descriptor_size; i++) {
  • uspace/drv/isa/isa.c

    r101ef25c r243cb86  
    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

    r101ef25c r243cb86  
    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

    r101ef25c r243cb86  
    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

    r101ef25c r243cb86  
    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

    r101ef25c r243cb86  
    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

    r101ef25c r243cb86  
    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/Makefile

    r101ef25c r243cb86  
    3333
    3434SOURCES = \
    35         main.c
     35        main.c \
     36        transfers.c
    3637
    3738include $(USPACE_PREFIX)/Makefile.common
  • uspace/drv/uhci/main.c

    r101ef25c r243cb86  
    2727 */
    2828#include <usb/hcdhubd.h>
     29#include <usb/debug.h>
    2930#include <errno.h>
     31#include "uhci.h"
    3032
    31 static int enqueue_transfer_out(usb_hc_device_t *hc,
    32     usb_hcd_attached_device_info_t *dev, usb_hc_endpoint_info_t *endpoint,
    33     void *buffer, size_t size,
    34     usb_hcd_transfer_callback_out_t callback, void *arg)
    35 {
    36         printf("UHCI: transfer OUT [%d.%d (%s); %u]\n",
    37             dev->address, endpoint->endpoint,
    38             usb_str_transfer_type(endpoint->transfer_type),
    39             size);
    40         return ENOTSUP;
    41 }
    42 
    43 static int enqueue_transfer_setup(usb_hc_device_t *hc,
    44     usb_hcd_attached_device_info_t *dev, usb_hc_endpoint_info_t *endpoint,
    45     void *buffer, size_t size,
    46     usb_hcd_transfer_callback_out_t callback, void *arg)
    47 {
    48         printf("UHCI: transfer SETUP [%d.%d (%s); %u]\n",
    49             dev->address, endpoint->endpoint,
    50             usb_str_transfer_type(endpoint->transfer_type),
    51             size);
    52         return ENOTSUP;
    53 }
    54 
    55 static int enqueue_transfer_in(usb_hc_device_t *hc,
    56     usb_hcd_attached_device_info_t *dev, usb_hc_endpoint_info_t *endpoint,
    57     void *buffer, size_t size,
    58     usb_hcd_transfer_callback_in_t callback, void *arg)
    59 {
    60         printf("UHCI: transfer IN [%d.%d (%s); %u]\n",
    61             dev->address, endpoint->endpoint,
    62             usb_str_transfer_type(endpoint->transfer_type),
    63             size);
    64         return ENOTSUP;
    65 }
    66 
    67 static usb_hcd_transfer_ops_t uhci_transfer_ops = {
    68         .transfer_out = enqueue_transfer_out,
    69         .transfer_in = enqueue_transfer_in,
    70         .transfer_setup = enqueue_transfer_setup
     33static device_ops_t uhci_ops = {
     34        .interfaces[USBHC_DEV_IFACE] = &uhci_iface,
    7135};
    7236
    73 static int uhci_add_hc(usb_hc_device_t *device)
     37static int uhci_add_device(device_t *device)
    7438{
    75         device->transfer_ops = &uhci_transfer_ops;
     39        usb_dprintf(NAME, 1, "uhci_add_device() called\n");
     40        device->ops = &uhci_ops;
    7641
    7742        /*
    7843         * We need to announce the presence of our root hub.
    7944         */
     45        usb_dprintf(NAME, 2, "adding root hub\n");
    8046        usb_hcd_add_root_hub(device);
    8147
     
    8349}
    8450
    85 usb_hc_driver_t uhci_driver = {
    86         .name = "uhci",
    87         .add_hc = uhci_add_hc
     51static driver_ops_t uhci_driver_ops = {
     52        .add_device = uhci_add_device,
     53};
     54
     55static driver_t uhci_driver = {
     56        .name = NAME,
     57        .driver_ops = &uhci_driver_ops
    8858};
    8959
     
    9363         * Do some global initializations.
    9464         */
     65        sleep(5);
     66        usb_dprintf_enable(NAME, 5);
    9567
    96         return usb_hcd_main(&uhci_driver);
     68        return driver_main(&uhci_driver);
    9769}
  • uspace/drv/uhci/uhci.ma

    r101ef25c r243cb86  
    1110 pci/ven=8086&dev=7020
    2 10 usb&hc=uhci
    3 10 usb&hc=uhci&hub
     2
  • uspace/drv/usbhub/utils.c

    r101ef25c r243cb86  
    3333 * @brief Hub driver.
    3434 */
    35 #include <usb/hcdhubd.h>
     35#include <driver.h>
    3636#include <usb/devreq.h>
    3737#include <usbhc_iface.h>
     38#include <usb/usbdrv.h>
    3839#include <usb/descriptor.h>
    3940#include <driver.h>
     
    4142#include <errno.h>
    4243#include <usb/classes/hub.h>
    43 #include "hcdhubd_private.h"
     44#include "usbhub.h"
    4445
    4546static void check_hub_changes(void);
     
    108109//*********************************************
    109110
    110 static void set_hub_address(usb_hc_device_t *hc, usb_address_t address);
    111 
    112111usb_hcd_hub_info_t * usb_create_hub_info(device_t * device) {
    113112        usb_hcd_hub_info_t* result = (usb_hcd_hub_info_t*) malloc(sizeof (usb_hcd_hub_info_t));
    114         //get parent device
    115         /// @TODO this code is not correct
    116         device_t * my_hcd = device;
    117         while (my_hcd->parent)
    118                 my_hcd = my_hcd->parent;
    119         //dev->
    120         printf("%s: owner hcd found: %s\n", hc_driver->name, my_hcd->name);
    121         //we add the hub into the first hc
    122         //link_t *link_hc = hc_list.next;
    123         //usb_hc_device_t *hc = list_get_instance(link_hc,
    124         //              usb_hc_device_t, link);
    125         //must get generic device info
    126 
    127113
    128114        return result;
     
    135121 */
    136122int usb_add_hub_device(device_t *dev) {
    137         usb_hc_device_t *hc = list_get_instance(hc_list.next, usb_hc_device_t, link);
    138         set_hub_address(hc, 5);
     123        printf(NAME ": add_hub_device(handle=%d)\n", (int) dev->handle);
    139124
    140125        check_hub_changes();
     
    145130         * connected devices.
    146131         */
    147         //insert hub into list
    148         //find owner hcd
    149         device_t * my_hcd = dev;
    150         while (my_hcd->parent)
    151                 my_hcd = my_hcd->parent;
    152         //dev->
    153         printf("%s: owner hcd found: %s\n", hc_driver->name, my_hcd->name);
    154         my_hcd = dev;
    155         while (my_hcd->parent)
    156                 my_hcd = my_hcd->parent;
    157         //dev->
    158 
    159         printf("%s: owner hcd found: %s\n", hc_driver->name, my_hcd->name);
    160132
    161133        //create the hub structure
    162134        usb_hcd_hub_info_t * hub_info = usb_create_hub_info(dev);
    163 
    164 
    165         //append into the list
    166         //we add the hub into the first hc
    167         list_append(&hub_info->link, &hc->hubs);
    168 
    169 
     135        (void)hub_info;
    170136
    171137        return EOK;
     
    173139}
    174140
    175 /** Sample usage of usb_hc_async functions.
    176  * This function sets hub address using standard SET_ADDRESS request.
    177  *
    178  * @warning This function shall be removed once you are familiar with
    179  * the usb_hc_ API.
    180  *
    181  * @param hc Host controller the hub belongs to.
    182  * @param address New hub address.
    183  */
    184 static void set_hub_address(usb_hc_device_t *hc, usb_address_t address) {
    185         printf("%s: setting hub address to %d\n", hc->generic->name, address);
    186         usb_target_t target = {0, 0};
    187         usb_handle_t handle;
    188         int rc;
    189 
    190         usb_device_request_setup_packet_t setup_packet = {
    191                 .request_type = 0,
    192                 .request = USB_DEVREQ_SET_ADDRESS,
    193                 .index = 0,
    194                 .length = 0,
    195         };
    196         setup_packet.value = address;
    197 
    198         rc = usb_hc_async_control_write_setup(hc, target,
    199                         &setup_packet, sizeof (setup_packet), &handle);
    200         if (rc != EOK) {
    201                 return;
    202         }
    203 
    204         rc = usb_hc_async_wait_for(handle);
    205         if (rc != EOK) {
    206                 return;
    207         }
    208 
    209         rc = usb_hc_async_control_write_status(hc, target, &handle);
    210         if (rc != EOK) {
    211                 return;
    212         }
    213 
    214         rc = usb_hc_async_wait_for(handle);
    215         if (rc != EOK) {
    216                 return;
    217         }
    218 
    219         printf("%s: hub address changed\n", hc->generic->name);
    220 }
    221141
    222142/** Check changes on all known hubs.
     
    224144static void check_hub_changes(void) {
    225145        /*
    226          * Iterate through all HCs.
     146         * Iterate through all hubs.
    227147         */
    228         link_t *link_hc;
    229         for (link_hc = hc_list.next;
    230                         link_hc != &hc_list;
    231                         link_hc = link_hc->next) {
    232                 usb_hc_device_t *hc = list_get_instance(link_hc,
    233                                 usb_hc_device_t, link);
    234                 /*
    235                  * Iterate through all their hubs.
    236                  */
    237                 link_t *link_hub;
    238                 for (link_hub = hc->hubs.next;
    239                                 link_hub != &hc->hubs;
    240                                 link_hub = link_hub->next) {
    241                         usb_hcd_hub_info_t *hub = list_get_instance(link_hub,
    242                                         usb_hcd_hub_info_t, link);
    243 
    244                         /*
    245                          * Check status change pipe of this hub.
    246                          */
    247                         usb_target_t target = {
    248                                 .address = hub->device->address,
    249                                 .endpoint = 1
    250                         };
    251 
    252                         // FIXME: count properly
    253                         size_t byte_length = (hub->port_count / 8) + 1;
    254 
    255                         void *change_bitmap = malloc(byte_length);
    256                         size_t actual_size;
    257                         usb_handle_t handle;
    258 
    259                         /*
    260                          * Send the request.
    261                          * FIXME: check returned value for possible errors
    262                          */
    263                         usb_hc_async_interrupt_in(hc, target,
    264                                         change_bitmap, byte_length, &actual_size,
    265                                         &handle);
    266 
    267                         usb_hc_async_wait_for(handle);
    268 
    269                         /*
    270                          * TODO: handle the changes.
    271                          */
     148        for (; false; ) {
     149                /*
     150                 * Check status change pipe of this hub.
     151                 */
     152                usb_target_t target = {
     153                        .address = 5,
     154                        .endpoint = 1
     155                };
     156
     157                size_t port_count = 7;
     158
     159                /*
     160                 * Connect to respective HC.
     161                 */
     162                int hc = usb_drv_hc_connect(NULL, 0);
     163                if (hc < 0) {
     164                        continue;
    272165                }
     166
     167                // FIXME: count properly
     168                size_t byte_length = (port_count / 8) + 1;
     169
     170                void *change_bitmap = malloc(byte_length);
     171                size_t actual_size;
     172                usb_handle_t handle;
     173
     174                /*
     175                 * Send the request.
     176                 * FIXME: check returned value for possible errors
     177                 */
     178                usb_drv_async_interrupt_in(hc, target,
     179                                change_bitmap, byte_length, &actual_size,
     180                                &handle);
     181
     182                usb_drv_async_wait_for(handle);
     183
     184                /*
     185                 * TODO: handle the changes.
     186                 */
     187
     188                /*
     189                 * WARNING: sample code, will not work out of the box.
     190                 * And does not contain code for checking for errors.
     191                 */
     192#if 0
     193                /*
     194                 * Before opening the port, we must acquire the default
     195                 * address.
     196                 */
     197                usb_drv_reserve_default_address(hc);
     198
     199                usb_address_t new_device_address = usb_drv_request_address(hc);
     200
     201                // TODO: open the port
     202
     203                // TODO: send request for setting address to new_device_address
     204
     205                /*
     206                 * Once new address is set, we can release the default
     207                 * address.
     208                 */
     209                usb_drv_release_default_address(hc);
     210
     211                /*
     212                 * Obtain descriptors and create match ids for devman.
     213                 */
     214
     215                // TODO: get device descriptors
     216
     217                // TODO: create match ids
     218
     219                // TODO: add child device
     220
     221                // child_device_register sets the device handle
     222                // TODO: store it here
     223                devman_handle_t new_device_handle = 0;
     224
     225                /*
     226                 * Inform the HC that the new device has devman handle
     227                 * assigned.
     228                 */
     229                usb_drv_bind_address(hc, new_device_address, new_device_handle);
     230
     231                /*
     232                 * That's all.
     233                 */
     234#endif
     235
     236
     237                /*
     238                 * Hang-up the HC-connected phone.
     239                 */
     240                ipc_hangup(hc);
    273241        }
    274242}
  • uspace/drv/usbkbd/main.c

    r101ef25c r243cb86  
    3232#include <fibril.h>
    3333#include <usb/classes/hid.h>
     34#include <usb/classes/hidparser.h>
     35#include <usb/devreq.h>
    3436
    3537#define BUFFER_SIZE 32
     
    3739
    3840static const usb_endpoint_t CONTROL_EP = 0;
     41
     42/*
     43 * Callbacks for parser
     44 */
     45static void usbkbd_process_keycodes(const uint16_t *key_codes, size_t count,
     46                                    void *arg)
     47{
     48
     49}
     50
     51/*
     52 * Kbd functions
     53 */
     54static int usbkbd_get_descriptors()
     55{
     56        // copy-pasted:
     57       
     58        /* Prepare the setup packet. */
     59        usb_device_request_setup_packet_t setup_packet = {
     60                .request_type = 128,
     61                .request = USB_DEVREQ_GET_DESCRIPTOR,
     62                .index = 0,
     63                .length = sizeof(usb_standard_device_descriptor_t)
     64        };
     65       
     66        setup_packet.value_high = USB_DESCTYPE_DEVICE;
     67        setup_packet.value_low = 0;
     68
     69        /* Prepare local descriptor. */
     70        size_t actually_transferred = 0;
     71        usb_standard_device_descriptor_t descriptor_tmp;
     72
     73        /* Perform the control read transaction. */
     74        int rc = usb_drv_psync_control_read(phone, target,
     75            &setup_packet, sizeof(setup_packet),
     76            &descriptor_tmp, sizeof(descriptor_tmp), &actually_transferred);
     77
     78        if (rc != EOK) {
     79                return rc;
     80        }
     81       
     82        // end of copy-paste
     83}
    3984
    4085static usb_hid_dev_kbd_t *usbkbd_init_device(device_t *dev)
     
    68113
    69114        // TODO: get descriptors
    70 
     115        usbkbd_get_descriptors();
    71116        // TODO: parse descriptors and save endpoints
    72117
     
    75120
    76121static void usbkbd_process_interrupt_in(usb_hid_dev_kbd_t *kbd_dev,
    77                                         char *buffer, size_t actual_size)
     122                                        uint8_t *buffer, size_t actual_size)
    78123{
    79124        /*
     
    81126         * now only take last 6 bytes and process, i.e. send to kbd
    82127         */
     128
     129        usb_hid_report_in_callbacks_t *callbacks =
     130            (usb_hid_report_in_callbacks_t *)malloc(
     131                sizeof(usb_hid_report_in_callbacks_t));
     132        callbacks->keyboard = usbkbd_process_keycodes;
     133
     134        usb_hid_parse_report(kbd_dev->parser, buffer, callbacks, NULL);
    83135}
    84136
     
    87139        int rc;
    88140        usb_handle_t handle;
    89         char buffer[BUFFER_SIZE];
     141        uint8_t buffer[BUFFER_SIZE];
    90142        size_t actual_size;
    91143        //usb_endpoint_t poll_endpoint = 1;
  • uspace/drv/vhc/conn.h

    r101ef25c r243cb86  
    3838#include <usb/usb.h>
    3939#include <usb/hcdhubd.h>
     40#include <usbhc_iface.h>
    4041#include "vhcd.h"
    4142#include "devices.h"
     
    4445
    4546usb_hcd_transfer_ops_t vhc_transfer_ops;
     47usbhc_iface_t vhc_iface;
     48
     49void address_init(void);
     50
    4651
    4752void default_connection_handler(device_t *, ipc_callid_t, ipc_call_t *);
  • uspace/drv/vhc/connhost.c

    r101ef25c r243cb86  
    3636#include <errno.h>
    3737#include <usb/usb.h>
     38#include <usb/hcd.h>
    3839
    3940#include "vhcd.h"
     
    4344typedef struct {
    4445        usb_direction_t direction;
    45         usb_hcd_transfer_callback_out_t out_callback;
    46         usb_hcd_transfer_callback_in_t in_callback;
    47         usb_hc_device_t *hc;
     46        usbhc_iface_transfer_out_callback_t out_callback;
     47        usbhc_iface_transfer_in_callback_t in_callback;
     48        device_t *dev;
    4849        void *arg;
    4950} transfer_info_t;
     
    5657        switch (transfer->direction) {
    5758                case USB_DIRECTION_IN:
    58                         transfer->in_callback(transfer->hc,
    59                             size, outcome,
     59                        transfer->in_callback(transfer->dev,
     60                            outcome, size,
    6061                            transfer->arg);
    6162                        break;
    6263                case USB_DIRECTION_OUT:
    63                         transfer->out_callback(transfer->hc,
     64                        transfer->out_callback(transfer->dev,
    6465                            outcome,
    6566                            transfer->arg);
     
    7374}
    7475
    75 static transfer_info_t *create_transfer_info(usb_hc_device_t *hc,
     76static transfer_info_t *create_transfer_info(device_t *dev,
    7677    usb_direction_t direction, void *arg)
    7778{
     
    8283        transfer->out_callback = NULL;
    8384        transfer->arg = arg;
    84         transfer->hc = hc;
     85        transfer->dev = dev;
    8586
    8687        return transfer;
    8788}
    8889
    89 static int enqueue_transfer_out(usb_hc_device_t *hc,
    90     usb_hcd_attached_device_info_t *dev, usb_hc_endpoint_info_t *endpoint,
     90static int enqueue_transfer_out(device_t *dev,
     91    usb_target_t target, usb_transfer_type_t transfer_type,
    9192    void *buffer, size_t size,
    92     usb_hcd_transfer_callback_out_t callback, void *arg)
    93 {
    94         printf(NAME ": transfer OUT [%d.%d (%s); %u]\n",
    95             dev->address, endpoint->endpoint,
    96             usb_str_transfer_type(endpoint->transfer_type),
     93    usbhc_iface_transfer_out_callback_t callback, void *arg)
     94{
     95        printf(NAME ": transfer OUT [%d.%d (%s); %zu]\n",
     96            target.address, target.endpoint,
     97            usb_str_transfer_type(transfer_type),
    9798            size);
    9899
    99100        transfer_info_t *transfer
    100             = create_transfer_info(hc, USB_DIRECTION_OUT, arg);
     101            = create_transfer_info(dev, USB_DIRECTION_OUT, arg);
    101102        transfer->out_callback = callback;
    102 
    103         usb_target_t target = {
    104                 .address = dev->address,
    105                 .endpoint = endpoint->endpoint
    106         };
    107103
    108104        hc_add_transaction_to_device(false, target, buffer, size,
     
    112108}
    113109
    114 static int enqueue_transfer_setup(usb_hc_device_t *hc,
    115     usb_hcd_attached_device_info_t *dev, usb_hc_endpoint_info_t *endpoint,
     110static int enqueue_transfer_setup(device_t *dev,
     111    usb_target_t target, usb_transfer_type_t transfer_type,
    116112    void *buffer, size_t size,
    117     usb_hcd_transfer_callback_out_t callback, void *arg)
    118 {
    119         printf(NAME ": transfer SETUP [%d.%d (%s); %u]\n",
    120             dev->address, endpoint->endpoint,
    121             usb_str_transfer_type(endpoint->transfer_type),
     113    usbhc_iface_transfer_out_callback_t callback, void *arg)
     114{
     115        printf(NAME ": transfer SETUP [%d.%d (%s); %zu]\n",
     116            target.address, target.endpoint,
     117            usb_str_transfer_type(transfer_type),
    122118            size);
    123119
    124120        transfer_info_t *transfer
    125             = create_transfer_info(hc, USB_DIRECTION_OUT, arg);
     121            = create_transfer_info(dev, USB_DIRECTION_OUT, arg);
    126122        transfer->out_callback = callback;
    127 
    128         usb_target_t target = {
    129                 .address = dev->address,
    130                 .endpoint = endpoint->endpoint
    131         };
    132123
    133124        hc_add_transaction_to_device(true, target, buffer, size,
     
    137128}
    138129
    139 static int enqueue_transfer_in(usb_hc_device_t *hc,
    140     usb_hcd_attached_device_info_t *dev, usb_hc_endpoint_info_t *endpoint,
     130static int enqueue_transfer_in(device_t *dev,
     131    usb_target_t target, usb_transfer_type_t transfer_type,
    141132    void *buffer, size_t size,
    142     usb_hcd_transfer_callback_in_t callback, void *arg)
    143 {
    144         printf(NAME ": transfer IN [%d.%d (%s); %u]\n",
    145             dev->address, endpoint->endpoint,
    146             usb_str_transfer_type(endpoint->transfer_type),
     133    usbhc_iface_transfer_in_callback_t callback, void *arg)
     134{
     135        printf(NAME ": transfer IN [%d.%d (%s); %zu]\n",
     136            target.address, target.endpoint,
     137            usb_str_transfer_type(transfer_type),
    147138            size);
    148139
    149140        transfer_info_t *transfer
    150             = create_transfer_info(hc, USB_DIRECTION_IN, arg);
     141            = create_transfer_info(dev, USB_DIRECTION_IN, arg);
    151142        transfer->in_callback = callback;
    152 
    153         usb_target_t target = {
    154                 .address = dev->address,
    155                 .endpoint = endpoint->endpoint
    156         };
    157143
    158144        hc_add_transaction_from_device(target, buffer, size,
     
    163149
    164150
    165 usb_hcd_transfer_ops_t vhc_transfer_ops = {
    166         .transfer_out = enqueue_transfer_out,
    167         .transfer_in = enqueue_transfer_in,
    168         .transfer_setup = enqueue_transfer_setup
     151static int interrupt_out(device_t *dev, usb_target_t target,
     152    void *data, size_t size,
     153    usbhc_iface_transfer_out_callback_t callback, void *arg)
     154{
     155        return enqueue_transfer_out(dev, target, USB_TRANSFER_INTERRUPT,
     156            data, size,
     157            callback, arg);
     158}
     159
     160static int interrupt_in(device_t *dev, usb_target_t target,
     161    void *data, size_t size,
     162    usbhc_iface_transfer_in_callback_t callback, void *arg)
     163{
     164        return enqueue_transfer_in(dev, target, USB_TRANSFER_INTERRUPT,
     165            data, size,
     166            callback, arg);
     167}
     168
     169static int control_write_setup(device_t *dev, usb_target_t target,
     170    void *data, size_t size,
     171    usbhc_iface_transfer_out_callback_t callback, void *arg)
     172{
     173        return enqueue_transfer_setup(dev, target, USB_TRANSFER_CONTROL,
     174            data, size,
     175            callback, arg);
     176}
     177
     178static int control_write_data(device_t *dev, usb_target_t target,
     179    void *data, size_t size,
     180    usbhc_iface_transfer_out_callback_t callback, void *arg)
     181{
     182        return enqueue_transfer_out(dev, target, USB_TRANSFER_CONTROL,
     183            data, size,
     184            callback, arg);
     185}
     186
     187static int control_write_status(device_t *dev, usb_target_t target,
     188    usbhc_iface_transfer_in_callback_t callback, void *arg)
     189{
     190        return enqueue_transfer_in(dev, target, USB_TRANSFER_CONTROL,
     191            NULL, 0,
     192            callback, arg);
     193}
     194
     195static int control_read_setup(device_t *dev, usb_target_t target,
     196    void *data, size_t size,
     197    usbhc_iface_transfer_out_callback_t callback, void *arg)
     198{
     199        return enqueue_transfer_setup(dev, target, USB_TRANSFER_CONTROL,
     200            data, size,
     201            callback, arg);
     202}
     203
     204static int control_read_data(device_t *dev, usb_target_t target,
     205    void *data, size_t size,
     206    usbhc_iface_transfer_in_callback_t callback, void *arg)
     207{
     208        return enqueue_transfer_in(dev, target, USB_TRANSFER_CONTROL,
     209            data, size,
     210            callback, arg);
     211}
     212
     213static int control_read_status(device_t *dev, usb_target_t target,
     214    usbhc_iface_transfer_out_callback_t callback, void *arg)
     215{
     216        return enqueue_transfer_out(dev, target, USB_TRANSFER_CONTROL,
     217            NULL, 0,
     218            callback, arg);
     219}
     220
     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}
     275
     276usbhc_iface_t vhc_iface = {
     277        .tell_address = tell_address,
     278
     279        .reserve_default_address = reserve_default_address,
     280        .release_default_address = release_default_address,
     281        .request_address = request_address,
     282        .bind_address = bind_address,
     283        .release_address = release_address,
     284
     285        .interrupt_out = interrupt_out,
     286        .interrupt_in = interrupt_in,
     287
     288        .control_write_setup = control_write_setup,
     289        .control_write_data = control_write_data,
     290        .control_write_status = control_write_status,
     291
     292        .control_read_setup = control_read_setup,
     293        .control_read_data = control_read_data,
     294        .control_read_status = control_read_status
    169295};
    170296
  • uspace/drv/vhc/debug.c

    r101ef25c r243cb86  
    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/hcd.c

    r101ef25c r243cb86  
    5252#include "conn.h"
    5353
     54static device_ops_t vhc_ops = {
     55        .interfaces[USBHC_DEV_IFACE] = &vhc_iface,
     56        .default_handler = default_connection_handler
     57};
    5458
    5559static int vhc_count = 0;
    56 static int vhc_add_device(usb_hc_device_t *dev)
     60static int vhc_add_device(device_t *dev)
    5761{
    5862        /*
     
    6569        vhc_count++;
    6670
    67         dev->transfer_ops = &vhc_transfer_ops;
    68         dev->generic->ops->default_handler = default_connection_handler;
     71        dev->ops = &vhc_ops;
     72
     73        /*
     74         * Initialize address management.
     75         */
     76        address_init();
    6977
    7078        /*
    7179         * Initialize our hub and announce its presence.
    7280         */
    73         hub_init();
    74         usb_hcd_add_root_hub(dev);
     81        hub_init(dev);
    7582
    7683        printf("%s: virtual USB host controller ready.\n", NAME);
     
    7986}
    8087
    81 static usb_hc_driver_t vhc_driver = {
     88static driver_ops_t vhc_driver_ops = {
     89        .add_device = vhc_add_device,
     90};
     91
     92static driver_t vhc_driver = {
    8293        .name = NAME,
    83         .add_hc = &vhc_add_device
     94        .driver_ops = &vhc_driver_ops
    8495};
    8596
     
    99110        printf("%s: virtual USB host controller driver.\n", NAME);
    100111
    101         debug_level = 10;
     112        usb_dprintf_enable(NAME, 10);
    102113
    103114        fid_t fid = fibril_create(hc_manager_fibril, NULL);
     
    114125        sleep(4);
    115126
    116         return usb_hcd_main(&vhc_driver);
     127        return driver_main(&vhc_driver);
    117128}
    118129
  • uspace/drv/vhc/hub.c

    r101ef25c r243cb86  
    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
     
    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)
     176void hub_init(device_t *hc_dev)
    152177{
    153178        size_t i;
     
    163188       
    164189        dprintf(1, "virtual hub (%d ports) created", HUB_PORT_COUNT);
     190
     191        usb_address_t hub_address = hub_set_address(&virthub_dev);
     192        if (hub_address < 0) {
     193                dprintf(1, "problem changing hub address (%s)",
     194                    str_error(hub_address));
     195        }
     196
     197        dprintf(2, "virtual hub address changed to %d", hub_address);
     198
     199        char *id;
     200        int rc = asprintf(&id, "usb&hub");
     201        if (rc <= 0) {
     202                return;
     203        }
     204        devman_handle_t hub_handle;
     205        rc = child_device_register_wrapper(hc_dev, "hub", id, 10, &hub_handle);
     206        if (rc != EOK) {
     207                free(id);
     208        }
     209
     210        vhc_iface.bind_address(NULL, hub_address, hub_handle); 
     211
     212        dprintf(2, "virtual hub has devman handle %d", (int) hub_handle);
    165213}
    166214
  • uspace/drv/vhc/hub.h

    r101ef25c r243cb86  
    3737
    3838#include <usbvirt/device.h>
     39#include <driver.h>
    3940
    4041#include "devices.h"
     
    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/vhc.ma

    r101ef25c r243cb86  
    1110 usb&hc=vhc
    2 10 usb&hc=vhc&hub
     2
  • uspace/drv/vhc/vhcd.h

    r101ef25c r243cb86  
    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/block/libblock.c

    r101ef25c r243cb86  
    6666        fibril_mutex_t lock;
    6767        size_t lblock_size;             /**< Logical block size. */
     68        unsigned blocks_cluster;        /**< Physical blocks per block_t */
    6869        unsigned block_count;           /**< Total number of blocks. */
    6970        unsigned blocks_cached;         /**< Number of cached blocks. */
     
    9091static int get_block_size(int dev_phone, size_t *bsize);
    9192static int get_num_blocks(int dev_phone, aoff64_t *nblocks);
     93static aoff64_t ba_ltop(devcon_t *devcon, aoff64_t lba);
    9294
    9395static devcon_t *devcon_search(devmap_handle_t devmap_handle)
     
    259261{
    260262        block_t *b = hash_table_get_instance(item, block_t, hash_link);
    261         return b->boff == *key;
     263        return b->lba == *key;
    262264}
    263265
     
    292294        cache->mode = mode;
    293295
    294         /* No block size translation a.t.m. */
    295         assert(cache->lblock_size == devcon->pblock_size);
     296        /* Allow 1:1 or small-to-large block size translation */
     297        if (cache->lblock_size % devcon->pblock_size != 0)
     298                return ENOTSUP;
     299
     300        cache->blocks_cluster = cache->lblock_size / devcon->pblock_size;
    296301
    297302        if (!hash_table_create(&cache->block_hash, CACHE_BUCKETS, 1,
     
    329334                if (b->dirty) {
    330335                        memcpy(devcon->comm_area, b->data, b->size);
    331                         rc = write_blocks(devcon, b->boff, 1);
     336                        rc = write_blocks(devcon, b->pba, cache->blocks_cluster);
    332337                        if (rc != EOK)
    333338                                return rc;
    334339                }
    335340
    336                 unsigned long key = b->boff;
     341                unsigned long key = b->lba;
    337342                hash_table_remove(&cache->block_hash, &key, 1);
    338343               
     
    375380 *                              block pointer on success.
    376381 * @param devmap_handle         Device handle of the block device.
    377  * @param boff                  Block offset.
     382 * @param ba                    Block address (logical).
    378383 * @param flags                 If BLOCK_FLAGS_NOREAD is specified, block_get()
    379384 *                              will not read the contents of the block from the
     
    382387 * @return                      EOK on success or a negative error code.
    383388 */
    384 int block_get(block_t **block, devmap_handle_t devmap_handle, aoff64_t boff, int flags)
     389int block_get(block_t **block, devmap_handle_t devmap_handle, aoff64_t ba, int flags)
    385390{
    386391        devcon_t *devcon;
     
    388393        block_t *b;
    389394        link_t *l;
    390         unsigned long key = boff;
     395        unsigned long key = ba;
    391396        int rc;
    392397       
     
    465470                                fibril_mutex_lock(&devcon->comm_area_lock);
    466471                                memcpy(devcon->comm_area, b->data, b->size);
    467                                 rc = write_blocks(devcon, b->boff, 1);
     472                                rc = write_blocks(devcon, b->pba,
     473                                    cache->blocks_cluster);
    468474                                fibril_mutex_unlock(&devcon->comm_area_lock);
    469475                                if (rc != EOK) {
     
    495501                         */
    496502                        list_remove(&b->free_link);
    497                         temp_key = b->boff;
     503                        temp_key = b->lba;
    498504                        hash_table_remove(&cache->block_hash, &temp_key, 1);
    499505                }
     
    502508                b->devmap_handle = devmap_handle;
    503509                b->size = cache->lblock_size;
    504                 b->boff = boff;
     510                b->lba = ba;
     511                b->pba = ba_ltop(devcon, b->lba);
    505512                hash_table_insert(&cache->block_hash, &key, &b->hash_link);
    506513
     
    519526                         */
    520527                        fibril_mutex_lock(&devcon->comm_area_lock);
    521                         rc = read_blocks(devcon, b->boff, 1);
     528                        rc = read_blocks(devcon, b->pba, cache->blocks_cluster);
    522529                        memcpy(b->data, devcon->comm_area, cache->lblock_size);
    523530                        fibril_mutex_unlock(&devcon->comm_area_lock);
     
    580587                fibril_mutex_lock(&devcon->comm_area_lock);
    581588                memcpy(devcon->comm_area, block->data, block->size);
    582                 rc = write_blocks(devcon, block->boff, 1);
     589                rc = write_blocks(devcon, block->pba, cache->blocks_cluster);
    583590                fibril_mutex_unlock(&devcon->comm_area_lock);
    584591                block->dirty = false;
     
    614621                         * Take the block out of the cache and free it.
    615622                         */
    616                         unsigned long key = block->boff;
     623                        unsigned long key = block->lba;
    617624                        hash_table_remove(&cache->block_hash, &key, 1);
    618625                        free(block);
     
    712719 *
    713720 * @param devmap_handle Device handle of the block device.
    714  * @param ba            Address of first block.
     721 * @param ba            Address of first block (physical).
    715722 * @param cnt           Number of blocks.
    716723 * @param src           Buffer for storing the data.
     
    740747 *
    741748 * @param devmap_handle Device handle of the block device.
    742  * @param ba            Address of first block.
     749 * @param ba            Address of first block (physical).
    743750 * @param cnt           Number of blocks.
    744751 * @param src           The data to be written.
     
    879886}
    880887
     888/** Convert logical block address to physical block address. */
     889static aoff64_t ba_ltop(devcon_t *devcon, aoff64_t lba)
     890{
     891        assert(devcon->cache != NULL);
     892        return lba * devcon->cache->blocks_cluster;
     893}
     894
    881895/** @}
    882896 */
  • uspace/lib/block/libblock.h

    r101ef25c r243cb86  
    7373        /** Handle of the device where the block resides. */
    7474        devmap_handle_t devmap_handle;
    75         /** Block offset on the block device. Counted in 'size'-byte blocks. */
    76         aoff64_t boff;
     75        /** Logical block address */
     76        aoff64_t lba;
     77        /** Physical block address */
     78        aoff64_t pba;
    7779        /** Size of the block. */
    7880        size_t size;
  • uspace/lib/c/generic/adt/char_map.c

    r101ef25c r243cb86  
    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

    r101ef25c r243cb86  
    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

    r101ef25c r243cb86  
    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

    r101ef25c r243cb86  
    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

    r101ef25c r243cb86  
    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

    r101ef25c r243cb86  
    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

    r101ef25c r243cb86  
    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

    r101ef25c r243cb86  
    5252static void remote_usbhc_control_read_data(device_t *, void *, ipc_callid_t, ipc_call_t *);
    5353static void remote_usbhc_control_read_status(device_t *, void *, ipc_callid_t, ipc_call_t *);
     54static void remote_usbhc_reserve_default_address(device_t *, void *, ipc_callid_t, ipc_call_t *);
     55static void remote_usbhc_release_default_address(device_t *, void *, ipc_callid_t, ipc_call_t *);
     56static void remote_usbhc_request_address(device_t *, void *, ipc_callid_t, ipc_call_t *);
     57static void remote_usbhc_bind_address(device_t *, void *, ipc_callid_t, ipc_call_t *);
     58static void remote_usbhc_release_address(device_t *, void *, ipc_callid_t, ipc_call_t *);
    5459//static void remote_usbhc(device_t *, void *, ipc_callid_t, ipc_call_t *);
    5560
     
    5762static remote_iface_func_ptr_t remote_usbhc_iface_ops [] = {
    5863        remote_usbhc_get_address,
     64
    5965        remote_usbhc_get_buffer,
     66
     67        remote_usbhc_reserve_default_address,
     68        remote_usbhc_release_default_address,
     69
     70        remote_usbhc_request_address,
     71        remote_usbhc_bind_address,
     72        remote_usbhc_release_address,
     73
    6074        remote_usbhc_interrupt_out,
    6175        remote_usbhc_interrupt_in,
     76
    6277        remote_usbhc_control_write_setup,
    6378        remote_usbhc_control_write_data,
    6479        remote_usbhc_control_write_status,
     80
    6581        remote_usbhc_control_read_setup,
    6682        remote_usbhc_control_read_data,
     
    92108        }
    93109
    94         devman_handle_t handle = IPC_GET_ARG1(*call);
     110        devman_handle_t handle = DEV_IPC_GET_ARG1(*call);
    95111
    96112        usb_address_t address;
     
    106122    ipc_callid_t callid, ipc_call_t *call)
    107123{
    108         ipcarg_t buffer_hash = IPC_GET_ARG1(*call);
     124        ipcarg_t buffer_hash = DEV_IPC_GET_ARG1(*call);
    109125        async_transaction_t * trans = (async_transaction_t *)buffer_hash;
    110126        if (trans == NULL) {
     
    128144                accepted_size = trans->size;
    129145        }
    130         async_data_read_finalize(callid, trans->buffer, accepted_size);
     146        async_data_read_finalize(cid, trans->buffer, accepted_size);
    131147
    132148        ipc_answer_1(callid, EOK, accepted_size);
     
    134150        free(trans->buffer);
    135151        free(trans);
     152}
     153
     154void remote_usbhc_reserve_default_address(device_t *device, void *iface,
     155    ipc_callid_t callid, ipc_call_t *call)
     156{
     157        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     158
     159        if (!usb_iface->reserve_default_address) {
     160                ipc_answer_0(callid, ENOTSUP);
     161                return;
     162        }
     163
     164        int rc = usb_iface->reserve_default_address(device);
     165
     166        ipc_answer_0(callid, rc);
     167}
     168
     169void remote_usbhc_release_default_address(device_t *device, void *iface,
     170    ipc_callid_t callid, ipc_call_t *call)
     171{
     172        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     173
     174        if (!usb_iface->release_default_address) {
     175                ipc_answer_0(callid, ENOTSUP);
     176                return;
     177        }
     178
     179        int rc = usb_iface->release_default_address(device);
     180
     181        ipc_answer_0(callid, rc);
     182}
     183
     184void remote_usbhc_request_address(device_t *device, void *iface,
     185    ipc_callid_t callid, ipc_call_t *call)
     186{
     187        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     188
     189        if (!usb_iface->request_address) {
     190                ipc_answer_0(callid, ENOTSUP);
     191                return;
     192        }
     193
     194        usb_address_t address;
     195        int rc = usb_iface->request_address(device, &address);
     196        if (rc != EOK) {
     197                ipc_answer_0(callid, rc);
     198        } else {
     199                ipc_answer_1(callid, EOK, (ipcarg_t) address);
     200        }
     201}
     202
     203void remote_usbhc_bind_address(device_t *device, void *iface,
     204    ipc_callid_t callid, ipc_call_t *call)
     205{
     206        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     207
     208        if (!usb_iface->bind_address) {
     209                ipc_answer_0(callid, ENOTSUP);
     210                return;
     211        }
     212
     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);
     215
     216        int rc = usb_iface->bind_address(device, address, handle);
     217
     218        ipc_answer_0(callid, rc);
     219}
     220
     221void remote_usbhc_release_address(device_t *device, void *iface,
     222    ipc_callid_t callid, ipc_call_t *call)
     223{
     224        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     225
     226        if (!usb_iface->release_address) {
     227                ipc_answer_0(callid, ENOTSUP);
     228                return;
     229        }
     230
     231        usb_address_t address = (usb_address_t) DEV_IPC_GET_ARG1(*call);
     232
     233        int rc = usb_iface->release_address(device, address);
     234
     235        ipc_answer_0(callid, rc);
    136236}
    137237
     
    175275        }
    176276
    177         size_t expected_len = IPC_GET_ARG3(*call);
     277        size_t expected_len = DEV_IPC_GET_ARG3(*call);
    178278        usb_target_t target = {
    179                 .address = IPC_GET_ARG1(*call),
    180                 .endpoint = IPC_GET_ARG2(*call)
     279                .address = DEV_IPC_GET_ARG1(*call),
     280                .endpoint = DEV_IPC_GET_ARG2(*call)
    181281        };
    182282
     
    227327        }
    228328
    229         size_t len = IPC_GET_ARG3(*call);
     329        size_t len = DEV_IPC_GET_ARG3(*call);
    230330        usb_target_t target = {
    231                 .address = IPC_GET_ARG1(*call),
    232                 .endpoint = IPC_GET_ARG2(*call)
     331                .address = DEV_IPC_GET_ARG1(*call),
     332                .endpoint = DEV_IPC_GET_ARG2(*call)
    233333        };
    234334
     
    284384
    285385        usb_target_t target = {
    286                 .address = IPC_GET_ARG1(*call),
    287                 .endpoint = IPC_GET_ARG2(*call)
     386                .address = DEV_IPC_GET_ARG1(*call),
     387                .endpoint = DEV_IPC_GET_ARG2(*call)
    288388        };
    289389
  • uspace/lib/drv/include/driver.h

    r101ef25c r243cb86  
    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/drv/include/usbhc_iface.h

    r101ef25c r243cb86  
    111111
    112112
     113        /** Reserve usage of default address.
     114         * This call informs the host controller that the caller will be
     115         * using default USB address. It is duty of the HC driver to ensure
     116         * that only single entity will have it reserved.
     117         * The address is returned via IPC_M_USBHC_RELEASE_DEFAULT_ADDRESS.
     118         * The caller can start using the address after receiving EOK
     119         * answer.
     120         */
     121        IPC_M_USBHC_RESERVE_DEFAULT_ADDRESS,
     122
     123        /** Release usage of default address.
     124         * @see IPC_M_USBHC_RESERVE_DEFAULT_ADDRESS
     125         */
     126        IPC_M_USBHC_RELEASE_DEFAULT_ADDRESS,
     127
     128        /** Asks for address assignment by host controller.
     129         * Answer:
     130         * - ELIMIT - host controller run out of address
     131         * - EOK - address assigned
     132         * Answer arguments:
     133         * - assigned address
     134         *
     135         * The address must be released by via IPC_M_USBHC_RELEASE_ADDRESS.
     136         */
     137        IPC_M_USBHC_REQUEST_ADDRESS,
     138
     139        /** Bind USB address with devman handle.
     140         * Parameters:
     141         * - USB address
     142         * - devman handle
     143         * Answer:
     144         * - EOK - address binded
     145         * - ENOENT - address is not in use
     146         */
     147        IPC_M_USBHC_BIND_ADDRESS,
     148
     149        /** Release address in use.
     150         * Arguments:
     151         * - address to be released
     152         * Answer:
     153         * - ENOENT - address not in use
     154         * - EPERM - trying to release default USB address
     155         */
     156        IPC_M_USBHC_RELEASE_ADDRESS,
     157
     158
    113159        /** Send interrupt data to device.
    114160         * See explanation at usb_iface_funcs_t (OUT transaction).
     
    183229typedef struct {
    184230        int (*tell_address)(device_t *, devman_handle_t, usb_address_t *);
     231
     232        int (*reserve_default_address)(device_t *);
     233        int (*release_default_address)(device_t *);
     234        int (*request_address)(device_t *, usb_address_t *);
     235        int (*bind_address)(device_t *, usb_address_t, devman_handle_t);
     236        int (*release_address)(device_t *, usb_address_t);
    185237
    186238        usbhc_iface_transfer_out_t interrupt_out;
  • uspace/lib/usb/Makefile

    r101ef25c r243cb86  
    3333
    3434SOURCES = \
     35        src/addrkeep.c \
     36        src/debug.c \
     37        src/drvpsync.c \
    3538        src/hcdhubd.c \
    3639        src/hcdrv.c \
    37         src/hubdrv.c \
     40        src/hidparser.c \
    3841        src/localdrv.c \
    3942        src/remotedrv.c \
    4043        src/usb.c \
     44        src/usbdrvreq.c \
    4145        src/usbdrv.c
    4246
  • uspace/lib/usb/include/usb/classes/hid.h

    r101ef25c r243cb86  
    3838#include <usb/usb.h>
    3939#include <driver.h>
     40#include <usb/classes/hidparser.h>
    4041
    4142/** USB/HID device requests. */
     
    6667        usb_address_t address;
    6768        usb_endpoint_t default_ep;
     69        usb_hid_report_parser_t *parser;
    6870} usb_hid_dev_kbd_t;
    6971
  • uspace/lib/usb/include/usb/devreq.h

    r101ef25c r243cb86  
    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

    r101ef25c r243cb86  
    116116} usb_hcd_transfer_ops_t;
    117117
     118/**
     119 * @brief structure holding information about free and used addresses
     120 *
     121 * This structure should not be used outside usb hcd driver.
     122 * You better consider it to be 'private'.
     123 */
     124typedef struct {
     125        /** lower bound included in the interval */
     126        usb_address_t lower_bound;
     127
     128        /** upper bound, excluded from the interval */
     129        usb_address_t upper_bound;
     130
     131        /** */
     132        link_t link;
     133}usb_address_list_t;
     134
    118135struct usb_hc_device {
    119136        /** Transfer operations. */
     
    131148        /** List of hubs operating from this HC. */
    132149        link_t hubs;
     150
     151        /** Structure with free and used addresses */
     152        link_t addresses;
    133153
    134154        /** Link to other driven HCs. */
     
    146166
    147167int usb_hcd_main(usb_hc_driver_t *);
    148 int usb_hcd_add_root_hub(usb_hc_device_t *dev);
     168int usb_hcd_add_root_hub(device_t *dev);
     169
     170/**
     171 * find first not yet used address on this host controller and use it
     172 * @param this_hcd
     173 * @return number in the range of allowed usb addresses or
     174 *     a negative number if not succesful
     175 */
     176usb_address_t usb_use_free_address(usb_hc_device_t * this_hcd);
     177
     178/**
     179 * @brief free the address in the address space of this hcd.
     180 *
     181 * if address is not used, nothing happens
     182 * @param this_hcd
     183 * @param addr
     184 */
     185void usb_free_used_address(usb_hc_device_t * this_hcd, usb_address_t addr );
    149186
    150187
     
    154191 */
    155192
     193device_t *usb_hc_connect(device_t *);
    156194
    157195int usb_hc_async_interrupt_out(usb_hc_device_t *, usb_target_t,
  • uspace/lib/usb/include/usb/usb.h

    r101ef25c r243cb86  
    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

    r101ef25c r243cb86  
    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);
     44
     45int usb_drv_reserve_default_address(int);
     46int usb_drv_release_default_address(int);
     47usb_address_t usb_drv_request_address(int);
     48int usb_drv_bind_address(int, usb_address_t, devman_handle_t);
     49int usb_drv_release_address(int, usb_address_t);
    4250
    4351usb_address_t usb_drv_get_my_address(int, device_t *);
     
    4856    void *, size_t, size_t *, usb_handle_t *);
    4957
     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
    5063int usb_drv_async_control_write_setup(int, usb_target_t,
    5164    void *, size_t, usb_handle_t *);
     
    5467int usb_drv_async_control_write_status(int, usb_target_t,
    5568    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
    5677
    5778int usb_drv_async_control_read_setup(int, usb_target_t,
     
    6283    usb_handle_t *);
    6384
     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
    6494int usb_drv_async_wait_for(usb_handle_t);
     95
    6596
    6697#endif
  • uspace/lib/usb/src/hcdhubd.c

    r101ef25c r243cb86  
    5151 */
    5252static int add_device(device_t *dev) {
    53         bool is_hc = str_cmp(dev->name, USB_HUB_DEVICE_NAME) != 0;
    54         printf("%s: add_device(name=\"%s\")\n", hc_driver->name, dev->name);
    55 
    56         if (is_hc) {
    57                 /*
    58                  * We are the HC itself.
    59                  */
    60                 return usb_add_hc_device(dev);
    61         } else {
    62                 /*
    63                  * We are some (maybe deeply nested) hub.
    64                  * Thus, assign our own operations and explore already
    65                  * connected devices.
    66                  */
    67                 return usb_add_hub_device(dev);
    68         }
     53        return ENOTSUP;
    6954}
    7055
     
    10590 * @return Error code.
    10691 */
    107 int usb_hcd_add_root_hub(usb_hc_device_t *dev)
     92int usb_hcd_add_root_hub(device_t *dev)
    10893{
    10994        char *id;
    110         int rc = asprintf(&id, "usb&hc=%s&hub", hc_driver->name);
     95        int rc = asprintf(&id, "usb&hub");
    11196        if (rc <= 0) {
    11297                return rc;
    11398        }
    11499
    115         rc = usb_hc_add_child_device(dev->generic, USB_HUB_DEVICE_NAME, id, true);
     100        rc = usb_hc_add_child_device(dev, USB_HUB_DEVICE_NAME, id, true);
    116101        if (rc != EOK) {
    117102                free(id);
     
    129114
    130115/** Adds a child device fibril worker. */
    131 static int fibril_add_child_device(void *arg)
    132 {
     116static int fibril_add_child_device(void *arg) {
    133117        struct child_device_info *child_info
    134             = (struct child_device_info *) arg;
     118                        = (struct child_device_info *) arg;
    135119        int rc;
    136120
     
    156140
    157141        printf("%s: adding child device `%s' with match \"%s\"\n",
    158             hc_driver->name, child->name, match_id->id);
     142                        hc_driver->name, child->name, match_id->id);
    159143        rc = child_device_register(child, child_info->parent);
    160144        printf("%s: child device `%s' registration: %s\n",
    161             hc_driver->name, child->name, str_error(rc));
     145                        hc_driver->name, child->name, str_error(rc));
    162146
    163147        if (rc != EOK) {
     
    197181 */
    198182int usb_hc_add_child_device(device_t *parent, const char *name,
    199     const char *match_id, bool create_fibril)
    200 {
     183                const char *match_id, bool create_fibril) {
    201184        printf("%s: about to add child device `%s' (%s)\n", hc_driver->name,
    202             name, match_id);
     185                        name, match_id);
    203186
    204187        /*
     
    209192
    210193        struct child_device_info *child_info
    211             = malloc(sizeof(struct child_device_info));
     194                        = malloc(sizeof (struct child_device_info));
    212195
    213196        child_info->parent = parent;
     
    233216 * @return USB device address or error code.
    234217 */
    235 usb_address_t usb_get_address_by_handle(devman_handle_t handle)
    236 {
     218usb_address_t usb_get_address_by_handle(devman_handle_t handle) {
    237219        /* TODO: search list of attached devices. */
    238220        return ENOENT;
    239221}
    240222
     223usb_address_t usb_use_free_address(usb_hc_device_t * this_hcd) {
     224        //is there free address?
     225        link_t * addresses = &this_hcd->addresses;
     226        if (list_empty(addresses)) return -1;
     227        link_t * link_addr = addresses;
     228        bool found = false;
     229        usb_address_list_t * range = NULL;
     230        while (!found) {
     231                link_addr = link_addr->next;
     232                if (link_addr == addresses) return -2;
     233                range = list_get_instance(link_addr,
     234                                usb_address_list_t, link);
     235                if (range->upper_bound - range->lower_bound > 0) {
     236                        found = true;
     237                }
     238        }
     239        //now we have interval
     240        int result = range->lower_bound;
     241        ++(range->lower_bound);
     242        if (range->upper_bound - range->lower_bound == 0) {
     243                list_remove(&range->link);
     244                free(range);
     245        }
     246        return result;
     247}
     248
     249void usb_free_used_address(usb_hc_device_t * this_hcd, usb_address_t addr) {
     250        //check range
     251        if (addr < usb_lowest_address || addr > usb_highest_address)
     252                return;
     253        link_t * addresses = &this_hcd->addresses;
     254        link_t * link_addr = addresses;
     255        //find 'good' interval
     256        usb_address_list_t * found_range = NULL;
     257        bool found = false;
     258        while (!found) {
     259                link_addr = link_addr->next;
     260                if (link_addr == addresses) {
     261                        found = true;
     262                } else {
     263                        usb_address_list_t * range = list_get_instance(link_addr,
     264                                        usb_address_list_t, link);
     265                        if (    (range->lower_bound - 1 == addr) ||
     266                                        (range->upper_bound == addr)) {
     267                                found = true;
     268                                found_range = range;
     269                        }
     270                        if (range->lower_bound - 1 > addr) {
     271                                found = true;
     272                        }
     273
     274                }
     275        }
     276        if (found_range == NULL) {
     277                //no suitable range found
     278                usb_address_list_t * result_range =
     279                                (usb_address_list_t*) malloc(sizeof (usb_address_list_t));
     280                result_range->lower_bound = addr;
     281                result_range->upper_bound = addr + 1;
     282                list_insert_before(&result_range->link, link_addr);
     283        } else {
     284                //we have good range
     285                if (found_range->lower_bound - 1 == addr) {
     286                        --found_range->lower_bound;
     287                } else {
     288                        //only one possible case
     289                        ++found_range->upper_bound;
     290                        if (found_range->link.next != addresses) {
     291                                usb_address_list_t * next_range =
     292                                                list_get_instance( &found_range->link.next,
     293                                                usb_address_list_t, link);
     294                                //check neighbour range
     295                                if (next_range->lower_bound == addr + 1) {
     296                                        //join ranges
     297                                        found_range->upper_bound = next_range->upper_bound;
     298                                        list_remove(&next_range->link);
     299                                        free(next_range);
     300                                }
     301                        }
     302                }
     303        }
     304
     305}
     306
    241307/**
    242308 * @}
  • uspace/lib/usb/src/hcdhubd_private.h

    r101ef25c r243cb86  
    4646usb_address_t usb_get_address_by_handle(devman_handle_t);
    4747int usb_add_hc_device(device_t *);
    48 int usb_add_hub_device(device_t *);
     48
     49/** lowest allowed usb address */
     50extern int usb_lowest_address;
     51
     52/** highest allowed usb address */
     53extern int usb_highest_address;
     54
     55/**
     56 * @brief initialize address list of given hcd
     57 *
     58 * This function should be used only for hcd initialization.
     59 * It creates interval list of free addresses, thus it is initialized as
     60 * list with one interval with whole address space. Using an address shrinks
     61 * the interval, freeing an address extends an interval or creates a
     62 * new one.
     63 *
     64 * @param hcd
     65 * @return
     66 */
     67void  usb_create_address_list(usb_hc_device_t * hcd);
     68
     69
     70
     71
     72
    4973
    5074#endif
  • uspace/lib/usb/src/hcdrv.c

    r101ef25c r243cb86  
    4747LIST_INITIALIZE(hc_list);
    4848
     49/* Fake driver to have the name item initialized. */
     50static usb_hc_driver_t hc_driver_fake = {
     51        .name = "HCD",
     52};
     53
    4954/** Our HC driver. */
    50 usb_hc_driver_t *hc_driver = NULL;
     55usb_hc_driver_t *hc_driver = &hc_driver_fake;
     56
     57int usb_lowest_address = 1;
     58
     59int usb_highest_address = 255;
    5160
    5261static device_ops_t usb_device_ops = {
    5362        .interfaces[USBHC_DEV_IFACE] = &usbhc_interface
    5463};
     64
     65
     66void usb_create_address_list(usb_hc_device_t * hcd){
     67        list_initialize(&hcd->addresses);
     68        usb_address_list_t * range =
     69                        (usb_address_list_t*)malloc(sizeof(usb_address_list_t));
     70        range->lower_bound = usb_lowest_address;
     71        range->upper_bound = usb_highest_address + 1;
     72        list_append(&range->link, &hcd->addresses);
     73}
    5574
    5675static usb_hc_device_t *usb_hc_device_create(device_t *dev) {
     
    5978        list_initialize(&hc_dev->link);
    6079        list_initialize(&hc_dev->hubs);
     80        usb_create_address_list(hc_dev);
    6181        list_initialize(&hc_dev->attached_devices);
    6282        hc_dev->transfer_ops = NULL;
     
    7191int usb_add_hc_device(device_t *dev)
    7292{
     93        return ENOTSUP;
    7394        usb_hc_device_t *hc_dev = usb_hc_device_create(dev);
    7495
  • uspace/lib/usb/src/localdrv.c

    r101ef25c r243cb86  
    3939#include <errno.h>
    4040
     41/** Find host controller when handled by current task.
     42 *
     43 * @param dev Device asking for connection.
     44 * @return Device structure corresponding to parent host controller.
     45 * @retval NULL Corresponding host controller not found.
     46 */
     47device_t *usb_hc_connect(device_t *dev)
     48{
     49        /*
     50         * FIXME: this will not work when some hub on the path is
     51         * not driven by the same task.
     52         */
     53        device_t *parent = dev;
     54        while (parent->parent != NULL) {
     55                parent = parent->parent;
     56        }
     57       
     58        if (dev == parent) {
     59                printf("FIXME in %s:%d encountered!\n", __FILE__, __LINE__);
     60                parent = NULL;
     61        }
     62
     63        return parent;
     64}
     65
    4166/** Information about pending transaction on HC. */
    4267typedef struct {
  • uspace/lib/usb/src/remotedrv.c

    r101ef25c r243cb86  
    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

    r101ef25c r243cb86  
    5555/** Connect to host controller the device is physically attached to.
    5656 *
    57  * @param handle Device handle.
     57 * @param dev Device asking for connection.
    5858 * @param flags Connection flags (blocking connection).
    5959 * @return Phone to corresponding HC or error code.
     
    7171        devman_handle_t handle;
    7272
    73         rc = devman_device_get_handle("/vhc", &handle, 0);
     73        rc = devman_device_get_handle("/virt/usbhc", &handle, 0);
    7474        if (rc != EOK) {
    7575                return rc;
     
    9898
    9999        return (usb_address_t) address;
     100}
     101
     102/** Tell HC to reserve default address.
     103 *
     104 * @param phone Open phone to host controller driver.
     105 * @return Error code.
     106 */
     107int usb_drv_reserve_default_address(int phone)
     108{
     109        return async_req_0_0(phone, IPC_M_USBHC_RESERVE_DEFAULT_ADDRESS);
     110}
     111
     112/** Tell HC to release default address.
     113 *
     114 * @param phone Open phone to host controller driver.
     115 * @return Error code.
     116 */
     117int usb_drv_release_default_address(int phone)
     118{
     119        return async_req_0_0(phone, IPC_M_USBHC_RELEASE_DEFAULT_ADDRESS);
     120}
     121
     122/** Ask HC for free address assignment.
     123 *
     124 * @param phone Open phone to host controller driver.
     125 * @return Assigned USB address or negative error code.
     126 */
     127usb_address_t usb_drv_request_address(int phone)
     128{
     129        ipcarg_t address;
     130        int rc = async_req_0_1(phone, IPC_M_USBHC_REQUEST_ADDRESS, &address);
     131        if (rc != EOK) {
     132                return rc;
     133        } else {
     134                return (usb_address_t) address;
     135        }
     136}
     137
     138/** Inform HC about binding address with devman handle.
     139 *
     140 * @param phone Open phone to host controller driver.
     141 * @param address Address to be binded.
     142 * @param handle Devman handle of the device.
     143 * @return Error code.
     144 */
     145int usb_drv_bind_address(int phone, usb_address_t address,
     146    devman_handle_t handle)
     147{
     148        int rc = async_req_2_0(phone, IPC_M_USBHC_BIND_ADDRESS,
     149            address, handle);
     150
     151        return rc;
     152}
     153
     154/** Inform HC about address release.
     155 *
     156 * @param phone Open phone to host controller driver.
     157 * @param address Address to be released.
     158 * @return Error code.
     159 */
     160int usb_drv_release_address(int phone, usb_address_t address)
     161{
     162        return async_req_1_0(phone, IPC_M_USBHC_RELEASE_ADDRESS, address);
    100163}
    101164
  • uspace/lib/usbvirt/main.c

    r101ef25c r243cb86  
    183183}
    184184
    185 /** Create necessary phones for comunication with virtual HCD.
     185/** Create necessary phones for communication with virtual HCD.
    186186 * This function wraps following calls:
    187  * -# open <code>/dev/devices/\\vhc for reading
     187 * -# open <code>/dev/devices/\\virt\\usbhc for reading
    188188 * -# access phone of file opened in previous step
    189189 * -# create callback through just opened phone
     
    193193 * @warning This function is wrapper for several actions and therefore
    194194 * it is not possible - in case of error - to determine at which point
    195  * error occured.
    196  *
    197  * @param hcd_path HCD identification under devfs
    198  *     (without <code>/dev/usb/</code>).
     195 * error occurred.
     196 *
    199197 * @param dev Device to connect.
    200198 * @return EOK on success or error code from errno.h.
     
    207205        }
    208206       
    209         const char *vhc_path = "/vhc";
     207        const char *vhc_path = "/virt/usbhc";
    210208        int rc;
    211209        devman_handle_t handle;
  • uspace/srv/bd/file_bd/file_bd.c

    r101ef25c r243cb86  
    5656#define NAME "file_bd"
    5757
    58 static const size_t block_size = 512;
     58#define DEFAULT_BLOCK_SIZE 512
     59
     60static size_t block_size;
    5961static aoff64_t num_blocks;
    6062static FILE *img;
     
    6365static fibril_mutex_t dev_lock;
    6466
     67static void print_usage(void);
    6568static int file_bd_init(const char *fname);
    6669static void file_bd_connection(ipc_callid_t iid, ipc_call_t *icall);
     
    7174{
    7275        int rc;
     76        char *image_name;
     77        char *device_name;
    7378
    7479        printf(NAME ": File-backed block device driver\n");
    7580
    76         if (argc != 3) {
    77                 printf("Expected two arguments (image name, device name).\n");
     81        block_size = DEFAULT_BLOCK_SIZE;
     82
     83        ++argv; --argc;
     84        while (*argv != NULL && (*argv)[0] == '-') {
     85                /* Option */
     86                if (str_cmp(*argv, "-b") == 0) {
     87                        if (argc < 2) {
     88                                printf("Argument missing.\n");
     89                                print_usage();
     90                                return -1;
     91                        }
     92
     93                        rc = str_size_t(argv[1], NULL, 10, true, &block_size);
     94                        if (rc != EOK || block_size == 0) {
     95                                printf("Invalid block size '%s'.\n", argv[1]);
     96                                print_usage();
     97                                return -1;
     98                        }
     99                        ++argv; --argc;
     100                } else {
     101                        printf("Invalid option '%s'.\n", *argv);
     102                        print_usage();
     103                        return -1;
     104                }
     105                ++argv; --argc;
     106        }
     107
     108        if (argc < 2) {
     109                printf("Missing arguments.\n");
     110                print_usage();
    78111                return -1;
    79112        }
    80113
    81         if (file_bd_init(argv[1]) != EOK)
     114        image_name = argv[0];
     115        device_name = argv[1];
     116
     117        if (file_bd_init(image_name) != EOK)
    82118                return -1;
    83119
    84         rc = devmap_device_register(argv[2], &devmap_handle);
     120        rc = devmap_device_register(device_name, &devmap_handle);
    85121        if (rc != EOK) {
    86122                devmap_hangup_phone(DEVMAP_DRIVER);
    87                 printf(NAME ": Unable to register device %s.\n",
    88                         argv[2]);
     123                printf(NAME ": Unable to register device '%s'.\n",
     124                        device_name);
    89125                return rc;
    90126        }
     
    96132        /* Not reached */
    97133        return 0;
     134}
     135
     136static void print_usage(void)
     137{
     138        printf("Usage: " NAME " [-b <block_size>] <image_file> <device_name>\n");
    98139}
    99140
  • uspace/srv/devman/devman.c

    r101ef25c r243cb86  
    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
     688static FIBRIL_MUTEX_INITIALIZE(add_device_guard);
    639689
    640690/** Pass a device to running driver.
     
    645695void add_device(int phone, driver_t *drv, node_t *node, dev_tree_t *tree)
    646696{
    647         printf(NAME ": add_device\n");
     697        fibril_mutex_lock(&add_device_guard);
     698
     699        /*
     700         * We do not expect to have driver's mutex locked as we do not
     701         * access any structures that would affect driver_t.
     702         */
     703        printf(NAME ": add_device (driver `%s', device `%s')\n", drv->name,
     704            node->name);
    648705       
    649706        ipcarg_t rc;
     
    657714                parent_handle = 0;
    658715        }
     716
    659717        aid_t req = async_send_2(phone, DRIVER_ADD_DEVICE, node->handle,
    660718            parent_handle, &answer);
     
    666724                /* TODO handle error */
    667725        }
    668        
     726
    669727        /* Wait for answer from the driver. */
    670728        async_wait_for(req, &rc);
     729
     730        fibril_mutex_unlock(&add_device_guard);
     731
    671732        switch(rc) {
    672733        case EOK:
     
    681742        }
    682743       
     744        node->passed_to_driver = true;
     745
    683746        return;
    684747}
     
    706769        attach_driver(node, drv);
    707770       
     771        fibril_mutex_lock(&drv->driver_mutex);
    708772        if (drv->state == DRIVER_NOT_STARTED) {
    709773                /* Start the driver. */
    710774                start_driver(drv);
    711775        }
    712        
    713         if (drv->state == DRIVER_RUNNING) {
     776        bool is_running = drv->state == DRIVER_RUNNING;
     777        fibril_mutex_unlock(&drv->driver_mutex);
     778
     779        if (is_running) {
    714780                /* Notify the driver about the new device. */
    715                 int phone = ipc_connect_me_to(drv->phone, DRIVER_DEVMAN, 0, 0);
     781                int phone = async_connect_me_to(drv->phone, DRIVER_DEVMAN, 0, 0);
    716782                if (phone > 0) {
    717783                        add_device(phone, drv, node, tree);
     
    875941        node->name = dev_name;
    876942        if (!set_dev_path(node, parent)) {
    877                 fibril_rwlock_write_unlock(&tree->rwlock);
    878943                return false;
    879944        }
     
    10971162        while (link != &class_list->classes) {
    10981163                cl = list_get_instance(link, dev_class_t, link);
    1099                 if (str_cmp(cl->name, class_name) == 0)
     1164                if (str_cmp(cl->name, class_name) == 0) {
    11001165                        return cl;
     1166                }
     1167                link = link->next;
    11011168        }
    11021169       
  • uspace/srv/devman/devman.h

    r101ef25c r243cb86  
    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

    r101ef25c r243cb86  
    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

    r101ef25c r243cb86  
    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

    r101ef25c r243cb86  
    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

    r101ef25c r243cb86  
    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

    r101ef25c r243cb86  
    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

    r101ef25c r243cb86  
    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

    r101ef25c r243cb86  
    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

    r101ef25c r243cb86  
    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

    r101ef25c r243cb86  
    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

    r101ef25c r243cb86  
    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.