Changeset f37f811 in mainline
- Timestamp:
- 2010-12-15T22:25:01Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- cea3fca
- Parents:
- ea5dbaf (diff), e63a4e1 (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. - Location:
- uspace
- Files:
-
- 5 added
- 2 deleted
- 15 edited
- 9 moved
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/virtusbkbd/Makefile
rea5dbaf rf37f811 33 33 34 34 LIBS = $(LIBUSB_PREFIX)/libusb.a $(LIBUSBVIRT_PREFIX)/libusbvirt.a 35 EXTRA_CFLAGS = -I$(LIBUSB_PREFIX)/include -I$(LIB _PREFIX)-I$(LIBDRV_PREFIX)/include35 EXTRA_CFLAGS = -I$(LIBUSB_PREFIX)/include -I$(LIBUSBVIRT_PREFIX)/include -I$(LIBDRV_PREFIX)/include 36 36 37 37 SOURCES = \ -
uspace/app/virtusbkbd/stdreq.c
rea5dbaf rf37f811 39 39 #include "kbdconfig.h" 40 40 41 static int on_get_descriptor(struct usbvirt_device *dev, 42 usb_device_request_setup_packet_t *request, uint8_t *data); 43 44 usbvirt_standard_device_request_ops_t standard_request_ops = { 45 .on_get_status = NULL, 46 .on_clear_feature = NULL, 47 .on_set_feature = NULL, 48 .on_set_address = NULL, 49 .on_get_descriptor = on_get_descriptor, 50 .on_set_descriptor = NULL, 51 .on_get_configuration = NULL, 52 .on_set_configuration = NULL, 53 .on_get_interface = NULL, 54 .on_set_interface = NULL, 55 .on_synch_frame = NULL 56 }; 57 58 59 static int on_get_descriptor(struct usbvirt_device *dev, 41 int stdreq_on_get_descriptor(struct usbvirt_device *dev, 60 42 usb_device_request_setup_packet_t *request, uint8_t *data) 61 43 { -
uspace/app/virtusbkbd/stdreq.h
rea5dbaf rf37f811 38 38 #include <usbvirt/device.h> 39 39 40 extern usbvirt_standard_device_request_ops_t standard_request_ops; 40 int stdreq_on_get_descriptor(usbvirt_device_t *, 41 usb_device_request_setup_packet_t *, uint8_t *); 41 42 42 43 #endif -
uspace/app/virtusbkbd/virtusbkbd.c
rea5dbaf rf37f811 76 76 } 77 77 78 static int on_class_request(struct usbvirt_device *dev,79 usb_device_request_setup_packet_t *request, uint8_t *data)80 {81 printf("%s: class request (%d)\n", NAME, (int) request->request);82 83 return EOK;84 }85 78 86 79 /** Compares current and last status of pressed keys. … … 138 131 } 139 132 133 static usbvirt_control_transfer_handler_t endpoint_zero_handlers[] = { 134 { 135 .request_type = USBVIRT_MAKE_CONTROL_REQUEST_TYPE( 136 USB_DIRECTION_IN, 137 USBVIRT_REQUEST_TYPE_STANDARD, 138 USBVIRT_REQUEST_RECIPIENT_DEVICE), 139 .request = USB_DEVREQ_GET_DESCRIPTOR, 140 .name = "GetDescriptor", 141 .callback = stdreq_on_get_descriptor 142 }, 143 { 144 .request_type = USBVIRT_MAKE_CONTROL_REQUEST_TYPE( 145 USB_DIRECTION_IN, 146 USBVIRT_REQUEST_TYPE_CLASS, 147 USBVIRT_REQUEST_RECIPIENT_DEVICE), 148 .request = USB_DEVREQ_GET_DESCRIPTOR, 149 .name = "GetDescriptor", 150 .callback = stdreq_on_get_descriptor 151 }, 152 USBVIRT_CONTROL_TRANSFER_HANDLER_LAST 153 }; 140 154 141 155 /** Keyboard callbacks. … … 143 157 */ 144 158 static usbvirt_device_ops_t keyboard_ops = { 145 .standard_request_ops = &standard_request_ops, 146 .on_class_device_request = on_class_request, 159 .control_transfer_handlers = endpoint_zero_handlers, 147 160 .on_data = on_incoming_data, 148 161 .on_data_request = on_request_for_data … … 257 270 258 271 printf("%s: Simulating keyboard events...\n", NAME); 272 fibril_sleep(10); 259 273 while (1) { 260 274 kb_process_events(&status, keyboard_events, keyboard_events_count, -
uspace/drv/vhc/Makefile
rea5dbaf rf37f811 33 33 $(LIBDRV_PREFIX)/libdrv.a 34 34 EXTRA_CFLAGS += \ 35 -I$(LIB _PREFIX)\35 -I$(LIBUSBVIRT_PREFIX)/include \ 36 36 -I$(LIBUSB_PREFIX)/include \ 37 37 -I$(LIBDRV_PREFIX)/include … … 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/connhost.c
rea5dbaf rf37f811 102 102 transfer->out_callback = callback; 103 103 104 hc_add_transaction_to_device(false, target, buffer, size,104 hc_add_transaction_to_device(false, target, transfer_type, buffer, size, 105 105 universal_callback, transfer); 106 106 … … 122 122 transfer->out_callback = callback; 123 123 124 hc_add_transaction_to_device(true, target, buffer, size,124 hc_add_transaction_to_device(true, target, transfer_type, buffer, size, 125 125 universal_callback, transfer); 126 126 … … 142 142 transfer->in_callback = callback; 143 143 144 hc_add_transaction_from_device(target, buffer, size,144 hc_add_transaction_from_device(target, transfer_type, buffer, size, 145 145 universal_callback, transfer); 146 146 -
uspace/drv/vhc/devices.c
rea5dbaf rf37f811 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
rea5dbaf rf37f811 68 68 static link_t transaction_list; 69 69 70 #define TRANSACTION_FORMAT "T[%d :%d%s (%d)]"70 #define TRANSACTION_FORMAT "T[%d.%d %s/%s (%d)]" 71 71 #define TRANSACTION_PRINTF(t) \ 72 72 (t).target.address, (t).target.endpoint, \ 73 usb_str_transfer_type((t).transfer_type), \ 73 74 usbvirt_str_transaction_type((t).type), \ 74 75 (int)(t).len … … 76 77 #define transaction_get_instance(lnk) \ 77 78 list_get_instance(lnk, transaction_t, link) 79 80 #define HUB_STATUS_MAX_LEN (HUB_PORT_COUNT + 64) 78 81 79 82 static inline unsigned int pseudo_random(unsigned int *seed) … … 99 102 /** Host controller manager main function. 100 103 */ 101 void hc_manager(void)104 static int hc_manager_fibril(void *arg) 102 105 { 103 106 list_initialize(&transaction_list); … … 114 117 } 115 118 116 char ports[HUB_PORT_COUNT + 2]; 117 hub_get_port_statuses(ports, HUB_PORT_COUNT + 1); 118 dprintf(4, "virtual hub: addr=%d ports=%s", 119 virthub_dev.address, ports); 119 char ports[HUB_STATUS_MAX_LEN + 1]; 120 virthub_get_status(&virtual_hub_device, ports, HUB_STATUS_MAX_LEN); 120 121 121 122 link_t *first_transaction_link = transaction_list.next; … … 125 126 126 127 127 dprintf(0, "about to process " TRANSACTION_FORMAT " (vhub:%s)",128 dprintf(0, "about to process " TRANSACTION_FORMAT " [%s]", 128 129 TRANSACTION_PRINTF(*transaction), ports); 129 130 … … 138 139 free(transaction); 139 140 } 141 142 assert(false && "unreachable"); 143 return EOK; 144 } 145 146 void hc_manager(void) 147 { 148 fid_t fid = fibril_create(hc_manager_fibril, NULL); 149 if (fid == 0) { 150 printf(NAME ": failed to start HC manager fibril\n"); 151 return; 152 } 153 fibril_add_ready(fid); 140 154 } 141 155 … … 143 157 */ 144 158 static transaction_t *transaction_create(usbvirt_transaction_type_t type, 145 usb_target_t target, 159 usb_target_t target, usb_transfer_type_t transfer_type, 146 160 void * buffer, size_t len, 147 161 hc_transaction_done_callback_t callback, void * arg) … … 151 165 list_initialize(&transaction->link); 152 166 transaction->type = type; 167 transaction->transfer_type = transfer_type; 153 168 transaction->target = target; 154 169 transaction->buffer = buffer; … … 166 181 */ 167 182 void hc_add_transaction_to_device(bool setup, usb_target_t target, 183 usb_transfer_type_t transfer_type, 168 184 void * buffer, size_t len, 169 185 hc_transaction_done_callback_t callback, void * arg) 170 186 { 171 187 transaction_t *transaction = transaction_create( 172 setup ? USBVIRT_TRANSACTION_SETUP : USBVIRT_TRANSACTION_OUT, target, 188 setup ? USBVIRT_TRANSACTION_SETUP : USBVIRT_TRANSACTION_OUT, 189 target, transfer_type, 173 190 buffer, len, callback, arg); 174 191 list_append(&transaction->link, &transaction_list); … … 178 195 */ 179 196 void hc_add_transaction_from_device(usb_target_t target, 197 usb_transfer_type_t transfer_type, 180 198 void * buffer, size_t len, 181 199 hc_transaction_done_callback_t callback, void * arg) 182 200 { 183 201 transaction_t *transaction = transaction_create(USBVIRT_TRANSACTION_IN, 184 target, buffer, len, callback, arg); 202 target, transfer_type, 203 buffer, len, callback, arg); 185 204 list_append(&transaction->link, &transaction_list); 186 205 } -
uspace/drv/vhc/hc.h
rea5dbaf rf37f811 55 55 /** Transaction type. */ 56 56 usbvirt_transaction_type_t type; 57 /** Transfer type. */ 58 usb_transfer_type_t transfer_type; 57 59 /** Device address. */ 58 60 usb_target_t target; … … 71 73 void hc_manager(void); 72 74 73 void hc_add_transaction_to_device(bool setup, usb_target_t target, 75 void hc_add_transaction_to_device(bool setup, 76 usb_target_t target, usb_transfer_type_t transfer_type, 74 77 void * buffer, size_t len, 75 78 hc_transaction_done_callback_t callback, void * arg); 76 79 77 void hc_add_transaction_from_device(usb_target_t target, 80 void hc_add_transaction_from_device( 81 usb_target_t target, usb_transfer_type_t transfer_type, 78 82 void * buffer, size_t len, 79 83 hc_transaction_done_callback_t callback, void * arg); -
uspace/drv/vhc/hcd.c
rea5dbaf rf37f811 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); … … 95 95 }; 96 96 97 /** Fibril wrapper for HC transaction manager.98 *99 * @param arg Not used.100 * @return Nothing, return argument is unreachable.101 */102 static int hc_manager_fibril(void *arg)103 {104 hc_manager();105 return EOK;106 }107 97 108 98 int main(int argc, char * argv[]) 109 99 { 110 printf("%s: virtual USB host controller driver.\n", NAME);111 112 usb_dprintf_enable(NAME, 0);113 114 fid_t fid = fibril_create(hc_manager_fibril, NULL);115 if (fid == 0) {116 printf("%s: failed to start HC manager fibril\n", NAME);117 return ENOMEM;118 }119 fibril_add_ready(fid);120 121 100 /* 122 101 * Temporary workaround. Wait a little bit to be the last driver 123 102 * in devman output. 124 103 */ 125 sleep(4); 104 sleep(5); 105 106 usb_dprintf_enable(NAME, 0); 107 108 printf(NAME ": virtual USB host controller driver.\n"); 109 110 hc_manager(); 126 111 127 112 return driver_main(&vhc_driver); -
uspace/drv/vhc/hub.c
rea5dbaf rf37f811 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 = 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); 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 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; 193 80 194 usb_address_t hub_address = hub_set_address(&virthub_dev);195 if (h ub_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; 198 85 } 199 86 200 dprintf(2, "virtual hub address changed to %d", hub_address);87 usb_drv_reserve_default_address(hc); 201 88 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 207 94 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); 212 97 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; 216 99 } 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 normally240 * announce the plug-in.241 * Otherwise, we will wait until hub is configured242 * 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 }253 100 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 result295 * (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 }308 101 309 102 /** -
uspace/drv/vhc/hub.h
rea5dbaf rf37f811 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
rea5dbaf rf37f811 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 -
uspace/lib/c/generic/devman.c
rea5dbaf rf37f811 230 230 231 231 if (flags & IPC_FLAG_BLOCKING) { 232 phone = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_DEVMAN,232 phone = async_connect_me_to_blocking(PHONE_NS, SERVICE_DEVMAN, 233 233 DEVMAN_CONNECT_TO_DEVICE, handle); 234 234 } else { 235 phone = ipc_connect_me_to(PHONE_NS, SERVICE_DEVMAN,235 phone = async_connect_me_to(PHONE_NS, SERVICE_DEVMAN, 236 236 DEVMAN_CONNECT_TO_DEVICE, handle); 237 237 } -
uspace/lib/usb/src/usbdrv.c
rea5dbaf rf37f811 72 72 devman_handle_t handle; 73 73 74 rc = devman_device_get_handle("/virt/usbhc", &handle, 0);74 rc = devman_device_get_handle("/virt/usbhc", &handle, flags); 75 75 if (rc != EOK) { 76 76 return rc; 77 77 } 78 78 79 int phone = devman_device_connect(handle, 0);79 int phone = devman_device_connect(handle, flags); 80 80 81 81 return phone; -
uspace/lib/usbvirt/Makefile
rea5dbaf rf37f811 31 31 32 32 LIBS = $(LIBUSB_PREFIX)/libusb.a 33 EXTRA_CFLAGS = -I$(LIBUSB_PREFIX)/include 33 EXTRA_CFLAGS = -I$(LIBUSB_PREFIX)/include -Iinclude 34 34 35 35 SOURCES = \ 36 callback.c \37 ctrlpipe.c \38 debug.c \39 main.c \40 s tdreq.c \41 transaction.c36 src/callback.c \ 37 src/ctrlpipe.c \ 38 src/debug.c \ 39 src/main.c \ 40 src/stdreq.c \ 41 src/transaction.c 42 42 43 43 include $(USPACE_PREFIX)/Makefile.common -
uspace/lib/usbvirt/include/usbvirt/device.h
rea5dbaf rf37f811 40 40 #include <usb/devreq.h> 41 41 42 typedef enum { 43 USBVIRT_REQUEST_TYPE_STANDARD = 0, 44 USBVIRT_REQUEST_TYPE_CLASS = 1 45 } usbvirt_request_type_t; 46 47 typedef enum { 48 USBVIRT_REQUEST_RECIPIENT_DEVICE = 0, 49 USBVIRT_REQUEST_RECIPIENT_INTERFACE = 1, 50 USBVIRT_REQUEST_RECIPIENT_ENDPOINT = 2, 51 USBVIRT_REQUEST_RECIPIENT_OTHER = 3 52 } usbvirt_request_recipient_t; 53 54 /** Possible states of virtual USB device. 55 * Notice that these are not 1:1 mappings to those in USB specification. 56 */ 57 typedef enum { 58 USBVIRT_STATE_DEFAULT, 59 USBVIRT_STATE_ADDRESS, 60 USBVIRT_STATE_CONFIGURED 61 } usbvirt_device_state_t; 62 42 63 typedef struct usbvirt_device usbvirt_device_t; 43 64 struct usbvirt_control_transfer; … … 47 68 uint8_t *data); 48 69 49 /** Callbacks for standard device requests. 50 * When these functions are NULL or return EFORWARD, this 51 * framework will try to satisfy the request by itself. 52 */ 53 typedef struct { 54 u sbvirt_on_device_request_t on_get_status;55 u sbvirt_on_device_request_t on_clear_feature;56 usbvirt_on_device_request_t on_set_feature;57 usbvirt_ on_device_request_t on_set_address;58 usbvirt_on_device_request_t on_get_descriptor;59 usbvirt_on_device_request_t on_set_descriptor; 60 usbvirt_on_device_request_t on_get_configuration; 61 usbvirt_on_device_request_t on_set_configuration;62 usbvirt_on_device_request_t on_get_interface;63 usbvirt_on_device_request_t on_set_interface;64 usbvirt_on_device_request_t on_synch_frame; 65 } usbvirt_standard_device_request_ops_t; 70 typedef int (*usbvirt_control_request_callback_t)(usbvirt_device_t *dev, 71 usb_device_request_setup_packet_t *request, 72 uint8_t *data); 73 74 typedef struct { 75 uint8_t request_type; 76 uint8_t request; 77 const char *name; 78 usbvirt_control_request_callback_t callback; 79 } usbvirt_control_transfer_handler_t; 80 81 #define USBVIRT_MAKE_CONTROL_REQUEST_TYPE(direction, type, recipient) \ 82 ((((direction) == USB_DIRECTION_IN) ? 1 : 0) << 7) \ 83 | (((type) & 3) << 5) \ 84 | (((recipient) & 31)) 85 86 #define USBVIRT_CONTROL_TRANSFER_HANDLER_LAST { 0, 0, NULL, NULL } 66 87 67 88 /** Device operations. */ 68 89 typedef struct { 69 /** Callbacks for standard deivce requests. */ 70 usbvirt_standard_device_request_ops_t *standard_request_ops; 71 /** Callback for class-specific USB request. */ 72 usbvirt_on_device_request_t on_class_device_request; 73 90 /** Callbacks for transfers over control pipe zero. */ 91 usbvirt_control_transfer_handler_t *control_transfer_handlers; 92 74 93 int (*on_control_transfer)(usbvirt_device_t *dev, 75 94 usb_endpoint_t endpoint, struct usbvirt_control_transfer *transfer); … … 86 105 usb_direction_t (*decide_control_transfer_direction)( 87 106 usb_endpoint_t endpoint, void *buffer, size_t size); 107 108 /** Callback when device changes its state. 109 * 110 * It is correct that this function is called when both states 111 * are equal (e.g. this function is called during SET_CONFIGURATION 112 * request done on already configured device). 113 * 114 * @warning The value of <code>dev->state</code> before calling 115 * this function is not specified (i.e. can be @p old_state or 116 * @p new_state). 117 */ 118 void (*on_state_change)(usbvirt_device_t *dev, 119 usbvirt_device_state_t old_state, usbvirt_device_state_t new_state); 88 120 } usbvirt_device_ops_t; 89 121 … … 120 152 uint8_t current_configuration; 121 153 } usbvirt_descriptors_t; 122 123 /** Possible states of virtual USB device.124 * Notice that these are not 1:1 mappings to those in USB specification.125 */126 typedef enum {127 USBVIRT_STATE_DEFAULT,128 USBVIRT_STATE_ADDRESS,129 USBVIRT_STATE_CONFIGURED130 } usbvirt_device_state_t;131 154 132 155 /** Information about on-going control transfer. … … 157 180 usbvirt_device_ops_t *ops; 158 181 182 /** Custom device data. */ 183 void *device_data; 184 159 185 /** Reply onto control transfer. 160 186 */ -
uspace/lib/usbvirt/src/callback.c
rea5dbaf rf37f811 40 40 #include <mem.h> 41 41 42 #include "hub.h"43 #include "device.h"44 42 #include "private.h" 45 43 -
uspace/lib/usbvirt/src/debug.c
rea5dbaf rf37f811 36 36 #include <bool.h> 37 37 38 #include "device.h"39 38 #include "private.h" 40 39 -
uspace/lib/usbvirt/src/main.c
rea5dbaf rf37f811 39 39 #include <assert.h> 40 40 41 #include "hub.h"42 #include "device.h"43 41 #include "private.h" 44 42 -
uspace/lib/usbvirt/src/private.h
rea5dbaf rf37f811 36 36 #define LIBUSBVIRT_PRIVATE_H_ 37 37 38 #include "device.h" 39 #include "hub.h" 38 #include <usbvirt/device.h> 39 #include <usbvirt/hub.h> 40 #include <assert.h> 40 41 41 42 … … 86 87 } 87 88 89 extern usbvirt_control_transfer_handler_t control_pipe_zero_local_handlers[]; 90 88 91 #endif 89 92 /** -
uspace/lib/usbvirt/src/stdreq.c
rea5dbaf rf37f811 40 40 #include "private.h" 41 41 42 43 44 42 /* 45 43 * All sub handlers must return EFORWARD to inform the caller that … … 51 49 /** GET_DESCRIPTOR handler. */ 52 50 static int handle_get_descriptor(usbvirt_device_t *device, 53 uint8_t type, uint8_t index, uint16_t language, 54 uint16_t length) 51 usb_device_request_setup_packet_t *setup_packet, uint8_t *extra_data) 55 52 { 53 uint8_t type = setup_packet->value_high; 54 uint8_t index = setup_packet->value_low; 55 56 56 /* 57 57 * Standard device descriptor. … … 110 110 /** SET_ADDRESS handler. */ 111 111 static int handle_set_address(usbvirt_device_t *device, 112 uint16_t new_address, 113 uint16_t zero1, uint16_t zero2) 112 usb_device_request_setup_packet_t *setup_packet, uint8_t *extra_data) 114 113 { 114 uint16_t new_address = setup_packet->value; 115 uint16_t zero1 = setup_packet->index; 116 uint16_t zero2 = setup_packet->length; 117 115 118 if ((zero1 != 0) || (zero2 != 0)) { 116 119 return EINVAL; … … 128 131 /** SET_CONFIGURATION handler. */ 129 132 static int handle_set_configuration(usbvirt_device_t *device, 130 uint16_t configuration_value, 131 uint16_t zero1, uint16_t zero2) 133 usb_device_request_setup_packet_t *setup_packet, uint8_t *extra_data) 132 134 { 135 uint16_t configuration_value = setup_packet->value; 136 uint16_t zero1 = setup_packet->index; 137 uint16_t zero2 = setup_packet->length; 138 133 139 if ((zero1 != 0) || (zero2 != 0)) { 134 140 return EINVAL; … … 151 157 152 158 if (configuration_value == 0) { 159 if (DEVICE_HAS_OP(device, on_state_change)) { 160 device->ops->on_state_change(device, device->state, 161 USBVIRT_STATE_ADDRESS); 162 } 153 163 device->state = USBVIRT_STATE_ADDRESS; 154 164 } else { … … 157 167 * user selected existing configuration. 158 168 */ 169 if (DEVICE_HAS_OP(device, on_state_change)) { 170 device->ops->on_state_change(device, device->state, 171 USBVIRT_STATE_CONFIGURED); 172 } 159 173 device->state = USBVIRT_STATE_CONFIGURED; 160 174 if (device->descriptors) { … … 167 181 } 168 182 169 #define HANDLE_REQUEST(request, data, type, dev, user_callback, default_handler) \ 170 do { \ 171 if ((request)->request == (type)) { \ 172 int _rc = EFORWARD; \ 173 if (((dev)->ops) && ((dev)->ops->standard_request_ops) \ 174 && ((dev)->ops->standard_request_ops->user_callback)) { \ 175 _rc = (dev)->ops->standard_request_ops->\ 176 user_callback(dev, request, data); \ 177 } \ 178 if (_rc == EFORWARD) { \ 179 default_handler; \ 180 } \ 181 return _rc; \ 182 } \ 183 } while (false) 184 185 /** Handle standard device request. */ 186 int handle_std_request(usbvirt_device_t *device, 187 usb_device_request_setup_packet_t *request, uint8_t *data) 188 { 189 device->lib_debug(device, 3, USBVIRT_DEBUGTAG_CONTROL_PIPE_ZERO, 190 "handling standard request %d", request->request); 191 192 HANDLE_REQUEST(request, data, USB_DEVREQ_GET_DESCRIPTOR, 193 device, on_get_descriptor, 194 handle_get_descriptor(device, request->value_high, request->value_low, 195 request->index, request->length)); 196 197 HANDLE_REQUEST(request, data, USB_DEVREQ_SET_ADDRESS, 198 device, on_set_address, 199 handle_set_address(device, request->value, 200 request->index, request->length)); 201 202 HANDLE_REQUEST(request, data, USB_DEVREQ_SET_CONFIGURATION, 203 device, on_set_configuration, 204 handle_set_configuration(device, request->value, 205 request->index, request->length)); 206 207 return ENOTSUP; 208 } 183 184 #define MAKE_BM_REQUEST(direction, recipient) \ 185 USBVIRT_MAKE_CONTROL_REQUEST_TYPE(direction, \ 186 USBVIRT_REQUEST_TYPE_STANDARD, recipient) 187 #define MAKE_BM_REQUEST_DEV(direction) \ 188 MAKE_BM_REQUEST(direction, USBVIRT_REQUEST_RECIPIENT_DEVICE) 189 190 usbvirt_control_transfer_handler_t control_pipe_zero_local_handlers[] = { 191 { 192 .request_type = MAKE_BM_REQUEST_DEV(USB_DIRECTION_IN), 193 .request = USB_DEVREQ_GET_DESCRIPTOR, 194 .name = "GetDescriptor()", 195 .callback = handle_get_descriptor 196 }, 197 { 198 .request_type = MAKE_BM_REQUEST_DEV(USB_DIRECTION_OUT), 199 .request = USB_DEVREQ_SET_ADDRESS, 200 .name = "SetAddress()", 201 .callback = handle_set_address 202 }, 203 { 204 .request_type = MAKE_BM_REQUEST_DEV(USB_DIRECTION_OUT), 205 .request = USB_DEVREQ_SET_CONFIGURATION, 206 .name = "SetConfiguration()", 207 .callback = handle_set_configuration 208 }, 209 USBVIRT_CONTROL_TRANSFER_HANDLER_LAST 210 }; 209 211 210 212 /** -
uspace/lib/usbvirt/src/transaction.c
rea5dbaf rf37f811 37 37 #include <mem.h> 38 38 39 #include "hub.h"40 39 #include "private.h" 41 40
Note:
See TracChangeset
for help on using the changeset viewer.