Changes in uspace/drv/vhc/hub.c [ee0d8a8:774afaae] in mainline


Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/vhc/hub.c

    ree0d8a8 r774afaae  
    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 = 4,
    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         for (i = 0; i < HUB_PORT_COUNT; i++) {
    180                 hub_port_t *port = &hub_dev.ports[i];
    181                
    182                 port->device = NULL;
    183                 port->state = HUB_PORT_STATE_NOT_CONFIGURED;
    184                 port->status_change = 0;
    185         }
    186        
    187         usbvirt_connect_local(&virthub_dev);
    188        
    189         dprintf(1, "virtual hub (%d ports) created", HUB_PORT_COUNT);
     79        device_t *hc_dev = (device_t *) arg;
    19080
    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));
     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;
    19585        }
    19686
    197         dprintf(2, "virtual hub address changed to %d", hub_address);
     87        usb_drv_reserve_default_address(hc);
    19888
    199         char *id;
    200         int rc = asprintf(&id, "usb&hub");
    201         if (rc <= 0) {
    202                 return;
    203         }
     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
    20494        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         }
     95        usb_drv_register_child_in_devman(hc, hc_dev, hub_address, &hub_handle);
     96        usb_drv_bind_address(hc, hub_address, hub_handle);
    20997
    210         vhc_iface.bind_address(NULL, hub_address, hub_handle); 
    211 
    212         dprintf(2, "virtual hub has devman handle %d", (int) hub_handle);
     98        return EOK;
    21399}
    214 
    215 /** Connect device to the hub.
    216  *
    217  * @param device Device to be connected.
    218  * @return Port where the device was connected to.
    219  */
    220 size_t hub_add_device(virtdev_connection_t *device)
    221 {
    222         size_t i;
    223         for (i = 0; i < HUB_PORT_COUNT; i++) {
    224                 hub_port_t *port = &hub_dev.ports[i];
    225                
    226                 if (port->device != NULL) {
    227                         continue;
    228                 }
    229                
    230                 port->device = device;
    231                
    232                 /*
    233                  * TODO:
    234                  * If the hub was configured, we can normally
    235                  * announce the plug-in.
    236                  * Otherwise, we will wait until hub is configured
    237                  * and announce changes in single burst.
    238                  */
    239                 //if (port->state == HUB_PORT_STATE_DISCONNECTED) {
    240                         port->state = HUB_PORT_STATE_DISABLED;
    241                         set_port_status_change(port, HUB_STATUS_C_PORT_CONNECTION);
    242                 //}
    243                
    244                 return i;
    245         }
    246100       
    247         return (size_t)-1;
    248 }
    249 
    250 /** Disconnect device from the hub. */
    251 void hub_remove_device(virtdev_connection_t *device)
    252 {
    253         size_t i;
    254         for (i = 0; i < HUB_PORT_COUNT; i++) {
    255                 hub_port_t *port = &hub_dev.ports[i];
    256                
    257                 if (port->device != device) {
    258                         continue;
    259                 }
    260                
    261                 port->device = NULL;
    262                 port->state = HUB_PORT_STATE_DISCONNECTED;
    263                
    264                 set_port_status_change(port, HUB_STATUS_C_PORT_CONNECTION);
    265         }
    266 }
    267 
    268 /** Tell whether device port is open.
    269  *
    270  * @return Whether communication to and from the device can go through the hub.
    271  */
    272 bool hub_can_device_signal(virtdev_connection_t * device)
    273 {
    274         size_t i;
    275         for (i = 0; i < HUB_PORT_COUNT; i++) {
    276                 if (hub_dev.ports[i].device == device) {
    277                         return hub_dev.ports[i].state == HUB_PORT_STATE_ENABLED;
    278                 }
    279         }
    280        
    281         return false;
    282 }
    283 
    284 /** Format hub port status.
    285  *
    286  * @param result Buffer where to store status string.
    287  * @param len Number of characters that is possible to store in @p result
    288  *      (excluding trailing zero).
    289  */
    290 void hub_get_port_statuses(char *result, size_t len)
    291 {
    292         if (len > HUB_PORT_COUNT) {
    293                 len = HUB_PORT_COUNT;
    294         }
    295         size_t i;
    296         for (i = 0; i < len; i++) {
    297                 result[i] = hub_port_state_as_char(hub_dev.ports[i].state);
    298         }
    299         result[len] = 0;
    300 }
    301101
    302102/**
Note: See TracChangeset for help on using the changeset viewer.