Changes in uspace/drv/vhc/hub.c [ee0d8a8:774afaae] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/vhc/hub.c
ree0d8a8 r774afaae 40 40 #include <stdlib.h> 41 41 #include <driver.h> 42 #include <usb/usbdrv.h> 42 43 44 #include "hub.h" 45 #include "hub/virthub.h" 43 46 #include "vhcd.h" 44 #include "hub.h"45 #include "hubintern.h"46 #include "conn.h"47 47 48 usbvirt_device_t virtual_hub_device; 48 49 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 }; 50 static int hub_register_in_devman_fibril(void *arg); 60 51 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 }; 52 void virtual_hub_device_init(device_t *hc_dev) 53 { 54 virthub_init(&virtual_hub_device); 73 55 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 } 84 68 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 = 4, 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); 173 70 } 174 71 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 */ 77 int hub_register_in_devman_fibril(void *arg) 177 78 { 178 size_t i; 179 for (i = 0; i < HUB_PORT_COUNT; i++) { 180 hub_port_t *port = &hub_dev.ports[i]; 181 182 port->device = NULL; 183 port->state = HUB_PORT_STATE_NOT_CONFIGURED; 184 port->status_change = 0; 185 } 186 187 usbvirt_connect_local(&virthub_dev); 188 189 dprintf(1, "virtual hub (%d ports) created", HUB_PORT_COUNT); 79 device_t *hc_dev = (device_t *) arg; 190 80 191 usb_address_t hub_address = hub_set_address(&virthub_dev);192 if (h ub_address< 0) {193 dprintf(1, "problem changing hub address (%s)",194 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; 195 85 } 196 86 197 dprintf(2, "virtual hub address changed to %d", hub_address);87 usb_drv_reserve_default_address(hc); 198 88 199 char *id;200 int rc = asprintf(&id, "usb&hub");201 if (rc <= 0) { 202 return;203 } 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 204 94 devman_handle_t hub_handle; 205 rc = child_device_register_wrapper(hc_dev, "hub", id, 10, &hub_handle); 206 if (rc != EOK) { 207 free(id); 208 } 95 usb_drv_register_child_in_devman(hc, hc_dev, hub_address, &hub_handle); 96 usb_drv_bind_address(hc, hub_address, hub_handle); 209 97 210 vhc_iface.bind_address(NULL, hub_address, hub_handle); 211 212 dprintf(2, "virtual hub has devman handle %d", (int) hub_handle); 98 return EOK; 213 99 } 214 215 /** Connect device to the hub.216 *217 * @param device Device to be connected.218 * @return Port where the device was connected to.219 */220 size_t hub_add_device(virtdev_connection_t *device)221 {222 size_t i;223 for (i = 0; i < HUB_PORT_COUNT; i++) {224 hub_port_t *port = &hub_dev.ports[i];225 226 if (port->device != NULL) {227 continue;228 }229 230 port->device = device;231 232 /*233 * TODO:234 * If the hub was configured, we can normally235 * announce the plug-in.236 * Otherwise, we will wait until hub is configured237 * and announce changes in single burst.238 */239 //if (port->state == HUB_PORT_STATE_DISCONNECTED) {240 port->state = HUB_PORT_STATE_DISABLED;241 set_port_status_change(port, HUB_STATUS_C_PORT_CONNECTION);242 //}243 244 return i;245 }246 100 247 return (size_t)-1;248 }249 250 /** Disconnect device from the hub. */251 void hub_remove_device(virtdev_connection_t *device)252 {253 size_t i;254 for (i = 0; i < HUB_PORT_COUNT; i++) {255 hub_port_t *port = &hub_dev.ports[i];256 257 if (port->device != device) {258 continue;259 }260 261 port->device = NULL;262 port->state = HUB_PORT_STATE_DISCONNECTED;263 264 set_port_status_change(port, HUB_STATUS_C_PORT_CONNECTION);265 }266 }267 268 /** Tell whether device port is open.269 *270 * @return Whether communication to and from the device can go through the hub.271 */272 bool hub_can_device_signal(virtdev_connection_t * device)273 {274 size_t i;275 for (i = 0; i < HUB_PORT_COUNT; i++) {276 if (hub_dev.ports[i].device == device) {277 return hub_dev.ports[i].state == HUB_PORT_STATE_ENABLED;278 }279 }280 281 return false;282 }283 284 /** Format hub port status.285 *286 * @param result Buffer where to store status string.287 * @param len Number of characters that is possible to store in @p result288 * (excluding trailing zero).289 */290 void hub_get_port_statuses(char *result, size_t len)291 {292 if (len > HUB_PORT_COUNT) {293 len = HUB_PORT_COUNT;294 }295 size_t i;296 for (i = 0; i < len; i++) {297 result[i] = hub_port_state_as_char(hub_dev.ports[i].state);298 }299 result[len] = 0;300 }301 101 302 102 /**
Note:
See TracChangeset
for help on using the changeset viewer.