Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 11658b64 in mainline for uspace/drv/vhc/hub.c


Ignore:
Timestamp:
2010-12-16T11:54:53Z (11 years ago)
Author:
Vojtech Horky <vojtechhorky@…>
Branches:
lfn, master
Children:
557c7d0, 5863a95, 82122f3, a8b7dfd, f2962621
Parents:
a9b6bec (diff), 70e5ad5 (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:

Merged vojtechhorky/ - libusbvirt clean-up

File:
1 edited

Legend:

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

    ra9b6bec r11658b64  
    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/**
Note: See TracChangeset for help on using the changeset viewer.