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


Ignore:
File:
1 edited

Legend:

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

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