Changeset f37f811 in mainline


Ignore:
Timestamp:
2010-12-15T22:25:01Z (13 years ago)
Author:
Vojtech Horky <vojtechhorky@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
cea3fca
Parents:
ea5dbaf (diff), e63a4e1 (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 usbvirt clean-up branch

Location:
uspace
Files:
5 added
2 deleted
15 edited
9 moved

Legend:

Unmodified
Added
Removed
  • uspace/app/virtusbkbd/Makefile

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

    rea5dbaf rf37f811  
    3939#include "kbdconfig.h"
    4040
    41 static int on_get_descriptor(struct usbvirt_device *dev,
    42     usb_device_request_setup_packet_t *request, uint8_t *data);
    43 
    44 usbvirt_standard_device_request_ops_t standard_request_ops = {
    45         .on_get_status = NULL,
    46         .on_clear_feature = NULL,
    47         .on_set_feature = NULL,
    48         .on_set_address = NULL,
    49         .on_get_descriptor = on_get_descriptor,
    50         .on_set_descriptor = NULL,
    51         .on_get_configuration = NULL,
    52         .on_set_configuration = NULL,
    53         .on_get_interface = NULL,
    54         .on_set_interface = NULL,
    55         .on_synch_frame = NULL
    56 };
    57 
    58 
    59 static int on_get_descriptor(struct usbvirt_device *dev,
     41int stdreq_on_get_descriptor(struct usbvirt_device *dev,
    6042    usb_device_request_setup_packet_t *request, uint8_t *data)
    6143{
  • uspace/app/virtusbkbd/stdreq.h

    rea5dbaf rf37f811  
    3838#include <usbvirt/device.h>
    3939
    40 extern usbvirt_standard_device_request_ops_t standard_request_ops;
     40int stdreq_on_get_descriptor(usbvirt_device_t *,
     41    usb_device_request_setup_packet_t *, uint8_t *);
    4142
    4243#endif
  • uspace/app/virtusbkbd/virtusbkbd.c

    rea5dbaf rf37f811  
    7676}
    7777
    78 static int on_class_request(struct usbvirt_device *dev,
    79     usb_device_request_setup_packet_t *request, uint8_t *data)
    80 {       
    81         printf("%s: class request (%d)\n", NAME, (int) request->request);
    82        
    83         return EOK;
    84 }
    8578
    8679/** Compares current and last status of pressed keys.
     
    138131}
    139132
     133static usbvirt_control_transfer_handler_t endpoint_zero_handlers[] = {
     134        {
     135                .request_type = USBVIRT_MAKE_CONTROL_REQUEST_TYPE(
     136                    USB_DIRECTION_IN,
     137                    USBVIRT_REQUEST_TYPE_STANDARD,
     138                    USBVIRT_REQUEST_RECIPIENT_DEVICE),
     139                .request = USB_DEVREQ_GET_DESCRIPTOR,
     140                .name = "GetDescriptor",
     141                .callback = stdreq_on_get_descriptor
     142        },
     143        {
     144                .request_type = USBVIRT_MAKE_CONTROL_REQUEST_TYPE(
     145                    USB_DIRECTION_IN,
     146                    USBVIRT_REQUEST_TYPE_CLASS,
     147                    USBVIRT_REQUEST_RECIPIENT_DEVICE),
     148                .request = USB_DEVREQ_GET_DESCRIPTOR,
     149                .name = "GetDescriptor",
     150                .callback = stdreq_on_get_descriptor
     151        },
     152        USBVIRT_CONTROL_TRANSFER_HANDLER_LAST
     153};
    140154
    141155/** Keyboard callbacks.
     
    143157 */
    144158static usbvirt_device_ops_t keyboard_ops = {
    145         .standard_request_ops = &standard_request_ops,
    146         .on_class_device_request = on_class_request,
     159        .control_transfer_handlers = endpoint_zero_handlers,
    147160        .on_data = on_incoming_data,
    148161        .on_data_request = on_request_for_data
     
    257270       
    258271        printf("%s: Simulating keyboard events...\n", NAME);
     272        fibril_sleep(10);
    259273        while (1) {
    260274                kb_process_events(&status, keyboard_events, keyboard_events_count,
  • uspace/drv/vhc/Makefile

    rea5dbaf rf37f811  
    3333        $(LIBDRV_PREFIX)/libdrv.a
    3434EXTRA_CFLAGS += \
    35         -I$(LIB_PREFIX) \
     35        -I$(LIBUSBVIRT_PREFIX)/include \
    3636        -I$(LIBUSB_PREFIX)/include \
    3737        -I$(LIBDRV_PREFIX)/include
     
    3939
    4040SOURCES = \
     41        hub/hub.c \
     42        hub/virthub.c \
     43        hub/virthubops.c \
    4144        conndev.c \
    4245        connhost.c \
     
    4548        hc.c \
    4649        hcd.c \
    47         hub.c \
    48         hubops.c
     50        hub.c
    4951
    5052include $(USPACE_PREFIX)/Makefile.common
  • uspace/drv/vhc/connhost.c

    rea5dbaf rf37f811  
    102102        transfer->out_callback = callback;
    103103
    104         hc_add_transaction_to_device(false, target, buffer, size,
     104        hc_add_transaction_to_device(false, target, transfer_type, buffer, size,
    105105            universal_callback, transfer);
    106106
     
    122122        transfer->out_callback = callback;
    123123
    124         hc_add_transaction_to_device(true, target, buffer, size,
     124        hc_add_transaction_to_device(true, target, transfer_type, buffer, size,
    125125            universal_callback, transfer);
    126126
     
    142142        transfer->in_callback = callback;
    143143
    144         hc_add_transaction_from_device(target, buffer, size,
     144        hc_add_transaction_from_device(target, transfer_type, buffer, size,
    145145            universal_callback, transfer);
    146146
  • uspace/drv/vhc/devices.c

    rea5dbaf rf37f811  
    4747#include "devices.h"
    4848#include "hub.h"
     49#include "hub/virthub.h"
    4950#include "vhcd.h"
    5051
     
    6970        list_append(&dev->link, &devices);
    7071       
    71         hub_add_device(dev);
     72        virthub_connect_device(&virtual_hub_device, dev);
    7273       
    7374        return dev;
     
    7879void virtdev_destroy_device(virtdev_connection_t *dev)
    7980{
    80         hub_remove_device(dev);
     81        virthub_disconnect_device(&virtual_hub_device, dev);
    8182        list_remove(&dev->link);
    8283        free(dev);
     
    9495                    = list_get_instance(pos, virtdev_connection_t, link);
    9596               
    96                 if (!hub_can_device_signal(dev)) {
     97                if (!virthub_is_device_enabled(&virtual_hub_device, dev)) {
    9798                        continue;
    9899                }
     
    145146         * (if the address matches).
    146147         */
    147         if (virthub_dev.address == transaction->target.address) {
     148        if (virtual_hub_device.address == transaction->target.address) {
    148149                size_t tmp;
    149150                dprintf(1, "sending `%s' transaction to hub",
     
    151152                switch (transaction->type) {
    152153                        case USBVIRT_TRANSACTION_SETUP:
    153                                 virthub_dev.transaction_setup(&virthub_dev,
     154                                virtual_hub_device.transaction_setup(
     155                                    &virtual_hub_device,
    154156                                    transaction->target.endpoint,
    155157                                    transaction->buffer, transaction->len);
     
    157159                               
    158160                        case USBVIRT_TRANSACTION_IN:
    159                                 virthub_dev.transaction_in(&virthub_dev,
     161                                virtual_hub_device.transaction_in(
     162                                    &virtual_hub_device,
    160163                                    transaction->target.endpoint,
    161164                                    transaction->buffer, transaction->len,
     
    167170                               
    168171                        case USBVIRT_TRANSACTION_OUT:
    169                                 virthub_dev.transaction_out(&virthub_dev,
     172                                virtual_hub_device.transaction_out(
     173                                    &virtual_hub_device,
    170174                                    transaction->target.endpoint,
    171175                                    transaction->buffer, transaction->len);
  • uspace/drv/vhc/hc.c

    rea5dbaf rf37f811  
    6868static link_t transaction_list;
    6969
    70 #define TRANSACTION_FORMAT "T[%d:%d %s (%d)]"
     70#define TRANSACTION_FORMAT "T[%d.%d %s/%s (%d)]"
    7171#define TRANSACTION_PRINTF(t) \
    7272        (t).target.address, (t).target.endpoint, \
     73        usb_str_transfer_type((t).transfer_type), \
    7374        usbvirt_str_transaction_type((t).type), \
    7475        (int)(t).len
     
    7677#define transaction_get_instance(lnk) \
    7778        list_get_instance(lnk, transaction_t, link)
     79
     80#define HUB_STATUS_MAX_LEN (HUB_PORT_COUNT + 64)
    7881
    7982static inline unsigned int pseudo_random(unsigned int *seed)
     
    99102/** Host controller manager main function.
    100103 */
    101 void hc_manager(void)
     104static int hc_manager_fibril(void *arg)
    102105{
    103106        list_initialize(&transaction_list);
     
    114117                }
    115118               
    116                 char ports[HUB_PORT_COUNT + 2];
    117                 hub_get_port_statuses(ports, HUB_PORT_COUNT + 1);
    118                 dprintf(4, "virtual hub: addr=%d ports=%s",
    119                     virthub_dev.address, ports);
     119                char ports[HUB_STATUS_MAX_LEN + 1];
     120                virthub_get_status(&virtual_hub_device, ports, HUB_STATUS_MAX_LEN);
    120121               
    121122                link_t *first_transaction_link = transaction_list.next;
     
    125126               
    126127
    127                 dprintf(0, "about to process " TRANSACTION_FORMAT " (vhub:%s)",
     128                dprintf(0, "about to process " TRANSACTION_FORMAT " [%s]",
    128129                    TRANSACTION_PRINTF(*transaction), ports);
    129130
     
    138139                free(transaction);
    139140        }
     141
     142        assert(false && "unreachable");
     143        return EOK;
     144}
     145
     146void hc_manager(void)
     147{
     148        fid_t fid = fibril_create(hc_manager_fibril, NULL);
     149        if (fid == 0) {
     150                printf(NAME ": failed to start HC manager fibril\n");
     151                return;
     152        }
     153        fibril_add_ready(fid);
    140154}
    141155
     
    143157 */
    144158static transaction_t *transaction_create(usbvirt_transaction_type_t type,
    145     usb_target_t target,
     159    usb_target_t target, usb_transfer_type_t transfer_type,
    146160    void * buffer, size_t len,
    147161    hc_transaction_done_callback_t callback, void * arg)
     
    151165        list_initialize(&transaction->link);
    152166        transaction->type = type;
     167        transaction->transfer_type = transfer_type;
    153168        transaction->target = target;
    154169        transaction->buffer = buffer;
     
    166181 */
    167182void hc_add_transaction_to_device(bool setup, usb_target_t target,
     183    usb_transfer_type_t transfer_type,
    168184    void * buffer, size_t len,
    169185    hc_transaction_done_callback_t callback, void * arg)
    170186{
    171187        transaction_t *transaction = transaction_create(
    172             setup ? USBVIRT_TRANSACTION_SETUP : USBVIRT_TRANSACTION_OUT, target,
     188            setup ? USBVIRT_TRANSACTION_SETUP : USBVIRT_TRANSACTION_OUT,
     189            target, transfer_type,
    173190            buffer, len, callback, arg);
    174191        list_append(&transaction->link, &transaction_list);
     
    178195 */
    179196void hc_add_transaction_from_device(usb_target_t target,
     197    usb_transfer_type_t transfer_type,
    180198    void * buffer, size_t len,
    181199    hc_transaction_done_callback_t callback, void * arg)
    182200{
    183201        transaction_t *transaction = transaction_create(USBVIRT_TRANSACTION_IN,
    184             target, buffer, len, callback, arg);
     202            target, transfer_type,
     203            buffer, len, callback, arg);
    185204        list_append(&transaction->link, &transaction_list);
    186205}
  • uspace/drv/vhc/hc.h

    rea5dbaf rf37f811  
    5555        /** Transaction type. */
    5656        usbvirt_transaction_type_t type;
     57        /** Transfer type. */
     58        usb_transfer_type_t transfer_type;
    5759        /** Device address. */
    5860        usb_target_t target;
     
    7173void hc_manager(void);
    7274
    73 void hc_add_transaction_to_device(bool setup, usb_target_t target,
     75void hc_add_transaction_to_device(bool setup,
     76    usb_target_t target, usb_transfer_type_t transfer_type,
    7477    void * buffer, size_t len,
    7578    hc_transaction_done_callback_t callback, void * arg);
    7679
    77 void hc_add_transaction_from_device(usb_target_t target,
     80void hc_add_transaction_from_device(
     81    usb_target_t target, usb_transfer_type_t transfer_type,
    7882    void * buffer, size_t len,
    7983    hc_transaction_done_callback_t callback, void * arg);
  • uspace/drv/vhc/hcd.c

    rea5dbaf rf37f811  
    7979         * Initialize our hub and announce its presence.
    8080         */
    81         hub_init(dev);
     81        virtual_hub_device_init(dev);
    8282
    8383        printf("%s: virtual USB host controller ready.\n", NAME);
     
    9595};
    9696
    97 /** Fibril wrapper for HC transaction manager.
    98  *
    99  * @param arg Not used.
    100  * @return Nothing, return argument is unreachable.
    101  */
    102 static int hc_manager_fibril(void *arg)
    103 {
    104         hc_manager();
    105         return EOK;
    106 }
    10797
    10898int main(int argc, char * argv[])
    10999{       
    110         printf("%s: virtual USB host controller driver.\n", NAME);
    111 
    112         usb_dprintf_enable(NAME, 0);
    113 
    114         fid_t fid = fibril_create(hc_manager_fibril, NULL);
    115         if (fid == 0) {
    116                 printf("%s: failed to start HC manager fibril\n", NAME);
    117                 return ENOMEM;
    118         }
    119         fibril_add_ready(fid);
    120 
    121100        /*
    122101         * Temporary workaround. Wait a little bit to be the last driver
    123102         * in devman output.
    124103         */
    125         sleep(4);
     104        sleep(5);
     105
     106        usb_dprintf_enable(NAME, 0);
     107
     108        printf(NAME ": virtual USB host controller driver.\n");
     109
     110        hc_manager();
    126111
    127112        return driver_main(&vhc_driver);
  • uspace/drv/vhc/hub.c

    rea5dbaf rf37f811  
    4040#include <stdlib.h>
    4141#include <driver.h>
     42#include <usb/usbdrv.h>
    4243
     44#include "hub.h"
     45#include "hub/virthub.h"
    4346#include "vhcd.h"
    44 #include "hub.h"
    45 #include "hubintern.h"
    46 #include "conn.h"
    4747
     48usbvirt_device_t virtual_hub_device;
    4849
    49 /** Standard device descriptor. */
    50 usb_standard_device_descriptor_t std_device_descriptor = {
    51         .length = sizeof(usb_standard_device_descriptor_t),
    52         .descriptor_type = USB_DESCTYPE_DEVICE,
    53         .usb_spec_version = 0x110,
    54         .device_class = USB_CLASS_HUB,
    55         .device_subclass = 0,
    56         .device_protocol = 0,
    57         .max_packet_size = 64,
    58         .configuration_count = 1
    59 };
     50static int hub_register_in_devman_fibril(void *arg);
    6051
    61 /** Standard interface descriptor. */
    62 usb_standard_interface_descriptor_t std_interface_descriptor = {
    63         .length = sizeof(usb_standard_interface_descriptor_t),
    64         .descriptor_type = USB_DESCTYPE_INTERFACE,
    65         .interface_number = 0,
    66         .alternate_setting = 0,
    67         .endpoint_count = 1,
    68         .interface_class = USB_CLASS_HUB,
    69         .interface_subclass = 0,
    70         .interface_protocol = 0,
    71         .str_interface = 0
    72 };
     52void virtual_hub_device_init(device_t *hc_dev)
     53{
     54        virthub_init(&virtual_hub_device);
    7355
    74 hub_descriptor_t hub_descriptor = {
    75         .length = sizeof(hub_descriptor_t),
    76         .type = USB_DESCTYPE_HUB,
    77         .port_count = HUB_PORT_COUNT,
    78         .characteristics = 0,
    79         .power_on_warm_up = 50, /* Huh? */
    80         .max_current = 100, /* Huh again. */
    81         .removable_device = { 0 },
    82         .port_power = { 0xFF }
    83 };
     56        /*
     57         * We need to register the root hub.
     58         * This must be done in separate fibril because the device
     59         * we are connecting to are ourselves and we cannot connect
     60         * before leaving the add_device() function.
     61         */
     62        fid_t root_hub_registration
     63            = fibril_create(hub_register_in_devman_fibril, hc_dev);
     64        if (root_hub_registration == 0) {
     65                printf(NAME ": failed to register root hub\n");
     66                return;
     67        }
    8468
    85 /** Endpoint descriptor. */
    86 usb_standard_endpoint_descriptor_t endpoint_descriptor = {
    87         .length = sizeof(usb_standard_endpoint_descriptor_t),
    88         .descriptor_type = USB_DESCTYPE_ENDPOINT,
    89         .endpoint_address = HUB_STATUS_CHANGE_PIPE | 128,
    90         .attributes = USB_TRANSFER_INTERRUPT,
    91         .max_packet_size = 8,
    92         .poll_interval = 0xFF
    93 };
    94 
    95 /** Standard configuration descriptor. */
    96 usb_standard_configuration_descriptor_t std_configuration_descriptor = {
    97         .length = sizeof(usb_standard_configuration_descriptor_t),
    98         .descriptor_type = USB_DESCTYPE_CONFIGURATION,
    99         .total_length =
    100                 sizeof(usb_standard_configuration_descriptor_t)
    101                 + sizeof(std_interface_descriptor)
    102                 + sizeof(hub_descriptor)
    103                 + sizeof(endpoint_descriptor)
    104                 ,
    105         .interface_count = 1,
    106         .configuration_number = HUB_CONFIGURATION_ID,
    107         .str_configuration = 0,
    108         .attributes = 128, /* denotes bus-powered device */
    109         .max_power = 50
    110 };
    111 
    112 /** All hub configuration descriptors. */
    113 static usbvirt_device_configuration_extras_t extra_descriptors[] = {
    114         {
    115                 .data = (uint8_t *) &std_interface_descriptor,
    116                 .length = sizeof(std_interface_descriptor)
    117         },
    118         {
    119                 .data = (uint8_t *) &hub_descriptor,
    120                 .length = sizeof(hub_descriptor)
    121         },
    122         {
    123                 .data = (uint8_t *) &endpoint_descriptor,
    124                 .length = sizeof(endpoint_descriptor)
    125         }
    126 };
    127 
    128 /** Hub configuration. */
    129 usbvirt_device_configuration_t configuration = {
    130         .descriptor = &std_configuration_descriptor,
    131         .extra = extra_descriptors,
    132         .extra_count = sizeof(extra_descriptors)/sizeof(extra_descriptors[0])
    133 };
    134 
    135 /** Hub standard descriptors. */
    136 usbvirt_descriptors_t descriptors = {
    137         .device = &std_device_descriptor,
    138         .configuration = &configuration,
    139         .configuration_count = 1,
    140 };
    141 
    142 /** Hub as a virtual device. */
    143 usbvirt_device_t virthub_dev = {
    144         .ops = &hub_ops,
    145         .descriptors = &descriptors,
    146         .lib_debug_level = 0,
    147         .lib_debug_enabled_tags = USBVIRT_DEBUGTAG_ALL
    148 };
    149 
    150 /** Hub device. */
    151 hub_device_t hub_dev;
    152 
    153 static 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;
     69        fibril_add_ready(root_hub_registration);
    17370}
    17471
    175 /** Initialize virtual hub. */
    176 void hub_init(device_t *hc_dev)
     72/** Register root hub in devman.
     73 *
     74 * @param arg Host controller device (type <code>device_t *</code>).
     75 * @return Error code.
     76 */
     77int hub_register_in_devman_fibril(void *arg)
    17778{
    178         size_t i;
    179        
    180         for (i = 0; i < HUB_PORT_COUNT; i++) {
    181                 hub_port_t *port = &hub_dev.ports[i];
    182                
    183                 port->index = (int) i + 1;
    184                 port->device = NULL;
    185                 port->state = HUB_PORT_STATE_NOT_CONFIGURED;
    186                 port->status_change = 0;
    187                 fibril_mutex_initialize(&port->guard);
    188         }
    189        
    190         usbvirt_connect_local(&virthub_dev);
    191        
    192         dprintf(1, "virtual hub (%d ports) created", HUB_PORT_COUNT);
     79        device_t *hc_dev = (device_t *) arg;
    19380
    194         usb_address_t hub_address = hub_set_address(&virthub_dev);
    195         if (hub_address < 0) {
    196                 dprintf(1, "problem changing hub address (%s)",
    197                     str_error(hub_address));
     81        int hc = usb_drv_hc_connect(hc_dev, IPC_FLAG_BLOCKING);
     82        if (hc < 0) {
     83                printf(NAME ": failed to register root hub\n");
     84                return hc;
    19885        }
    19986
    200         dprintf(2, "virtual hub address changed to %d", hub_address);
     87        usb_drv_reserve_default_address(hc);
    20188
    202         char *id;
    203         int rc = asprintf(&id, "usb&hub");
    204         if (rc <= 0) {
    205                 return;
    206         }
     89        usb_address_t hub_address = usb_drv_request_address(hc);
     90        usb_drv_req_set_address(hc, USB_ADDRESS_DEFAULT, hub_address);
     91
     92        usb_drv_release_default_address(hc);
     93
    20794        devman_handle_t hub_handle;
    208         rc = child_device_register_wrapper(hc_dev, "hub", id, 10, &hub_handle);
    209         if (rc != EOK) {
    210                 free(id);
    211         }
     95        usb_drv_register_child_in_devman(hc, hc_dev, hub_address, &hub_handle);
     96        usb_drv_bind_address(hc, hub_address, hub_handle);
    21297
    213         vhc_iface.bind_address(NULL, hub_address, hub_handle); 
    214 
    215         dprintf(2, "virtual hub has devman handle %d", (int) hub_handle);
     98        return EOK;
    21699}
    217 
    218 /** Connect device to the hub.
    219  *
    220  * @param device Device to be connected.
    221  * @return Port where the device was connected to.
    222  */
    223 size_t hub_add_device(virtdev_connection_t *device)
    224 {
    225         size_t i;
    226         for (i = 0; i < HUB_PORT_COUNT; i++) {
    227                 hub_port_t *port = &hub_dev.ports[i];
    228                 fibril_mutex_lock(&port->guard);
    229                
    230                 if (port->device != NULL) {
    231                         fibril_mutex_unlock(&port->guard);
    232                         continue;
    233                 }
    234                
    235                 port->device = device;
    236                
    237                 /*
    238                  * TODO:
    239                  * If the hub was configured, we can normally
    240                  * announce the plug-in.
    241                  * Otherwise, we will wait until hub is configured
    242                  * and announce changes in single burst.
    243                  */
    244                 //if (port->state == HUB_PORT_STATE_DISCONNECTED) {
    245                         port->state = HUB_PORT_STATE_DISABLED;
    246                         set_port_status_change_nl(port, HUB_STATUS_C_PORT_CONNECTION);
    247                 //}
    248                
    249                 fibril_mutex_unlock(&port->guard);
    250 
    251                 return i;
    252         }
    253100       
    254         return (size_t)-1;
    255 }
    256 
    257 /** Disconnect device from the hub. */
    258 void hub_remove_device(virtdev_connection_t *device)
    259 {
    260         size_t i;
    261         for (i = 0; i < HUB_PORT_COUNT; i++) {
    262                 hub_port_t *port = &hub_dev.ports[i];
    263                
    264                 if (port->device != device) {
    265                         continue;
    266                 }
    267                
    268                 port->device = NULL;
    269                 port->state = HUB_PORT_STATE_DISCONNECTED;
    270                
    271                 set_port_status_change(port, HUB_STATUS_C_PORT_CONNECTION);
    272         }
    273 }
    274 
    275 /** Tell whether device port is open.
    276  *
    277  * @return Whether communication to and from the device can go through the hub.
    278  */
    279 bool hub_can_device_signal(virtdev_connection_t * device)
    280 {
    281         size_t i;
    282         for (i = 0; i < HUB_PORT_COUNT; i++) {
    283                 if (hub_dev.ports[i].device == device) {
    284                         return hub_dev.ports[i].state == HUB_PORT_STATE_ENABLED;
    285                 }
    286         }
    287        
    288         return false;
    289 }
    290 
    291 /** Format hub port status.
    292  *
    293  * @param result Buffer where to store status string.
    294  * @param len Number of characters that is possible to store in @p result
    295  *      (excluding trailing zero).
    296  */
    297 void hub_get_port_statuses(char *result, size_t len)
    298 {
    299         if (len > HUB_PORT_COUNT) {
    300                 len = HUB_PORT_COUNT;
    301         }
    302         size_t i;
    303         for (i = 0; i < len; i++) {
    304                 result[i] = hub_port_state_as_char(hub_dev.ports[i].state);
    305         }
    306         result[len] = 0;
    307 }
    308101
    309102/**
  • uspace/drv/vhc/hub.h

    rea5dbaf rf37f811  
    4040
    4141#include "devices.h"
     42#include "hub/hub.h"
     43#include "hub/virthub.h"
    4244
    43 #define HUB_PORT_COUNT 2
     45extern usbvirt_device_t virtual_hub_device;
    4446
    45 #define BITS2BYTES(bits) \
    46     (bits ? ((((bits)-1)>>3)+1) : 0)
    47 
    48 extern usbvirt_device_t virthub_dev;
    49 
    50 void hub_init(device_t *);
    51 size_t hub_add_device(virtdev_connection_t *);
    52 void hub_remove_device(virtdev_connection_t *);
    53 bool hub_can_device_signal(virtdev_connection_t *);
    54 void hub_get_port_statuses(char *result, size_t len);
     47void virtual_hub_device_init(device_t *);
    5548
    5649#endif
  • uspace/drv/vhc/hub/virthub.h

    rea5dbaf rf37f811  
    3333 * @brief
    3434 */
    35 #ifndef VHCD_HUBINTERN_H_
    36 #define VHCD_HUBINTERN_H_
     35#ifndef VHC_HUB_VIRTHUB_H_
     36#define VHC_HUB_VIRTHUB_H_
    3737
     38#include <usbvirt/device.h>
     39#include "../devices.h"
    3840#include "hub.h"
    39 #include <fibril_synch.h>
    4041
    4142/** Endpoint number for status change pipe. */
     
    4344/** Configuration value for hub configuration. */
    4445#define HUB_CONFIGURATION_ID 1
     46
    4547
    4648/** Hub descriptor.
     
    6971} __attribute__ ((packed)) hub_descriptor_t;
    7072
    71 /** Hub port internal state.
    72  * Some states (e.g. port over current) are not covered as they are not
    73  * simulated at all.
    74  */
    75 typedef enum {
    76         HUB_PORT_STATE_NOT_CONFIGURED,
    77         HUB_PORT_STATE_POWERED_OFF,
    78         HUB_PORT_STATE_DISCONNECTED,
    79         HUB_PORT_STATE_DISABLED,
    80         HUB_PORT_STATE_RESETTING,
    81         HUB_PORT_STATE_ENABLED,
    82         HUB_PORT_STATE_SUSPENDED,
    83         HUB_PORT_STATE_RESUMING,
    84         /* HUB_PORT_STATE_, */
    85 } hub_port_state_t;
    86 
    87 /** Convert hub port state to a char. */
    88 static inline char hub_port_state_as_char(hub_port_state_t state) {
    89         switch (state) {
    90                 case HUB_PORT_STATE_NOT_CONFIGURED:
    91                         return '-';
    92                 case HUB_PORT_STATE_POWERED_OFF:
    93                         return 'O';
    94                 case HUB_PORT_STATE_DISCONNECTED:
    95                         return 'X';
    96                 case HUB_PORT_STATE_DISABLED:
    97                         return 'D';
    98                 case HUB_PORT_STATE_RESETTING:
    99                         return 'R';
    100                 case HUB_PORT_STATE_ENABLED:
    101                         return 'E';
    102                 case HUB_PORT_STATE_SUSPENDED:
    103                         return 'S';
    104                 case HUB_PORT_STATE_RESUMING:
    105                         return 'F';
    106                 default:
    107                         return '?';
    108         }
    109 }
    110 
    111 /** Hub status change mask bits. */
    112 typedef enum {
    113         HUB_STATUS_C_PORT_CONNECTION = (1 << 0),
    114         HUB_STATUS_C_PORT_ENABLE = (1 << 1),
    115         HUB_STATUS_C_PORT_SUSPEND = (1 << 2),
    116         HUB_STATUS_C_PORT_OVER_CURRENT = (1 << 3),
    117         HUB_STATUS_C_PORT_RESET = (1 << 4),
    118         /* HUB_STATUS_C_ = (1 << ), */
    119 } hub_status_change_t;
    120 
    121 /** Hub port information. */
    122 typedef struct {
    123         virtdev_connection_t *device;
    124         int index;
    125         hub_port_state_t state;
    126         uint16_t status_change;
    127         fibril_mutex_t guard;
    128 } hub_port_t;
    129 
    130 /** Hub device type. */
    131 typedef struct {
    132         hub_port_t ports[HUB_PORT_COUNT];
    133 } hub_device_t;
    134 
    135 extern hub_device_t hub_dev;
    136 
     73extern usbvirt_device_ops_t hub_ops;
    13774extern hub_descriptor_t hub_descriptor;
    13875
    139 extern usbvirt_device_ops_t hub_ops;
    140 
    141 void clear_port_status_change(hub_port_t *, uint16_t);
    142 void set_port_status_change(hub_port_t *, uint16_t);
    143 void set_port_status_change_nl(hub_port_t *, uint16_t);
    144 
     76int virthub_init(usbvirt_device_t *);
     77int virthub_connect_device(usbvirt_device_t *, virtdev_connection_t *);
     78int virthub_disconnect_device(usbvirt_device_t *, virtdev_connection_t *);
     79bool virthub_is_device_enabled(usbvirt_device_t *, virtdev_connection_t *);
     80void virthub_get_status(usbvirt_device_t *, char *, size_t);
    14581
    14682#endif
  • uspace/lib/c/generic/devman.c

    rea5dbaf rf37f811  
    230230       
    231231        if (flags & IPC_FLAG_BLOCKING) {
    232                 phone = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_DEVMAN,
     232                phone = async_connect_me_to_blocking(PHONE_NS, SERVICE_DEVMAN,
    233233                    DEVMAN_CONNECT_TO_DEVICE, handle);
    234234        } else {
    235                 phone = ipc_connect_me_to(PHONE_NS, SERVICE_DEVMAN,
     235                phone = async_connect_me_to(PHONE_NS, SERVICE_DEVMAN,
    236236                    DEVMAN_CONNECT_TO_DEVICE, handle);
    237237        }
  • uspace/lib/usb/src/usbdrv.c

    rea5dbaf rf37f811  
    7272        devman_handle_t handle;
    7373
    74         rc = devman_device_get_handle("/virt/usbhc", &handle, 0);
     74        rc = devman_device_get_handle("/virt/usbhc", &handle, flags);
    7575        if (rc != EOK) {
    7676                return rc;
    7777        }
    7878       
    79         int phone = devman_device_connect(handle, 0);
     79        int phone = devman_device_connect(handle, flags);
    8080
    8181        return phone;
  • uspace/lib/usbvirt/Makefile

    rea5dbaf rf37f811  
    3131
    3232LIBS = $(LIBUSB_PREFIX)/libusb.a
    33 EXTRA_CFLAGS = -I$(LIBUSB_PREFIX)/include
     33EXTRA_CFLAGS = -I$(LIBUSB_PREFIX)/include -Iinclude
    3434
    3535SOURCES = \
    36         callback.c \
    37         ctrlpipe.c \
    38         debug.c \
    39         main.c \
    40         stdreq.c \
    41         transaction.c
     36        src/callback.c \
     37        src/ctrlpipe.c \
     38        src/debug.c \
     39        src/main.c \
     40        src/stdreq.c \
     41        src/transaction.c
    4242
    4343include $(USPACE_PREFIX)/Makefile.common
  • uspace/lib/usbvirt/include/usbvirt/device.h

    rea5dbaf rf37f811  
    4040#include <usb/devreq.h>
    4141
     42typedef enum {
     43        USBVIRT_REQUEST_TYPE_STANDARD = 0,
     44        USBVIRT_REQUEST_TYPE_CLASS = 1
     45} usbvirt_request_type_t;
     46
     47typedef enum {
     48        USBVIRT_REQUEST_RECIPIENT_DEVICE = 0,
     49        USBVIRT_REQUEST_RECIPIENT_INTERFACE = 1,
     50        USBVIRT_REQUEST_RECIPIENT_ENDPOINT = 2,
     51        USBVIRT_REQUEST_RECIPIENT_OTHER = 3
     52} usbvirt_request_recipient_t;
     53
     54/** Possible states of virtual USB device.
     55 * Notice that these are not 1:1 mappings to those in USB specification.
     56 */
     57typedef enum {
     58        USBVIRT_STATE_DEFAULT,
     59        USBVIRT_STATE_ADDRESS,
     60        USBVIRT_STATE_CONFIGURED
     61} usbvirt_device_state_t;
     62
    4263typedef struct usbvirt_device usbvirt_device_t;
    4364struct usbvirt_control_transfer;
     
    4768        uint8_t *data);
    4869
    49 /** Callbacks for standard device requests.
    50  * When these functions are NULL or return EFORWARD, this
    51  * framework will try to satisfy the request by itself.
    52  */
    53 typedef struct {
    54         usbvirt_on_device_request_t on_get_status;
    55         usbvirt_on_device_request_t on_clear_feature;
    56         usbvirt_on_device_request_t on_set_feature;
    57         usbvirt_on_device_request_t on_set_address;
    58         usbvirt_on_device_request_t on_get_descriptor;
    59         usbvirt_on_device_request_t on_set_descriptor;
    60         usbvirt_on_device_request_t on_get_configuration;
    61         usbvirt_on_device_request_t on_set_configuration;
    62         usbvirt_on_device_request_t on_get_interface;
    63         usbvirt_on_device_request_t on_set_interface;
    64         usbvirt_on_device_request_t on_synch_frame;
    65 } usbvirt_standard_device_request_ops_t;
     70typedef int (*usbvirt_control_request_callback_t)(usbvirt_device_t *dev,
     71        usb_device_request_setup_packet_t *request,
     72        uint8_t *data);
     73
     74typedef struct {
     75        uint8_t request_type;
     76        uint8_t request;
     77        const char *name;
     78        usbvirt_control_request_callback_t callback;
     79} usbvirt_control_transfer_handler_t;
     80
     81#define USBVIRT_MAKE_CONTROL_REQUEST_TYPE(direction, type, recipient) \
     82        ((((direction) == USB_DIRECTION_IN) ? 1 : 0) << 7) \
     83        | (((type) & 3) << 5) \
     84        | (((recipient) & 31))
     85
     86#define USBVIRT_CONTROL_TRANSFER_HANDLER_LAST { 0, 0, NULL, NULL }
    6687
    6788/** Device operations. */
    6889typedef struct {
    69         /** Callbacks for standard deivce requests. */
    70         usbvirt_standard_device_request_ops_t *standard_request_ops;
    71         /** Callback for class-specific USB request. */
    72         usbvirt_on_device_request_t on_class_device_request;
    73        
     90        /** Callbacks for transfers over control pipe zero. */
     91        usbvirt_control_transfer_handler_t *control_transfer_handlers;
     92
    7493        int (*on_control_transfer)(usbvirt_device_t *dev,
    7594            usb_endpoint_t endpoint, struct usbvirt_control_transfer *transfer);
     
    86105        usb_direction_t (*decide_control_transfer_direction)(
    87106            usb_endpoint_t endpoint, void *buffer, size_t size);
     107
     108        /** Callback when device changes its state.
     109         *
     110         * It is correct that this function is called when both states
     111         * are equal (e.g. this function is called during SET_CONFIGURATION
     112         * request done on already configured device).
     113         *
     114         * @warning The value of <code>dev->state</code> before calling
     115         * this function is not specified (i.e. can be @p old_state or
     116         * @p new_state).
     117         */
     118        void (*on_state_change)(usbvirt_device_t *dev,
     119            usbvirt_device_state_t old_state, usbvirt_device_state_t new_state);
    88120} usbvirt_device_ops_t;
    89121
     
    120152        uint8_t current_configuration;
    121153} usbvirt_descriptors_t;
    122 
    123 /** Possible states of virtual USB device.
    124  * Notice that these are not 1:1 mappings to those in USB specification.
    125  */
    126 typedef enum {
    127         USBVIRT_STATE_DEFAULT,
    128         USBVIRT_STATE_ADDRESS,
    129         USBVIRT_STATE_CONFIGURED
    130 } usbvirt_device_state_t;
    131154
    132155/** Information about on-going control transfer.
     
    157180        usbvirt_device_ops_t *ops;
    158181       
     182        /** Custom device data. */
     183        void *device_data;
     184
    159185        /** Reply onto control transfer.
    160186         */
  • uspace/lib/usbvirt/src/callback.c

    rea5dbaf rf37f811  
    4040#include <mem.h>
    4141
    42 #include "hub.h"
    43 #include "device.h"
    4442#include "private.h"
    4543
  • uspace/lib/usbvirt/src/debug.c

    rea5dbaf rf37f811  
    3636#include <bool.h>
    3737
    38 #include "device.h"
    3938#include "private.h"
    4039
  • uspace/lib/usbvirt/src/main.c

    rea5dbaf rf37f811  
    3939#include <assert.h>
    4040
    41 #include "hub.h"
    42 #include "device.h"
    4341#include "private.h"
    4442
  • uspace/lib/usbvirt/src/private.h

    rea5dbaf rf37f811  
    3636#define LIBUSBVIRT_PRIVATE_H_
    3737
    38 #include "device.h"
    39 #include "hub.h"
     38#include <usbvirt/device.h>
     39#include <usbvirt/hub.h>
     40#include <assert.h>
    4041
    4142
     
    8687}
    8788
     89extern usbvirt_control_transfer_handler_t control_pipe_zero_local_handlers[];
     90
    8891#endif
    8992/**
  • uspace/lib/usbvirt/src/stdreq.c

    rea5dbaf rf37f811  
    4040#include "private.h"
    4141
    42 
    43 
    4442/*
    4543 * All sub handlers must return EFORWARD to inform the caller that
     
    5149/** GET_DESCRIPTOR handler. */
    5250static int handle_get_descriptor(usbvirt_device_t *device,
    53     uint8_t type, uint8_t index, uint16_t language,
    54     uint16_t length)
     51    usb_device_request_setup_packet_t *setup_packet, uint8_t *extra_data)
    5552{
     53        uint8_t type = setup_packet->value_high;
     54        uint8_t index = setup_packet->value_low;
     55
    5656        /*
    5757         * Standard device descriptor.
     
    110110/** SET_ADDRESS handler. */
    111111static int handle_set_address(usbvirt_device_t *device,
    112     uint16_t new_address,
    113     uint16_t zero1, uint16_t zero2)
     112    usb_device_request_setup_packet_t *setup_packet, uint8_t *extra_data)
    114113{
     114        uint16_t new_address = setup_packet->value;
     115        uint16_t zero1 = setup_packet->index;
     116        uint16_t zero2 = setup_packet->length;
     117
    115118        if ((zero1 != 0) || (zero2 != 0)) {
    116119                return EINVAL;
     
    128131/** SET_CONFIGURATION handler. */
    129132static int handle_set_configuration(usbvirt_device_t *device,
    130     uint16_t configuration_value,
    131     uint16_t zero1, uint16_t zero2)
     133    usb_device_request_setup_packet_t *setup_packet, uint8_t *extra_data)
    132134{
     135        uint16_t configuration_value = setup_packet->value;
     136        uint16_t zero1 = setup_packet->index;
     137        uint16_t zero2 = setup_packet->length;
     138
    133139        if ((zero1 != 0) || (zero2 != 0)) {
    134140                return EINVAL;
     
    151157       
    152158        if (configuration_value == 0) {
     159                if (DEVICE_HAS_OP(device, on_state_change)) {
     160                        device->ops->on_state_change(device, device->state,
     161                            USBVIRT_STATE_ADDRESS);
     162                }
    153163                device->state = USBVIRT_STATE_ADDRESS;
    154164        } else {
     
    157167                * user selected existing configuration.
    158168                */
     169                if (DEVICE_HAS_OP(device, on_state_change)) {
     170                        device->ops->on_state_change(device, device->state,
     171                            USBVIRT_STATE_CONFIGURED);
     172                }
    159173                device->state = USBVIRT_STATE_CONFIGURED;
    160174                if (device->descriptors) {
     
    167181}
    168182
    169 #define HANDLE_REQUEST(request, data, type, dev, user_callback, default_handler) \
    170         do { \
    171                 if ((request)->request == (type)) { \
    172                         int _rc = EFORWARD; \
    173                         if (((dev)->ops) && ((dev)->ops->standard_request_ops) \
    174                             && ((dev)->ops->standard_request_ops->user_callback)) { \
    175                                 _rc = (dev)->ops->standard_request_ops->\
    176                                     user_callback(dev, request, data); \
    177                         } \
    178                         if (_rc == EFORWARD) { \
    179                                 default_handler; \
    180                         } \
    181                         return _rc; \
    182                 } \
    183         } while (false)
    184 
    185 /** Handle standard device request. */
    186 int handle_std_request(usbvirt_device_t *device,
    187     usb_device_request_setup_packet_t *request, uint8_t *data)
    188 {
    189         device->lib_debug(device, 3, USBVIRT_DEBUGTAG_CONTROL_PIPE_ZERO,
    190             "handling standard request %d", request->request);
    191        
    192         HANDLE_REQUEST(request, data, USB_DEVREQ_GET_DESCRIPTOR,
    193             device, on_get_descriptor,
    194             handle_get_descriptor(device, request->value_high, request->value_low,
    195                 request->index, request->length));
    196        
    197         HANDLE_REQUEST(request, data, USB_DEVREQ_SET_ADDRESS,
    198             device, on_set_address,
    199             handle_set_address(device, request->value,
    200                 request->index, request->length));
    201        
    202         HANDLE_REQUEST(request, data, USB_DEVREQ_SET_CONFIGURATION,
    203             device, on_set_configuration,
    204             handle_set_configuration(device, request->value,
    205                 request->index, request->length));
    206        
    207         return ENOTSUP;
    208 }
     183
     184#define MAKE_BM_REQUEST(direction, recipient) \
     185        USBVIRT_MAKE_CONTROL_REQUEST_TYPE(direction, \
     186            USBVIRT_REQUEST_TYPE_STANDARD, recipient)
     187#define MAKE_BM_REQUEST_DEV(direction) \
     188        MAKE_BM_REQUEST(direction, USBVIRT_REQUEST_RECIPIENT_DEVICE)
     189
     190usbvirt_control_transfer_handler_t control_pipe_zero_local_handlers[] = {
     191        {
     192                .request_type = MAKE_BM_REQUEST_DEV(USB_DIRECTION_IN),
     193                .request = USB_DEVREQ_GET_DESCRIPTOR,
     194                .name = "GetDescriptor()",
     195                .callback = handle_get_descriptor
     196        },
     197        {
     198                .request_type = MAKE_BM_REQUEST_DEV(USB_DIRECTION_OUT),
     199                .request = USB_DEVREQ_SET_ADDRESS,
     200                .name = "SetAddress()",
     201                .callback = handle_set_address
     202        },
     203        {
     204                .request_type = MAKE_BM_REQUEST_DEV(USB_DIRECTION_OUT),
     205                .request = USB_DEVREQ_SET_CONFIGURATION,
     206                .name = "SetConfiguration()",
     207                .callback = handle_set_configuration
     208        },
     209        USBVIRT_CONTROL_TRANSFER_HANDLER_LAST
     210};
    209211
    210212/**
  • uspace/lib/usbvirt/src/transaction.c

    rea5dbaf rf37f811  
    3737#include <mem.h>
    3838
    39 #include "hub.h"
    4039#include "private.h"
    4140
Note: See TracChangeset for help on using the changeset viewer.