Changeset 774afaae in mainline for uspace/drv/vhc/hub.c
- Timestamp:
- 2010-12-15T21:56:14Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- e63a4e1
- Parents:
- 1840e0d
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/vhc/hub.c
r1840e0d r774afaae 42 42 #include <usb/usbdrv.h> 43 43 44 #include "hub.h" 45 #include "hub/virthub.h" 44 46 #include "vhcd.h" 45 #include "hub.h"46 #include "hubintern.h"47 #include "conn.h"48 47 48 usbvirt_device_t virtual_hub_device; 49 49 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 }; 50 static int hub_register_in_devman_fibril(void *arg); 61 51 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 }; 52 void virtual_hub_device_init(device_t *hc_dev) 53 { 54 virthub_init(&virtual_hub_device); 74 55 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 } 85 68 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 } 153 71 154 72 /** Register root hub in devman. … … 157 75 * @return Error code. 158 76 */ 159 staticint hub_register_in_devman_fibril(void *arg)77 int hub_register_in_devman_fibril(void *arg) 160 78 { 161 79 device_t *hc_dev = (device_t *) arg; … … 180 98 return EOK; 181 99 } 182 183 /** Initialize virtual hub. */184 void hub_init(device_t *hc_dev)185 {186 size_t i;187 100 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 device203 * we are connecting to are ourselves and we cannot connect204 * before leaving the add_device() function.205 */206 fid_t root_hub_registration207 = 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 normally238 * announce the plug-in.239 * Otherwise, we will wait until hub is configured240 * 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 result293 * (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 }306 101 307 102 /**
Note:
See TracChangeset
for help on using the changeset viewer.