Changeset 774afaae in mainline
- Timestamp:
- 2010-12-15T21:56:14Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- e63a4e1
- Parents:
- 1840e0d
- Location:
- uspace/drv/vhc
- Files:
-
- 4 added
- 1 deleted
- 6 edited
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/vhc/Makefile
r1840e0d r774afaae 39 39 40 40 SOURCES = \ 41 hub/hub.c \ 42 hub/virthub.c \ 43 hub/virthubops.c \ 41 44 conndev.c \ 42 45 connhost.c \ … … 45 48 hc.c \ 46 49 hcd.c \ 47 hub.c \ 48 hubops.c 50 hub.c 49 51 50 52 include $(USPACE_PREFIX)/Makefile.common -
uspace/drv/vhc/devices.c
r1840e0d r774afaae 47 47 #include "devices.h" 48 48 #include "hub.h" 49 #include "hub/virthub.h" 49 50 #include "vhcd.h" 50 51 … … 69 70 list_append(&dev->link, &devices); 70 71 71 hub_add_device(dev);72 virthub_connect_device(&virtual_hub_device, dev); 72 73 73 74 return dev; … … 78 79 void virtdev_destroy_device(virtdev_connection_t *dev) 79 80 { 80 hub_remove_device(dev);81 virthub_disconnect_device(&virtual_hub_device, dev); 81 82 list_remove(&dev->link); 82 83 free(dev); … … 94 95 = list_get_instance(pos, virtdev_connection_t, link); 95 96 96 if (! hub_can_device_signal(dev)) {97 if (!virthub_is_device_enabled(&virtual_hub_device, dev)) { 97 98 continue; 98 99 } … … 145 146 * (if the address matches). 146 147 */ 147 if (virt hub_dev.address == transaction->target.address) {148 if (virtual_hub_device.address == transaction->target.address) { 148 149 size_t tmp; 149 150 dprintf(1, "sending `%s' transaction to hub", … … 151 152 switch (transaction->type) { 152 153 case USBVIRT_TRANSACTION_SETUP: 153 virthub_dev.transaction_setup(&virthub_dev, 154 virtual_hub_device.transaction_setup( 155 &virtual_hub_device, 154 156 transaction->target.endpoint, 155 157 transaction->buffer, transaction->len); … … 157 159 158 160 case USBVIRT_TRANSACTION_IN: 159 virthub_dev.transaction_in(&virthub_dev, 161 virtual_hub_device.transaction_in( 162 &virtual_hub_device, 160 163 transaction->target.endpoint, 161 164 transaction->buffer, transaction->len, … … 167 170 168 171 case USBVIRT_TRANSACTION_OUT: 169 virthub_dev.transaction_out(&virthub_dev, 172 virtual_hub_device.transaction_out( 173 &virtual_hub_device, 170 174 transaction->target.endpoint, 171 175 transaction->buffer, transaction->len); -
uspace/drv/vhc/hc.c
r1840e0d r774afaae 78 78 list_get_instance(lnk, transaction_t, link) 79 79 80 #define HUB_STATUS_MAX_LEN (HUB_PORT_COUNT + 64) 81 80 82 static inline unsigned int pseudo_random(unsigned int *seed) 81 83 { … … 115 117 } 116 118 117 char ports[HUB_PORT_COUNT + 2]; 118 hub_get_port_statuses(ports, HUB_PORT_COUNT + 1); 119 dprintf(4, "virtual hub: addr=%d ports=%s", 120 virthub_dev.address, ports); 119 char ports[HUB_STATUS_MAX_LEN + 1]; 120 virthub_get_status(&virtual_hub_device, ports, HUB_STATUS_MAX_LEN); 121 121 122 122 link_t *first_transaction_link = transaction_list.next; … … 126 126 127 127 128 dprintf(0, "about to process " TRANSACTION_FORMAT " (vhub:%s)",128 dprintf(0, "about to process " TRANSACTION_FORMAT " [%s]", 129 129 TRANSACTION_PRINTF(*transaction), ports); 130 130 -
uspace/drv/vhc/hcd.c
r1840e0d r774afaae 79 79 * Initialize our hub and announce its presence. 80 80 */ 81 hub_init(dev);81 virtual_hub_device_init(dev); 82 82 83 83 printf("%s: virtual USB host controller ready.\n", NAME); … … 108 108 int main(int argc, char * argv[]) 109 109 { 110 printf("%s: virtual USB host controller driver.\n", NAME); 110 /* 111 * Temporary workaround. Wait a little bit to be the last driver 112 * in devman output. 113 */ 114 sleep(4); 115 116 printf(NAME ": virtual USB host controller driver.\n"); 111 117 112 118 usb_dprintf_enable(NAME, 0); … … 114 120 fid_t fid = fibril_create(hc_manager_fibril, NULL); 115 121 if (fid == 0) { 116 printf( "%s: failed to start HC manager fibril\n", NAME);122 printf(NAME ": failed to start HC manager fibril\n"); 117 123 return ENOMEM; 118 124 } 119 125 fibril_add_ready(fid); 120 126 121 /*122 * Temporary workaround. Wait a little bit to be the last driver123 * in devman output.124 */125 sleep(4);126 127 127 128 return driver_main(&vhc_driver); -
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 /** -
uspace/drv/vhc/hub.h
r1840e0d r774afaae 40 40 41 41 #include "devices.h" 42 #include "hub/hub.h" 43 #include "hub/virthub.h" 42 44 43 #define HUB_PORT_COUNT 2 45 extern usbvirt_device_t virtual_hub_device; 44 46 45 #define BITS2BYTES(bits) \ 46 (bits ? ((((bits)-1)>>3)+1) : 0) 47 48 extern usbvirt_device_t virthub_dev; 49 50 void hub_init(device_t *); 51 size_t hub_add_device(virtdev_connection_t *); 52 void hub_remove_device(virtdev_connection_t *); 53 bool hub_can_device_signal(virtdev_connection_t *); 54 void hub_get_port_statuses(char *result, size_t len); 47 void virtual_hub_device_init(device_t *); 55 48 56 49 #endif -
uspace/drv/vhc/hub/virthub.h
r1840e0d r774afaae 33 33 * @brief 34 34 */ 35 #ifndef VHC D_HUBINTERN_H_36 #define VHC D_HUBINTERN_H_35 #ifndef VHC_HUB_VIRTHUB_H_ 36 #define VHC_HUB_VIRTHUB_H_ 37 37 38 #include <usbvirt/device.h> 39 #include "../devices.h" 38 40 #include "hub.h" 39 #include <fibril_synch.h>40 41 41 42 /** Endpoint number for status change pipe. */ … … 43 44 /** Configuration value for hub configuration. */ 44 45 #define HUB_CONFIGURATION_ID 1 46 45 47 46 48 /** Hub descriptor. … … 69 71 } __attribute__ ((packed)) hub_descriptor_t; 70 72 71 /** Hub port internal state. 72 * Some states (e.g. port over current) are not covered as they are not 73 * simulated at all. 74 */ 75 typedef enum { 76 HUB_PORT_STATE_NOT_CONFIGURED, 77 HUB_PORT_STATE_POWERED_OFF, 78 HUB_PORT_STATE_DISCONNECTED, 79 HUB_PORT_STATE_DISABLED, 80 HUB_PORT_STATE_RESETTING, 81 HUB_PORT_STATE_ENABLED, 82 HUB_PORT_STATE_SUSPENDED, 83 HUB_PORT_STATE_RESUMING, 84 /* HUB_PORT_STATE_, */ 85 } hub_port_state_t; 86 87 /** Convert hub port state to a char. */ 88 static inline char hub_port_state_as_char(hub_port_state_t state) { 89 switch (state) { 90 case HUB_PORT_STATE_NOT_CONFIGURED: 91 return '-'; 92 case HUB_PORT_STATE_POWERED_OFF: 93 return 'O'; 94 case HUB_PORT_STATE_DISCONNECTED: 95 return 'X'; 96 case HUB_PORT_STATE_DISABLED: 97 return 'D'; 98 case HUB_PORT_STATE_RESETTING: 99 return 'R'; 100 case HUB_PORT_STATE_ENABLED: 101 return 'E'; 102 case HUB_PORT_STATE_SUSPENDED: 103 return 'S'; 104 case HUB_PORT_STATE_RESUMING: 105 return 'F'; 106 default: 107 return '?'; 108 } 109 } 110 111 /** Hub status change mask bits. */ 112 typedef enum { 113 HUB_STATUS_C_PORT_CONNECTION = (1 << 0), 114 HUB_STATUS_C_PORT_ENABLE = (1 << 1), 115 HUB_STATUS_C_PORT_SUSPEND = (1 << 2), 116 HUB_STATUS_C_PORT_OVER_CURRENT = (1 << 3), 117 HUB_STATUS_C_PORT_RESET = (1 << 4), 118 /* HUB_STATUS_C_ = (1 << ), */ 119 } hub_status_change_t; 120 121 /** Hub port information. */ 122 typedef struct { 123 virtdev_connection_t *device; 124 int index; 125 hub_port_state_t state; 126 uint16_t status_change; 127 fibril_mutex_t guard; 128 } hub_port_t; 129 130 /** Hub device type. */ 131 typedef struct { 132 hub_port_t ports[HUB_PORT_COUNT]; 133 } hub_device_t; 134 135 extern hub_device_t hub_dev; 136 73 extern usbvirt_device_ops_t hub_ops; 137 74 extern hub_descriptor_t hub_descriptor; 138 75 139 extern usbvirt_device_ops_t hub_ops; 140 141 void clear_port_status_change(hub_port_t *, uint16_t); 142 void set_port_status_change(hub_port_t *, uint16_t); 143 void set_port_status_change_nl(hub_port_t *, uint16_t); 144 76 int virthub_init(usbvirt_device_t *); 77 int virthub_connect_device(usbvirt_device_t *, virtdev_connection_t *); 78 int virthub_disconnect_device(usbvirt_device_t *, virtdev_connection_t *); 79 bool virthub_is_device_enabled(usbvirt_device_t *, virtdev_connection_t *); 80 void virthub_get_status(usbvirt_device_t *, char *, size_t); 145 81 146 82 #endif
Note:
See TracChangeset
for help on using the changeset viewer.