virthub.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2010 Vojtech Horky
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  *
00009  * - Redistributions of source code must retain the above copyright
00010  *   notice, this list of conditions and the following disclaimer.
00011  * - Redistributions in binary form must reproduce the above copyright
00012  *   notice, this list of conditions and the following disclaimer in the
00013  *   documentation and/or other materials provided with the distribution.
00014  * - The name of the author may not be used to endorse or promote products
00015  *   derived from this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
00018  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00019  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
00020  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
00021  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
00022  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00023  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00024  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00025  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00026  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00027  */
00028 
00035 #include <usb/classes/classes.h>
00036 #include <usbvirt/device.h>
00037 #include <assert.h>
00038 #include <errno.h>
00039 #include <str_error.h>
00040 #include <assert.h>
00041 #include <stdlib.h>
00042 #include <ddf/driver.h>
00043 
00044 #include "virthub.h"
00045 #include "hub.h"
00046 
00047 
00049 usb_standard_device_descriptor_t std_device_descriptor = {
00050         .length = sizeof(usb_standard_device_descriptor_t),
00051         .descriptor_type = USB_DESCTYPE_DEVICE,
00052         .usb_spec_version = 0x110,
00053         .device_class = USB_CLASS_HUB,
00054         .device_subclass = 0,
00055         .device_protocol = 0,
00056         .max_packet_size = 64,
00057         .configuration_count = 1
00058 };
00059 
00061 usb_standard_interface_descriptor_t std_interface_descriptor = {
00062         .length = sizeof(usb_standard_interface_descriptor_t),
00063         .descriptor_type = USB_DESCTYPE_INTERFACE,
00064         .interface_number = 0,
00065         .alternate_setting = 0,
00066         .endpoint_count = 1,
00067         .interface_class = USB_CLASS_HUB,
00068         .interface_subclass = 0,
00069         .interface_protocol = 0,
00070         .str_interface = 0
00071 };
00072 
00074 hub_descriptor_t hub_descriptor = {
00075         .length = sizeof(hub_descriptor_t),
00076         .type = USB_DESCTYPE_HUB,
00077         .port_count = HUB_PORT_COUNT,
00078         .characteristics = 0, 
00079         .power_on_warm_up = 50, /* Huh? */
00080         .max_current = 100, /* Huh again. */
00081         .removable_device = { 0 },
00082         .port_power = { 0xFF }
00083 };
00084 
00086 usb_standard_endpoint_descriptor_t endpoint_descriptor = {
00087         .length = sizeof(usb_standard_endpoint_descriptor_t),
00088         .descriptor_type = USB_DESCTYPE_ENDPOINT,
00089         .endpoint_address = HUB_STATUS_CHANGE_PIPE | 128,
00090         .attributes = USB_TRANSFER_INTERRUPT,
00091         .max_packet_size = 8,
00092         .poll_interval = 0xFF
00093 };
00094 
00096 usb_standard_configuration_descriptor_t std_configuration_descriptor = {
00097         .length = sizeof(usb_standard_configuration_descriptor_t),
00098         .descriptor_type = USB_DESCTYPE_CONFIGURATION,
00099         .total_length = 
00100                 sizeof(usb_standard_configuration_descriptor_t)
00101                 + sizeof(std_interface_descriptor)
00102                 + sizeof(hub_descriptor)
00103                 + sizeof(endpoint_descriptor)
00104                 ,
00105         .interface_count = 1,
00106         .configuration_number = HUB_CONFIGURATION_ID,
00107         .str_configuration = 0,
00108         .attributes = 128, /* denotes bus-powered device */
00109         .max_power = 50
00110 };
00111 
00113 static usbvirt_device_configuration_extras_t extra_descriptors[] = {
00114         {
00115                 .data = (uint8_t *) &std_interface_descriptor,
00116                 .length = sizeof(std_interface_descriptor)
00117         },
00118         {
00119                 .data = (uint8_t *) &hub_descriptor,
00120                 .length = sizeof(hub_descriptor)
00121         },
00122         {
00123                 .data = (uint8_t *) &endpoint_descriptor,
00124                 .length = sizeof(endpoint_descriptor)
00125         }
00126 };
00127 
00129 usbvirt_device_configuration_t configuration = {
00130         .descriptor = &std_configuration_descriptor,
00131         .extra = extra_descriptors,
00132         .extra_count = sizeof(extra_descriptors)/sizeof(extra_descriptors[0])
00133 };
00134 
00136 usbvirt_descriptors_t descriptors = {
00137         .device = &std_device_descriptor,
00138         .configuration = &configuration,
00139         .configuration_count = 1,
00140 };
00141 
00147 int virthub_init(usbvirt_device_t *dev)
00148 {
00149         if (dev == NULL) {
00150                 return EBADMEM;
00151         }
00152         dev->ops = &hub_ops;
00153         dev->descriptors = &descriptors;
00154 
00155         hub_t *hub = malloc(sizeof(hub_t));
00156         if (hub == NULL) {
00157                 return ENOMEM;
00158         }
00159 
00160         hub_init(hub);
00161         dev->device_data = hub;
00162 
00163         return EOK;
00164 }
00165 
00172 int virthub_connect_device(usbvirt_device_t *dev, vhc_virtdev_t *conn)
00173 {
00174         assert(dev != NULL);
00175         assert(conn != NULL);
00176 
00177         hub_t *hub = (hub_t *) dev->device_data;
00178 
00179         hub_acquire(hub);
00180         size_t port = hub_connect_device(hub, conn);
00181         hub_release(hub);
00182 
00183         return port;
00184 }
00185 
00192 int virthub_disconnect_device(usbvirt_device_t *dev, vhc_virtdev_t *conn)
00193 {
00194         assert(dev != NULL);
00195         assert(conn != NULL);
00196 
00197         hub_t *hub = (hub_t *) dev->device_data;
00198 
00199         hub_acquire(hub);
00200         hub_disconnect_device(hub, conn);
00201         hub_release(hub);
00202 
00203         return EOK;
00204 }
00205 
00212 bool virthub_is_device_enabled(usbvirt_device_t *dev, vhc_virtdev_t *conn)
00213 {
00214         assert(dev != NULL);
00215         assert(conn != NULL);
00216 
00217         hub_t *hub = (hub_t *) dev->device_data;
00218 
00219         hub_acquire(hub);
00220 
00221         hub_port_state_t state = HUB_PORT_STATE_UNKNOWN;
00222         size_t port = hub_find_device(hub, conn);
00223         if (port != (size_t) -1) {
00224                 state = hub_get_port_state(hub, port);
00225         }
00226         hub_release(hub);
00227 
00228         return state == HUB_PORT_STATE_ENABLED;
00229 }
00230 
00237 void virthub_get_status(usbvirt_device_t *dev, char *status, size_t len)
00238 {
00239         assert(dev != NULL);
00240         if (len == 0) {
00241                 return;
00242         }
00243 
00244         hub_t *hub = (hub_t *) dev->device_data;
00245 
00246         char port_status[HUB_PORT_COUNT + 1];
00247 
00248         size_t i;
00249         for (i = 0; i < HUB_PORT_COUNT; i++) {
00250                 port_status[i] = hub_port_state_to_char(
00251                     hub_get_port_state(hub, i));
00252         }
00253         port_status[HUB_PORT_COUNT] = 0;
00254 
00255         snprintf(status, len, "vhub:%s", port_status);
00256 }
00257 

Generated on Thu Jun 2 07:45:45 2011 for HelenOS/USB by  doxygen 1.4.7