Changeset 774afaae in mainline for uspace/drv/vhc/hub.c


Ignore:
Timestamp:
2010-12-15T21:56:14Z (13 years ago)
Author:
Vojtech Horky <vojtechhorky@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
e63a4e1
Parents:
1840e0d
Message:

Refactoring of virtual hub

The hub is now divided into two layers (one as a hub and the other
one as a virtual USB device) and separated into more files for better
readability.

File:
1 edited

Legend:

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

    r1840e0d r774afaae  
    4242#include <usb/usbdrv.h>
    4343
     44#include "hub.h"
     45#include "hub/virthub.h"
    4446#include "vhcd.h"
    45 #include "hub.h"
    46 #include "hubintern.h"
    47 #include "conn.h"
    4847
     48usbvirt_device_t virtual_hub_device;
    4949
    50 /** Standard device descriptor. */
    51 usb_standard_device_descriptor_t std_device_descriptor = {
    52         .length = sizeof(usb_standard_device_descriptor_t),
    53         .descriptor_type = USB_DESCTYPE_DEVICE,
    54         .usb_spec_version = 0x110,
    55         .device_class = USB_CLASS_HUB,
    56         .device_subclass = 0,
    57         .device_protocol = 0,
    58         .max_packet_size = 64,
    59         .configuration_count = 1
    60 };
     50static int hub_register_in_devman_fibril(void *arg);
    6151
    62 /** Standard interface descriptor. */
    63 usb_standard_interface_descriptor_t std_interface_descriptor = {
    64         .length = sizeof(usb_standard_interface_descriptor_t),
    65         .descriptor_type = USB_DESCTYPE_INTERFACE,
    66         .interface_number = 0,
    67         .alternate_setting = 0,
    68         .endpoint_count = 1,
    69         .interface_class = USB_CLASS_HUB,
    70         .interface_subclass = 0,
    71         .interface_protocol = 0,
    72         .str_interface = 0
    73 };
     52void virtual_hub_device_init(device_t *hc_dev)
     53{
     54        virthub_init(&virtual_hub_device);
    7455
    75 hub_descriptor_t hub_descriptor = {
    76         .length = sizeof(hub_descriptor_t),
    77         .type = USB_DESCTYPE_HUB,
    78         .port_count = HUB_PORT_COUNT,
    79         .characteristics = 0,
    80         .power_on_warm_up = 50, /* Huh? */
    81         .max_current = 100, /* Huh again. */
    82         .removable_device = { 0 },
    83         .port_power = { 0xFF }
    84 };
     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        }
    8568
    86 /** Endpoint descriptor. */
    87 usb_standard_endpoint_descriptor_t endpoint_descriptor = {
    88         .length = sizeof(usb_standard_endpoint_descriptor_t),
    89         .descriptor_type = USB_DESCTYPE_ENDPOINT,
    90         .endpoint_address = HUB_STATUS_CHANGE_PIPE | 128,
    91         .attributes = USB_TRANSFER_INTERRUPT,
    92         .max_packet_size = 8,
    93         .poll_interval = 0xFF
    94 };
    95 
    96 /** Standard configuration descriptor. */
    97 usb_standard_configuration_descriptor_t std_configuration_descriptor = {
    98         .length = sizeof(usb_standard_configuration_descriptor_t),
    99         .descriptor_type = USB_DESCTYPE_CONFIGURATION,
    100         .total_length =
    101                 sizeof(usb_standard_configuration_descriptor_t)
    102                 + sizeof(std_interface_descriptor)
    103                 + sizeof(hub_descriptor)
    104                 + sizeof(endpoint_descriptor)
    105                 ,
    106         .interface_count = 1,
    107         .configuration_number = HUB_CONFIGURATION_ID,
    108         .str_configuration = 0,
    109         .attributes = 128, /* denotes bus-powered device */
    110         .max_power = 50
    111 };
    112 
    113 /** All hub configuration descriptors. */
    114 static usbvirt_device_configuration_extras_t extra_descriptors[] = {
    115         {
    116                 .data = (uint8_t *) &std_interface_descriptor,
    117                 .length = sizeof(std_interface_descriptor)
    118         },
    119         {
    120                 .data = (uint8_t *) &hub_descriptor,
    121                 .length = sizeof(hub_descriptor)
    122         },
    123         {
    124                 .data = (uint8_t *) &endpoint_descriptor,
    125                 .length = sizeof(endpoint_descriptor)
    126         }
    127 };
    128 
    129 /** Hub configuration. */
    130 usbvirt_device_configuration_t configuration = {
    131         .descriptor = &std_configuration_descriptor,
    132         .extra = extra_descriptors,
    133         .extra_count = sizeof(extra_descriptors)/sizeof(extra_descriptors[0])
    134 };
    135 
    136 /** Hub standard descriptors. */
    137 usbvirt_descriptors_t descriptors = {
    138         .device = &std_device_descriptor,
    139         .configuration = &configuration,
    140         .configuration_count = 1,
    141 };
    142 
    143 /** Hub as a virtual device. */
    144 usbvirt_device_t virthub_dev = {
    145         .ops = &hub_ops,
    146         .descriptors = &descriptors,
    147         .lib_debug_level = 0,
    148         .lib_debug_enabled_tags = USBVIRT_DEBUGTAG_ALL
    149 };
    150 
    151 /** Hub device. */
    152 hub_device_t hub_dev;
     69        fibril_add_ready(root_hub_registration);
     70}
    15371
    15472/** Register root hub in devman.
     
    15775 * @return Error code.
    15876 */
    159 static int hub_register_in_devman_fibril(void *arg)
     77int hub_register_in_devman_fibril(void *arg)
    16078{
    16179        device_t *hc_dev = (device_t *) arg;
     
    18098        return EOK;
    18199}
    182 
    183 /** Initialize virtual hub. */
    184 void hub_init(device_t *hc_dev)
    185 {
    186         size_t i;
    187100       
    188         for (i = 0; i < HUB_PORT_COUNT; i++) {
    189                 hub_port_t *port = &hub_dev.ports[i];
    190                
    191                 port->index = (int) i + 1;
    192                 port->device = NULL;
    193                 port->state = HUB_PORT_STATE_NOT_CONFIGURED;
    194                 port->status_change = 0;
    195                 fibril_mutex_initialize(&port->guard);
    196         }
    197        
    198         usbvirt_connect_local(&virthub_dev);
    199        
    200         /*
    201          * We need to register the root hub.
    202          * This must be done in separate fibril because the device
    203          * we are connecting to are ourselves and we cannot connect
    204          * before leaving the add_device() function.
    205          */
    206         fid_t root_hub_registration
    207             = fibril_create(hub_register_in_devman_fibril, hc_dev);
    208         if (root_hub_registration == 0) {
    209                 printf(NAME ": failed to register root hub\n");
    210                 return;
    211         }
    212 
    213         fibril_add_ready(root_hub_registration);
    214 }
    215 
    216 /** Connect device to the hub.
    217  *
    218  * @param device Device to be connected.
    219  * @return Port where the device was connected to.
    220  */
    221 size_t hub_add_device(virtdev_connection_t *device)
    222 {
    223         size_t i;
    224         for (i = 0; i < HUB_PORT_COUNT; i++) {
    225                 hub_port_t *port = &hub_dev.ports[i];
    226                 fibril_mutex_lock(&port->guard);
    227                
    228                 if (port->device != NULL) {
    229                         fibril_mutex_unlock(&port->guard);
    230                         continue;
    231                 }
    232                
    233                 port->device = device;
    234                
    235                 /*
    236                  * TODO:
    237                  * If the hub was configured, we can normally
    238                  * announce the plug-in.
    239                  * Otherwise, we will wait until hub is configured
    240                  * and announce changes in single burst.
    241                  */
    242                 //if (port->state == HUB_PORT_STATE_DISCONNECTED) {
    243                         port->state = HUB_PORT_STATE_DISABLED;
    244                         set_port_status_change_nl(port, HUB_STATUS_C_PORT_CONNECTION);
    245                 //}
    246                
    247                 fibril_mutex_unlock(&port->guard);
    248 
    249                 return i;
    250         }
    251        
    252         return (size_t)-1;
    253 }
    254 
    255 /** Disconnect device from the hub. */
    256 void hub_remove_device(virtdev_connection_t *device)
    257 {
    258         size_t i;
    259         for (i = 0; i < HUB_PORT_COUNT; i++) {
    260                 hub_port_t *port = &hub_dev.ports[i];
    261                
    262                 if (port->device != device) {
    263                         continue;
    264                 }
    265                
    266                 port->device = NULL;
    267                 port->state = HUB_PORT_STATE_DISCONNECTED;
    268                
    269                 set_port_status_change(port, HUB_STATUS_C_PORT_CONNECTION);
    270         }
    271 }
    272 
    273 /** Tell whether device port is open.
    274  *
    275  * @return Whether communication to and from the device can go through the hub.
    276  */
    277 bool hub_can_device_signal(virtdev_connection_t * device)
    278 {
    279         size_t i;
    280         for (i = 0; i < HUB_PORT_COUNT; i++) {
    281                 if (hub_dev.ports[i].device == device) {
    282                         return hub_dev.ports[i].state == HUB_PORT_STATE_ENABLED;
    283                 }
    284         }
    285        
    286         return false;
    287 }
    288 
    289 /** Format hub port status.
    290  *
    291  * @param result Buffer where to store status string.
    292  * @param len Number of characters that is possible to store in @p result
    293  *      (excluding trailing zero).
    294  */
    295 void hub_get_port_statuses(char *result, size_t len)
    296 {
    297         if (len > HUB_PORT_COUNT) {
    298                 len = HUB_PORT_COUNT;
    299         }
    300         size_t i;
    301         for (i = 0; i < len; i++) {
    302                 result[i] = hub_port_state_as_char(hub_dev.ports[i].state);
    303         }
    304         result[len] = 0;
    305 }
    306101
    307102/**
Note: See TracChangeset for help on using the changeset viewer.