Changeset 20eaa82 in mainline
- Timestamp:
- 2017-10-15T13:44:39Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 2770b66
- Parents:
- 867b375
- Location:
- uspace
- Files:
-
- 18 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/ehci/hw_struct/queue_head.c
r867b375 r20eaa82 37 37 #include <mem.h> 38 38 #include <macros.h> 39 #include <usb/host/bus.h> 39 40 40 41 #include "mem_access.h" … … 81 82 if (ep->speed != USB_SPEED_HIGH) { 82 83 ep_cap |= 83 QH_EP_CAP_TT_PORT_SET(ep-> tt.port) |84 QH_EP_CAP_TT_ADDR_SET(ep-> tt.address);84 QH_EP_CAP_TT_PORT_SET(ep->device->tt.port) | 85 QH_EP_CAP_TT_ADDR_SET(ep->device->tt.address); 85 86 } 86 87 if (ep->transfer_type == USB_TRANSFER_INTERRUPT) { -
uspace/drv/bus/usb/ehci/main.c
r867b375 r20eaa82 57 57 58 58 static const ddf_hc_driver_t ehci_hc_driver = { 59 .hc_speed = USB_SPEED_HIGH,60 59 .name = "EHCI-PCI", 61 60 .init = ehci_driver_init, -
uspace/drv/bus/usb/xhci/bus.c
r867b375 r20eaa82 35 35 #include <adt/hash_table.h> 36 36 #include <adt/hash.h> 37 #include <usb/host/ddf_helpers.h> 37 38 #include <usb/host/endpoint.h> 39 #include <usb/host/hcd.h> 38 40 #include <usb/debug.h> 39 41 40 42 #include <assert.h> 41 43 #include <errno.h> 44 #include <str_error.h> 42 45 #include <macros.h> 43 46 #include <stdbool.h> … … 53 56 xhci_device_t *device; 54 57 } hashed_device_t; 58 59 /** TODO: Still some copy-pasta left... 60 */ 61 int xhci_bus_enumerate_device(xhci_bus_t *bus, xhci_hc_t *hc, device_t *dev) 62 { 63 int err; 64 65 /* TODO: get speed from the default address reservation */ 66 dev->speed = USB_SPEED_FULL; 67 68 /* Manage TT */ 69 if (dev->hub->speed == USB_SPEED_HIGH && usb_speed_is_11(dev->speed)) { 70 /* For LS devices under HS hub */ 71 /* TODO: How about SS hubs? */ 72 dev->tt.address = dev->hub->address; 73 dev->tt.port = dev->port; 74 } 75 else { 76 /* Inherit hub's TT */ 77 dev->tt = dev->hub->tt; 78 } 79 80 /* Assign an address to the device */ 81 if ((err = xhci_rh_address_device(&hc->rh, dev))) { 82 usb_log_error("Failed to setup address of the new device: %s", str_error(err)); 83 return err; 84 } 85 86 /* Read the device descriptor, derive the match ids */ 87 if ((err = hcd_ddf_device_explore(hc->hcd, dev))) { 88 usb_log_error("Device(%d): Failed to explore device: %s", dev->address, str_error(err)); 89 bus_release_address(&bus->base, dev->address); 90 return err; 91 } 92 93 return EOK; 94 } 95 96 static int enumerate_device(bus_t *bus, hcd_t *hcd, device_t *dev) 97 { 98 xhci_hc_t *hc = hcd_get_driver_data(hcd); 99 assert(hc); 100 101 return xhci_bus_enumerate_device((xhci_bus_t *) bus, hc, dev); 102 } 103 104 static int remove_device(bus_t *bus, hcd_t *hcd, device_t *dev) 105 { 106 // TODO: Implement me! 107 108 return ENOTSUP; 109 } 55 110 56 111 /** Ops receive generic bus_t pointer. */ … … 214 269 } 215 270 216 static int get_speed(bus_t *bus_base, usb_address_t address, usb_speed_t *speed)217 {218 xhci_bus_t *bus = bus_to_xhci_bus(bus_base);219 assert(bus);220 221 // TODO: Use `xhci_get_port_speed` once we find the port corresponding to `address`.222 *speed = USB_SPEED_SUPER;223 return EOK;224 }225 226 271 static int release_address(bus_t *bus_base, usb_address_t address) 227 272 { … … 255 300 256 301 static const bus_ops_t xhci_bus_ops = { 302 .enumerate_device = enumerate_device, 303 .remove_device = remove_device, 304 257 305 .create_endpoint = create_endpoint, 258 306 .destroy_endpoint = destroy_endpoint, … … 263 311 264 312 .request_address = request_address, 265 .get_speed = get_speed,266 313 .release_address = release_address, 267 314 .reset_toggle = reset_toggle, … … 303 350 assert(bus); 304 351 305 bus_init(&bus->base );352 bus_init(&bus->base, sizeof(device_t)); 306 353 307 354 if (!hash_table_create(&bus->devices, 0, 0, &device_ht_ops)) { … … 320 367 hash_table_destroy(&bus->devices); 321 368 } 369 322 370 /** 323 371 * @} -
uspace/drv/bus/usb/xhci/bus.h
r867b375 r20eaa82 42 42 #include <usb/host/bus.h> 43 43 44 typedef struct xhci_hc xhci_hc_t; 45 44 46 /** Endpoint management structure */ 45 47 typedef struct xhci_bus { … … 58 60 void xhci_bus_fini(xhci_bus_t *); 59 61 62 int xhci_bus_enumerate_device(xhci_bus_t *, xhci_hc_t *, device_t *); 63 60 64 #endif 61 65 /** -
uspace/drv/bus/usb/xhci/hc.c
r867b375 r20eaa82 158 158 return err; 159 159 160 hc-> base = base;160 hc->reg_base = base; 161 161 hc->cap_regs = (xhci_cap_regs_t *) base; 162 162 hc->op_regs = (xhci_op_regs_t *) (base + XHCI_REG_RD(hc->cap_regs, XHCI_CAP_LENGTH)); … … 180 180 181 181 if ((err = hc_parse_ec(hc))) { 182 pio_disable(hc-> base, RNGSZ(hc->mmio_range));182 pio_disable(hc->reg_base, RNGSZ(hc->mmio_range)); 183 183 return err; 184 184 } … … 619 619 xhci_fini_commands(hc); 620 620 xhci_rh_fini(&hc->rh); 621 pio_disable(hc-> base, RNGSZ(hc->mmio_range));621 pio_disable(hc->reg_base, RNGSZ(hc->mmio_range)); 622 622 usb_log_info("HC(%p): Finalized.", hc); 623 623 } -
uspace/drv/bus/usb/xhci/hc.h
r867b375 r20eaa82 53 53 /* MMIO range */ 54 54 addr_range_t mmio_range; 55 void *base;56 55 57 56 /* Mapped register sets */ 57 void *reg_base; 58 58 xhci_cap_regs_t *cap_regs; 59 59 xhci_op_regs_t *op_regs; … … 83 83 list_t commands; 84 84 list_t transfers; 85 86 /* TODO: Hack. Figure out a better way. */ 87 hcd_t *hcd; 85 88 } xhci_hc_t; 86 89 -
uspace/drv/bus/usb/xhci/main.c
r867b375 r20eaa82 55 55 static void hcd_interrupt(hcd_t *, uint32_t); 56 56 static int hcd_schedule(hcd_t *, usb_transfer_batch_t *); 57 static int hcd_address_device(hcd_t *, usb_speed_t, usb_tt_address_t, usb_address_t *);58 57 static void hc_driver_fini(hcd_t *); 59 58 60 59 static const ddf_hc_driver_t xhci_ddf_hc_driver = { 61 .hc_speed = USB_SPEED_SUPER,62 60 .name = "XHCI-PCI", 63 61 .init = hc_driver_init, … … 71 69 .irq_hook = hcd_interrupt, 72 70 .status_hook = hcd_status, 73 .address_device = hcd_address_device,74 71 } 75 72 }; … … 90 87 91 88 hcd_set_implementation(hcd, hc, &xhci_ddf_hc_driver.ops, &hc->bus.base); 89 hc->hcd = hcd; 92 90 93 91 return EOK; … … 126 124 assert(hc); 127 125 128 hc->rh.hc d_rh = hcd_roothub_create(hcd, dev, USB_SPEED_SUPER);129 return hc->rh.hcd_rh ? EOK : ENOMEM;126 hc->rh.hc_device = dev; 127 return device_init(&hc->rh.device); 130 128 } 131 129 … … 153 151 154 152 hc_interrupt(hc, status); 155 }156 157 static int hcd_address_device(hcd_t *hcd, usb_speed_t speed, usb_tt_address_t tt, usb_address_t *address)158 {159 xhci_hc_t *hc = hcd_get_driver_data(hcd);160 assert(hc);161 162 return xhci_rh_address_device(&hc->rh, speed, tt, address);163 153 } 164 154 -
uspace/drv/bus/usb/xhci/rh.c
r867b375 r20eaa82 38 38 #include <usb/debug.h> 39 39 #include <usb/host/utils/malloc32.h> 40 #include <usb/host/bus.h> 40 41 #include <usb/host/ddf_helpers.h> 41 42 … … 73 74 // TODO: This currently assumes the device is attached to rh directly. 74 75 // Also, we should consider moving a lot of functionailty to xhci bus 75 int xhci_rh_address_device(xhci_rh_t *rh, usb_speed_t unused_speed, usb_tt_address_t tt, usb_address_t *address)76 int xhci_rh_address_device(xhci_rh_t *rh, device_t *dev) 76 77 { 77 78 int err; … … 81 82 xhci_cmd_init(&cmd); 82 83 83 uint8_t port = tt.port;84 85 84 /* XXX Certainly not generic solution. */ 86 85 uint32_t route_str = 0; 87 86 88 const xhci_port_speed_t *speed = xhci_rh_get_port_speed(rh, port);87 const xhci_port_speed_t *speed = xhci_rh_get_port_speed(rh, dev->port); 89 88 90 89 xhci_send_enable_slot_command(hc, &cmd); … … 109 108 /* Initialize slot_ctx according to section 4.3.3 point 3. */ 110 109 /* Attaching to root hub port, root string equals to 0. */ 111 XHCI_SLOT_ROOT_HUB_PORT_SET(ictx->slot_ctx, port);110 XHCI_SLOT_ROOT_HUB_PORT_SET(ictx->slot_ctx, dev->port); 112 111 XHCI_SLOT_CTX_ENTRIES_SET(ictx->slot_ctx, 1); 113 112 XHCI_SLOT_ROUTE_STRING_SET(ictx->slot_ctx, route_str); … … 158 157 xhci_cmd_fini(&cmd); 159 158 160 *address = XHCI_SLOT_DEVICE_ADDRESS(dctx->slot_ctx);161 usb_log_debug2("Obtained USB address: %d.\n", *address);159 dev->address = XHCI_SLOT_DEVICE_ADDRESS(dctx->slot_ctx); 160 usb_log_debug2("Obtained USB address: %d.\n", dev->address); 162 161 163 162 // TODO: Ask libusbhost to create a control endpoint for EP0. … … 183 182 } 184 183 184 /** Create a device node for device directly connected to RH. 185 */ 185 186 static int rh_setup_device(xhci_rh_t *rh, uint8_t port_id) 186 187 { 187 /** This should ideally use the libusbhost in a clean and elegant way, 188 * to create child function. The refactoring of libusbhost is not over 189 * yet, so for now it is still quirky. 190 */ 191 192 return hcd_roothub_new_device(rh->hcd_rh, port_id); 188 int err; 189 assert(rh); 190 191 xhci_bus_t *bus = &rh->hc->bus; 192 193 device_t *dev = hcd_ddf_device_create(rh->hc_device, bus->base.device_size); 194 if (!dev) { 195 usb_log_error("Failed to create USB device function."); 196 return ENOMEM; 197 } 198 199 dev->hub = &rh->device; 200 dev->port = port_id; 201 202 if ((err = xhci_bus_enumerate_device(bus, rh->hc, dev))) { 203 usb_log_error("Failed to enumerate USB device: %s", str_error(err)); 204 return err; 205 } 206 207 if (!ddf_fun_get_name(dev->fun)) { 208 device_set_default_name(dev); 209 } 210 211 if ((err = ddf_fun_bind(dev->fun))) { 212 usb_log_error("Device(%d): Failed to register: %s.", dev->address, str_error(err)); 213 goto err_usb_dev; 214 } 215 216 fibril_mutex_lock(&rh->device.guard); 217 list_append(&dev->link, &rh->device.devices); 218 fibril_mutex_unlock(&rh->device.guard); 219 220 return EOK; 221 222 err_usb_dev: 223 hcd_ddf_device_destroy(dev); 224 return err; 193 225 } 194 226 -
uspace/drv/bus/usb/xhci/rh.h
r867b375 r20eaa82 38 38 39 39 #include <usb/host/usb_transfer_batch.h> 40 #include <usb/host/bus.h> 40 41 #include "hw_struct/regs.h" 41 42 42 43 typedef struct xhci_hc xhci_hc_t; 44 typedef struct ddf_dev ddf_dev_t; 43 45 44 46 /** … … 58 60 xhci_hc_t *hc; 59 61 62 /* Root for the device tree */ 63 device_t device; 64 65 /* We need this to attach children to */ 66 ddf_dev_t *hc_device; 67 60 68 /** Port speeds reported from HC */ 61 69 xhci_port_speed_t speeds [16]; … … 66 74 /* Number of hub ports. */ 67 75 uint8_t max_ports; 68 69 /* We need this to create child devices */70 hcd_roothub_t *hcd_rh;71 76 } xhci_rh_t; 72 77 … … 79 84 void xhci_rh_handle_port_change(xhci_rh_t *); 80 85 81 int xhci_rh_address_device(xhci_rh_t * , usb_speed_t, usb_tt_address_t, usb_address_t *);86 int xhci_rh_address_device(xhci_rh_t *rh, device_t *dev); 82 87 83 88 #endif -
uspace/lib/usb/include/usb/request.h
r867b375 r20eaa82 112 112 const usb_device_request_setup_packet_t *request); 113 113 114 #define GET_DEVICE_DESC(size) \ 115 { \ 116 .request_type = SETUP_REQUEST_TYPE_DEVICE_TO_HOST \ 117 | (USB_REQUEST_TYPE_STANDARD << 5) \ 118 | USB_REQUEST_RECIPIENT_DEVICE, \ 119 .request = USB_DEVREQ_GET_DESCRIPTOR, \ 120 .value = uint16_host2usb(USB_DESCTYPE_DEVICE << 8), \ 121 .index = uint16_host2usb(0), \ 122 .length = uint16_host2usb(size), \ 123 }; 124 125 #define SET_ADDRESS(address) \ 126 { \ 127 .request_type = SETUP_REQUEST_TYPE_HOST_TO_DEVICE \ 128 | (USB_REQUEST_TYPE_STANDARD << 5) \ 129 | USB_REQUEST_RECIPIENT_DEVICE, \ 130 .request = USB_DEVREQ_SET_ADDRESS, \ 131 .value = uint16_host2usb(address), \ 132 .index = uint16_host2usb(0), \ 133 .length = uint16_host2usb(0), \ 134 }; 135 136 #define CTRL_PIPE_MIN_PACKET_SIZE 8 137 114 138 #endif 115 139 /** -
uspace/lib/usbhost/include/usb/host/bus.h
r867b375 r20eaa82 45 45 #include <usb/usb.h> 46 46 47 #include <assert.h> 47 48 #include <fibril_synch.h> 48 49 #include <stdbool.h> … … 51 52 typedef struct endpoint endpoint_t; 52 53 typedef struct bus bus_t; 54 typedef struct ddf_fun ddf_fun_t; 55 56 typedef struct device { 57 /* Device tree keeping */ 58 link_t link; 59 list_t devices; 60 fibril_mutex_t guard; 61 62 /* Associated DDF function, if any */ 63 ddf_fun_t *fun; 64 65 /* Invalid for the roothub device */ 66 unsigned port; 67 struct device *hub; 68 69 /* Transaction translator */ 70 usb_tt_address_t tt; 71 72 /* The following are not set by the library */ 73 usb_speed_t speed; 74 usb_address_t address; 75 76 /* This structure is meant to be extended by overriding. */ 77 } device_t; 53 78 54 79 typedef struct { 80 int (*enumerate_device)(bus_t *, hcd_t *, device_t *); 81 int (*remove_device)(bus_t *, hcd_t *, device_t *); 82 55 83 endpoint_t *(*create_endpoint)(bus_t *); 56 84 int (*register_endpoint)(bus_t *, endpoint_t *); … … 59 87 60 88 int (*request_address)(bus_t *, usb_address_t*, bool, usb_speed_t); 61 int (*get_speed)(bus_t *, usb_address_t, usb_speed_t *);62 89 int (*release_address)(bus_t *, usb_address_t); 63 90 … … 77 104 fibril_mutex_t guard; 78 105 106 size_t device_size; 107 79 108 /* Do not call directly, ops are synchronized. */ 80 109 bus_ops_t ops; … … 83 112 } bus_t; 84 113 85 void bus_init(bus_t *); 114 void bus_init(bus_t *, size_t); 115 int device_init(device_t *); 116 117 extern int bus_add_ep(bus_t *bus, device_t *device, usb_endpoint_t endpoint, 118 usb_direction_t dir, usb_transfer_type_t type, size_t max_packet_size, 119 unsigned packets, size_t size); 120 extern int bus_remove_ep(bus_t *bus, usb_target_t target, usb_direction_t dir); 121 122 int device_set_default_name(device_t *); 123 124 int bus_enumerate_device(bus_t *, hcd_t *, device_t *); 125 int bus_remove_device(bus_t *, hcd_t *, device_t *); 86 126 87 127 endpoint_t *bus_create_endpoint(bus_t *); … … 93 133 94 134 int bus_request_address(bus_t *, usb_address_t *, bool, usb_speed_t); 95 int bus_get_speed(bus_t *, usb_address_t, usb_speed_t *);96 135 int bus_release_address(bus_t *, usb_address_t); 136 137 static inline int bus_reserve_default_address(bus_t *bus, usb_speed_t speed) { 138 usb_address_t addr = USB_ADDRESS_DEFAULT; 139 140 const int r = bus_request_address(bus, &addr, true, speed); 141 assert(addr == USB_ADDRESS_DEFAULT); 142 return r; 143 } 144 145 static inline int bus_release_default_address(bus_t *bus) { 146 return bus_release_address(bus, USB_ADDRESS_DEFAULT); 147 } 97 148 98 149 int bus_reset_toggle(bus_t *, usb_target_t, bool); -
uspace/lib/usbhost/include/usb/host/ddf_helpers.h
r867b375 r20eaa82 59 59 typedef struct { 60 60 hcd_ops_t ops; 61 usb_speed_t hc_speed;62 61 const char *name; 63 62 … … 83 82 int hcd_setup_virtual_root_hub(hcd_t *, ddf_dev_t *); 84 83 84 device_t *hcd_ddf_device_create(ddf_dev_t *, size_t); 85 void hcd_ddf_device_destroy(device_t *); 86 int hcd_ddf_device_explore(hcd_t *, device_t *); 87 85 88 hcd_t *dev_to_hcd(ddf_dev_t *dev); 86 89 … … 93 96 void ddf_hcd_gen_irq_handler(ipc_callid_t iid, ipc_call_t *call, ddf_dev_t *dev); 94 97 95 /* For xHCI, we need to drive the roothub without roothub having assigned an96 * address. Thus we cannot create function for it, and we have to carry the97 * usb_dev_t somewhere.98 *99 * This is sort of hacky, but at least does not expose the internals of ddf_helpers.100 */101 typedef struct hcd_roothub hcd_roothub_t;102 103 hcd_roothub_t *hcd_roothub_create(hcd_t *, ddf_dev_t *, usb_speed_t);104 int hcd_roothub_new_device(hcd_roothub_t *, unsigned port);105 106 98 #endif 107 99 -
uspace/lib/usbhost/include/usb/host/endpoint.h
r867b375 r20eaa82 47 47 48 48 typedef struct bus bus_t; 49 typedef struct device device_t; 49 50 50 51 /** Host controller side endpoint structure. */ … … 56 57 /** Part of linked list. */ 57 58 link_t link; 59 /** USB device */ 60 device_t *device; 58 61 /** USB address. */ 59 62 usb_target_t target; … … 78 81 /** Signals change of active status. */ 79 82 fibril_condvar_t avail; 80 /** High speed TT data */81 usb_tt_address_t tt;82 83 83 84 /* This structure is meant to be extended by overriding. */ -
uspace/lib/usbhost/include/usb/host/hcd.h
r867b375 r20eaa82 103 103 extern usb_address_t hcd_request_address(hcd_t *, usb_speed_t); 104 104 105 extern int hcd_release_address(hcd_t *, usb_address_t);106 107 extern int hcd_reserve_default_address(hcd_t *, usb_speed_t);108 109 static inline int hcd_release_default_address(hcd_t *hcd)110 {111 return hcd_release_address(hcd, USB_ADDRESS_DEFAULT);112 }113 114 105 extern int hcd_add_ep(hcd_t *, usb_target_t, usb_direction_t, 115 106 usb_transfer_type_t, size_t, unsigned int, size_t, usb_tt_address_t); -
uspace/lib/usbhost/src/bus.c
r867b375 r20eaa82 36 36 #include <usb/host/bus.h> 37 37 #include <usb/host/endpoint.h> 38 #include <ddf/driver.h> 38 39 39 40 #include <mem.h> 40 41 #include <errno.h> 42 #include <stdio.h> 41 43 42 44 /** 43 45 * Initializes the bus structure. 44 46 */ 45 void bus_init(bus_t *bus) 46 { 47 void bus_init(bus_t *bus, size_t device_size) 48 { 49 assert(bus); 50 assert(device_size >= sizeof(device_t)); 47 51 memset(bus, 0, sizeof(bus_t)); 48 52 49 53 fibril_mutex_initialize(&bus->guard); 54 bus->device_size = device_size; 55 } 56 57 int device_init(device_t *dev) 58 { 59 memset(dev, 0, sizeof(*dev)); 60 61 link_initialize(&dev->link); 62 list_initialize(&dev->devices); 63 fibril_mutex_initialize(&dev->guard); 64 65 return EOK; 66 } 67 68 int bus_add_ep(bus_t *bus, device_t *device, usb_endpoint_t endpoint, 69 usb_direction_t dir, usb_transfer_type_t type, size_t max_packet_size, 70 unsigned packets, size_t size) 71 { 72 assert(bus); 73 assert(device); 74 75 /* Temporary reference */ 76 endpoint_t *ep = bus_create_endpoint(bus); 77 if (!ep) 78 return ENOMEM; 79 80 ep->target = (usb_target_t) { 81 .address = device->address, 82 .endpoint = endpoint, 83 }; 84 85 ep->device = device; 86 ep->direction = dir; 87 ep->transfer_type = type; 88 ep->max_packet_size = max_packet_size; 89 ep->packets = packets; 90 91 ep->bandwidth = bus_count_bw(ep, size); 92 93 const int err = bus_register_endpoint(bus, ep); 94 95 /* drop Temporary reference */ 96 endpoint_del_ref(ep); 97 98 return err; 99 } 100 101 int bus_remove_ep(bus_t *bus, usb_target_t target, usb_direction_t dir) 102 { 103 assert(bus); 104 endpoint_t *ep = bus_find_endpoint(bus, target, dir); 105 if (!ep) 106 return ENOENT; 107 108 return bus_release_endpoint(bus, ep); 109 } 110 111 int device_set_default_name(device_t *dev) 112 { 113 assert(dev); 114 assert(dev->fun); 115 116 char buf[10] = { 0 }; /* usbxyz-ss */ 117 snprintf(buf, sizeof(buf) - 1, "usb%u-%cs", 118 dev->address, usb_str_speed(dev->speed)[0]); 119 120 return ddf_fun_set_name(dev->fun, buf); 121 } 122 123 int bus_enumerate_device(bus_t *bus, hcd_t *hcd, device_t *dev) 124 { 125 assert(bus); 126 assert(hcd); 127 assert(dev); 128 129 if (!bus->ops.enumerate_device) 130 return ENOTSUP; 131 132 fibril_mutex_lock(&bus->guard); 133 const int r = bus->ops.enumerate_device(bus, hcd, dev); 134 fibril_mutex_unlock(&bus->guard); 135 return r; 136 } 137 138 int bus_remove_device(bus_t *bus, hcd_t *hcd, device_t *dev) 139 { 140 assert(bus); 141 assert(dev); 142 143 if (!bus->ops.remove_device) 144 return ENOTSUP; 145 146 fibril_mutex_lock(&bus->guard); 147 const int r = bus->ops.remove_device(bus, hcd, dev); 148 fibril_mutex_unlock(&bus->guard); 149 return r; 50 150 } 51 151 … … 141 241 } 142 242 143 int bus_get_speed(bus_t *bus, usb_address_t address, usb_speed_t *speed)144 {145 assert(bus);146 assert(speed);147 148 if (!bus->ops.get_speed)149 return ENOTSUP;150 151 fibril_mutex_lock(&bus->guard);152 const int r = bus->ops.get_speed(bus, address, speed);153 fibril_mutex_unlock(&bus->guard);154 return r;155 }156 157 243 int bus_reset_toggle(bus_t *bus, usb_target_t target, bool all) 158 244 { -
uspace/lib/usbhost/src/ddf_helpers.c
r867b375 r20eaa82 35 35 36 36 #include <usb/classes/classes.h> 37 #include <usb/host/bus.h> 37 38 #include <usb/debug.h> 38 39 #include <usb/descriptor.h> … … 50 51 #include <fibril_synch.h> 51 52 #include <macros.h> 52 #include <stdio.h>53 53 #include <stdlib.h> 54 54 #include <str_error.h> … … 56 56 57 57 #include "ddf_helpers.h" 58 59 #define CTRL_PIPE_MIN_PACKET_SIZE 860 61 typedef struct usb_dev {62 link_t link;63 list_t devices;64 fibril_mutex_t guard;65 usb_address_t address;66 usb_speed_t speed;67 usb_tt_address_t tt;68 69 /* This must be set iff the usb_dev is managed by ddf_fun. */70 ddf_fun_t *fun;71 } usb_dev_t;72 58 73 59 typedef struct hc_dev { … … 92 78 93 79 94 static int hcd_ddf_new_device(hcd_t *hcd, ddf_dev_t *hc, usb_dev_t *hub_dev, unsigned port);95 static int hcd_ddf_remove_device(ddf_dev_t *device, usb_dev_t *hub, unsigned port);80 static int hcd_ddf_new_device(hcd_t *hcd, ddf_dev_t *hc, device_t *hub_dev, unsigned port); 81 static int hcd_ddf_remove_device(ddf_dev_t *device, device_t *hub, unsigned port); 96 82 97 83 … … 115 101 assert(fun); 116 102 hcd_t *hcd = dev_to_hcd(ddf_fun_get_dev(fun)); 117 usb_dev_t *dev = ddf_fun_data_get(fun);103 device_t *dev = ddf_fun_data_get(fun); 118 104 assert(hcd); 105 assert(hcd->bus); 119 106 assert(dev); 120 107 const size_t size = max_packet_size; 121 const usb_target_t target =122 {{.address = dev->address, .endpoint = endpoint}};123 108 124 109 usb_log_debug("Register endpoint %d:%d %s-%s %zuB %ums.\n", … … 126 111 usb_str_direction(direction), max_packet_size, interval); 127 112 128 return hcd_add_ep(hcd, target, direction, transfer_type,129 max_packet_size, packets, size , dev->tt);113 return bus_add_ep(hcd->bus, dev, endpoint, direction, transfer_type, 114 max_packet_size, packets, size); 130 115 } 131 116 … … 142 127 assert(fun); 143 128 hcd_t *hcd = dev_to_hcd(ddf_fun_get_dev(fun)); 144 usb_dev_t *dev = ddf_fun_data_get(fun);129 device_t *dev = ddf_fun_data_get(fun); 145 130 assert(hcd); 131 assert(hcd->bus); 146 132 assert(dev); 147 const usb_target_t target = 148 {{.address = dev->address, .endpoint = endpoint}}; 133 const usb_target_t target = {{ 134 .address = dev->address, 135 .endpoint = endpoint 136 }}; 149 137 usb_log_debug("Unregister endpoint %d:%d %s.\n", 150 138 dev->address, endpoint, usb_str_direction(direction)); 151 return hcd_remove_ep(hcd, target, direction);139 return bus_remove_ep(hcd->bus, target, direction); 152 140 } 153 141 … … 156 144 assert(fun); 157 145 hcd_t *hcd = dev_to_hcd(ddf_fun_get_dev(fun)); 158 usb_dev_t *dev = ddf_fun_data_get(fun);146 device_t *dev = ddf_fun_data_get(fun); 159 147 assert(hcd); 148 assert(hcd->bus); 160 149 assert(dev); 161 150 162 151 usb_log_debug("Device %d requested default address at %s speed\n", 163 152 dev->address, usb_str_speed(speed)); 164 return hcd_reserve_default_address(hcd, speed);153 return bus_reserve_default_address(hcd->bus, speed); 165 154 } 166 155 … … 169 158 assert(fun); 170 159 hcd_t *hcd = dev_to_hcd(ddf_fun_get_dev(fun)); 171 usb_dev_t *dev = ddf_fun_data_get(fun);160 device_t *dev = ddf_fun_data_get(fun); 172 161 assert(hcd); 162 assert(hcd->bus); 173 163 assert(dev); 174 164 175 165 usb_log_debug("Device %d released default address\n", dev->address); 176 return hcd_release_default_address(hcd);166 return bus_release_default_address(hcd->bus); 177 167 } 178 168 … … 184 174 hcd_t *hcd = dev_to_hcd(hc); 185 175 assert(hcd); 186 usb_dev_t *hub = ddf_fun_data_get(fun);176 device_t *hub = ddf_fun_data_get(fun); 187 177 assert(hub); 188 178 … … 196 186 assert(fun); 197 187 ddf_dev_t *ddf_dev = ddf_fun_get_dev(fun); 198 usb_dev_t *dev = ddf_fun_data_get(fun);188 device_t *dev = ddf_fun_data_get(fun); 199 189 assert(ddf_dev); 200 190 assert(dev); … … 233 223 { 234 224 assert(fun); 235 usb_dev_t *usb_dev = ddf_fun_data_get(fun);236 assert( usb_dev);225 device_t *dev = ddf_fun_data_get(fun); 226 assert(dev); 237 227 const usb_target_t target = {{ 238 .address = usb_dev->address,228 .address = dev->address, 239 229 .endpoint = endpoint, 240 230 }}; … … 259 249 { 260 250 assert(fun); 261 usb_dev_t *usb_dev = ddf_fun_data_get(fun);262 assert( usb_dev);251 device_t *dev = ddf_fun_data_get(fun); 252 assert(dev); 263 253 const usb_target_t target = {{ 264 .address = usb_dev->address,254 .address = dev->address, 265 255 .endpoint = endpoint, 266 256 }}; … … 343 333 } 344 334 345 static int hcd_ddf_remove_device(ddf_dev_t *device, usb_dev_t *hub,335 static int hcd_ddf_remove_device(ddf_dev_t *device, device_t *hub, 346 336 unsigned port) 347 337 { … … 350 340 hcd_t *hcd = dev_to_hcd(device); 351 341 assert(hcd); 342 assert(hcd->bus); 352 343 353 344 hc_dev_t *hc_dev = dev_to_hc_dev(device); … … 356 347 fibril_mutex_lock(&hub->guard); 357 348 358 usb_dev_t *victim = NULL;359 360 list_foreach(hub->devices, link, usb_dev_t, it) {361 if (it-> tt.port == port) {349 device_t *victim = NULL; 350 351 list_foreach(hub->devices, link, device_t, it) { 352 if (it->port == port) { 362 353 victim = it; 363 354 break; … … 366 357 if (victim) { 367 358 assert(victim->fun); 368 assert(victim->tt.port == port); 359 assert(victim->port == port); 360 assert(victim->hub == hub); 369 361 list_remove(&victim->link); 370 362 fibril_mutex_unlock(&hub->guard); … … 372 364 if (ret == EOK) { 373 365 usb_address_t address = victim->address; 366 bus_remove_device(hcd->bus, hcd, victim); 374 367 ddf_fun_destroy(victim->fun); 375 hcd_release_address(hcd, address);368 bus_release_address(hcd->bus, address); 376 369 } else { 377 370 usb_log_warning("Failed to unbind device `%s': %s\n", … … 384 377 } 385 378 386 #define GET_DEVICE_DESC(size) \ 387 { \ 388 .request_type = SETUP_REQUEST_TYPE_DEVICE_TO_HOST \ 389 | (USB_REQUEST_TYPE_STANDARD << 5) \ 390 | USB_REQUEST_RECIPIENT_DEVICE, \ 391 .request = USB_DEVREQ_GET_DESCRIPTOR, \ 392 .value = uint16_host2usb(USB_DESCTYPE_DEVICE << 8), \ 393 .index = uint16_host2usb(0), \ 394 .length = uint16_host2usb(size), \ 395 }; 396 397 #define SET_ADDRESS(address) \ 398 { \ 399 .request_type = SETUP_REQUEST_TYPE_HOST_TO_DEVICE \ 400 | (USB_REQUEST_TYPE_STANDARD << 5) \ 401 | USB_REQUEST_RECIPIENT_DEVICE, \ 402 .request = USB_DEVREQ_SET_ADDRESS, \ 403 .value = uint16_host2usb(address), \ 404 .index = uint16_host2usb(0), \ 405 .length = uint16_host2usb(0), \ 406 }; 407 408 static int hcd_usb2_address_device(hcd_t *hcd, usb_speed_t speed, 409 usb_tt_address_t tt, usb_address_t *out_address) 410 { 411 int err; 412 413 static const usb_target_t default_target = {{ 414 .address = USB_ADDRESS_DEFAULT, 415 .endpoint = 0, 416 }}; 417 418 /** Reserve address early, we want pretty log messages */ 419 const usb_address_t address = hcd_request_address(hcd, speed); 420 if (address < 0) { 421 usb_log_error("Failed to reserve new address: %s.", 422 str_error(address)); 423 return address; 424 } 425 usb_log_debug("Device(%d): Reserved new address.", address); 426 427 /* Add default pipe on default address */ 428 usb_log_debug("Device(%d): Adding default target (0:0)", address); 429 err = hcd_add_ep(hcd, 430 default_target, USB_DIRECTION_BOTH, USB_TRANSFER_CONTROL, 431 CTRL_PIPE_MIN_PACKET_SIZE, CTRL_PIPE_MIN_PACKET_SIZE, 1, tt); 432 if (err != EOK) { 433 usb_log_error("Device(%d): Failed to add default target: %s.", 434 address, str_error(err)); 435 goto err_address; 436 } 437 438 /* Get max packet size for default pipe */ 439 usb_standard_device_descriptor_t desc = { 0 }; 440 const usb_device_request_setup_packet_t get_device_desc_8 = 441 GET_DEVICE_DESC(CTRL_PIPE_MIN_PACKET_SIZE); 442 443 usb_log_debug("Device(%d): Requesting first 8B of device descriptor.", 444 address); 445 ssize_t got = hcd_send_batch_sync(hcd, default_target, USB_DIRECTION_IN, 446 &desc, CTRL_PIPE_MIN_PACKET_SIZE, *(uint64_t *)&get_device_desc_8, 447 "read first 8 bytes of dev descriptor"); 448 449 if (got != CTRL_PIPE_MIN_PACKET_SIZE) { 450 err = got < 0 ? got : EOVERFLOW; 451 usb_log_error("Device(%d): Failed to get 8B of dev descr: %s.", 452 address, str_error(err)); 453 goto err_default_target; 454 } 455 456 /* Set new address */ 457 const usb_device_request_setup_packet_t set_address = SET_ADDRESS(address); 458 459 usb_log_debug("Device(%d): Setting USB address.", address); 460 err = hcd_send_batch_sync(hcd, default_target, USB_DIRECTION_OUT, 461 NULL, 0, *(uint64_t *)&set_address, "set address"); 462 if (err != 0) { 463 usb_log_error("Device(%d): Failed to set new address: %s.", 464 address, str_error(got)); 465 goto err_default_target; 466 } 467 468 *out_address = address; 469 470 usb_target_t control_ep = { 471 .address = address, 472 .endpoint = 0 473 }; 474 475 /* Register EP on the new address */ 476 usb_log_debug("Device(%d): Registering control EP.", address); 477 err = hcd_add_ep(hcd, control_ep, USB_DIRECTION_BOTH, USB_TRANSFER_CONTROL, 478 ED_MPS_PACKET_SIZE_GET(uint16_usb2host(desc.max_packet_size)), 479 ED_MPS_TRANS_OPPORTUNITIES_GET(uint16_usb2host(desc.max_packet_size)), 480 ED_MPS_PACKET_SIZE_GET(uint16_usb2host(desc.max_packet_size)), tt); 481 if (err != EOK) { 482 usb_log_error("Device(%d): Failed to register EP0: %s", 483 address, str_error(err)); 484 goto err_default_target; 485 } 486 487 hcd_remove_ep(hcd, default_target, USB_DIRECTION_BOTH); 488 return EOK; 489 490 491 err_default_target: 492 hcd_remove_ep(hcd, default_target, USB_DIRECTION_BOTH); 493 err_address: 494 hcd_release_address(hcd, address); 495 return err; 496 } 497 498 static int usb_dev_init(usb_dev_t *usb_dev, usb_speed_t speed) 499 { 500 memset(usb_dev, 0, sizeof(*usb_dev)); 501 502 link_initialize(&usb_dev->link); 503 list_initialize(&usb_dev->devices); 504 fibril_mutex_initialize(&usb_dev->guard); 505 506 usb_dev->speed = speed; 507 508 return EOK; 509 } 510 511 static usb_dev_t *usb_dev_create(ddf_dev_t *hc, usb_speed_t speed) 379 device_t *hcd_ddf_device_create(ddf_dev_t *hc, size_t device_size) 512 380 { 513 381 /* Create DDF function for the new device */ … … 519 387 520 388 /* Create USB device node for the new device */ 521 usb_dev_t *usb_dev = ddf_fun_data_alloc(fun, sizeof(usb_dev_t));522 if (! usb_dev) {389 device_t *dev = ddf_fun_data_alloc(fun, device_size); 390 if (!dev) { 523 391 ddf_fun_destroy(fun); 524 392 return NULL; 525 393 } 526 394 527 usb_dev_init(usb_dev, speed);528 usb_dev->fun = fun;529 return usb_dev;530 } 531 532 static void usb_dev_destroy(usb_dev_t *dev)395 device_init(dev); 396 dev->fun = fun; 397 return dev; 398 } 399 400 void hcd_ddf_device_destroy(device_t *dev) 533 401 { 534 402 assert(dev); … … 537 405 } 538 406 539 static int usb_dev_set_default_name(usb_dev_t *usb_dev) 540 { 541 assert(usb_dev); 542 543 char buf[10] = { 0 }; /* usbxyz-ss */ 544 snprintf(buf, sizeof(buf) - 1, "usb%u-%cs", 545 usb_dev->address, usb_str_speed(usb_dev->speed)[0]); 546 547 return ddf_fun_set_name(usb_dev->fun, buf); 548 } 549 550 static int usb_dev_explore(hcd_t *hcd, usb_dev_t *usb_dev) 407 int hcd_ddf_device_explore(hcd_t *hcd, device_t *device) 551 408 { 552 409 int err; … … 556 413 init_match_ids(&mids); 557 414 558 usb_target_t control_ep = { 559 .address = usb_dev->address,415 usb_target_t control_ep = {{ 416 .address = device->address, 560 417 .endpoint = 0 561 } ;418 }}; 562 419 563 420 /* Get std device descriptor */ … … 566 423 567 424 usb_log_debug("Device(%d): Requesting full device descriptor.", 568 usb_dev->address);425 device->address); 569 426 ssize_t got = hcd_send_batch_sync(hcd, control_ep, USB_DIRECTION_IN, 570 427 &desc, sizeof(desc), *(uint64_t *)&get_device_desc, … … 573 430 err = got < 0 ? got : EOVERFLOW; 574 431 usb_log_error("Device(%d): Failed to set get dev descriptor: %s", 575 usb_dev->address, str_error(err));432 device->address, str_error(err)); 576 433 goto out; 577 434 } 578 435 579 436 /* Create match ids from the device descriptor */ 580 usb_log_debug("Device(%d): Creating match IDs.", usb_dev->address);437 usb_log_debug("Device(%d): Creating match IDs.", device->address); 581 438 if ((err = create_match_ids(&mids, &desc))) { 582 usb_log_error("Device(%d): Failed to create match ids: %s", usb_dev->address, str_error(err));439 usb_log_error("Device(%d): Failed to create match ids: %s", device->address, str_error(err)); 583 440 goto out; 584 441 } 585 442 586 443 list_foreach(mids.ids, link, const match_id_t, mid) { 587 ddf_fun_add_match_id( usb_dev->fun, mid->id, mid->score);444 ddf_fun_add_match_id(device->fun, mid->id, mid->score); 588 445 } 589 446 … … 593 450 } 594 451 595 static int hcd_address_device(hcd_t *hcd, usb_dev_t *usb_dev) 596 { 597 if (hcd->ops.address_device) 598 return hcd->ops.address_device(hcd, usb_dev->speed, usb_dev->tt, &usb_dev->address); 599 else 600 return hcd_usb2_address_device(hcd, usb_dev->speed, usb_dev->tt, &usb_dev->address); 601 } 602 603 static int hcd_ddf_new_device(hcd_t *hcd, ddf_dev_t *hc, usb_dev_t *hub_dev, unsigned port) 452 static int hcd_ddf_new_device(hcd_t *hcd, ddf_dev_t *hc, device_t *hub, unsigned port) 604 453 { 605 454 int err; 606 455 assert(hcd); 607 assert(hub_dev); 456 assert(hcd->bus); 457 assert(hub); 608 458 assert(hc); 609 459 610 usb_speed_t speed = USB_SPEED_MAX; 611 /* The speed of the new device was reported by the hub when reserving 612 * default address. 460 device_t *dev = hcd_ddf_device_create(hc, hcd->bus->device_size); 461 if (!dev) { 462 usb_log_error("Failed to create USB device function."); 463 return ENOMEM; 464 } 465 466 dev->hub = hub; 467 dev->port = port; 468 469 if ((err = bus_enumerate_device(hcd->bus, hcd, dev))) { 470 usb_log_error("Failed to initialize USB dev memory structures."); 471 return err; 472 } 473 474 /* If the driver didn't name the dev when enumerating, 475 * do it in some generic way. 613 476 */ 614 if ((err = bus_get_speed(hcd->bus, USB_ADDRESS_DEFAULT, &speed))) { 615 usb_log_error("Failed to verify speed: %s.", str_error(err)); 616 return err; 617 } 618 usb_log_debug("Found new %s speed USB device.", usb_str_speed(speed)); 619 620 usb_dev_t *usb_dev = usb_dev_create(hc, speed); 621 if (!usb_dev) { 622 usb_log_error("Failed to create USB device function."); 623 return err; 624 } 625 626 /* For devices under HS hub */ 627 /* TODO: How about SS hubs? */ 628 if (hub_dev->speed == USB_SPEED_HIGH && usb_speed_is_11(speed)) { 629 usb_dev->tt.address = hub_dev->address; 630 } 631 else { 632 /* Inherit hub's TT */ 633 usb_dev->tt.address = hub_dev->tt.address; 634 } 635 usb_dev->tt.port = port; 636 637 /* Assign an address to the device */ 638 if ((err = hcd_address_device(hcd, usb_dev))) { 639 usb_log_error("Failed to setup address of the new device: %s", str_error(err)); 477 if (!ddf_fun_get_name(dev->fun)) { 478 device_set_default_name(dev); 479 } 480 481 if ((err = ddf_fun_bind(dev->fun))) { 482 usb_log_error("Device(%d): Failed to register: %s.", dev->address, str_error(err)); 640 483 goto err_usb_dev; 641 484 } 642 485 643 /* Read the device descriptor, derive the match ids */ 644 if ((err = usb_dev_explore(hcd, usb_dev))) { 645 usb_log_error("Device(%d): Failed to explore device: %s", usb_dev->address, str_error(err)); 646 goto err_usb_dev; 647 } 648 649 /* If the driver didn't name the device when addressing/exploring, 650 * do it insome generic way. 651 */ 652 if (!ddf_fun_get_name(usb_dev->fun)) { 653 usb_dev_set_default_name(usb_dev); 654 } 655 656 if ((err = ddf_fun_bind(usb_dev->fun))) { 657 usb_log_error("Device(%d): Failed to register: %s.", usb_dev->address, str_error(err)); 658 goto err_usb_dev; 659 } 660 661 fibril_mutex_lock(&hub_dev->guard); 662 list_append(&usb_dev->link, &hub_dev->devices); 663 fibril_mutex_unlock(&hub_dev->guard); 486 fibril_mutex_lock(&hub->guard); 487 list_append(&dev->link, &hub->devices); 488 fibril_mutex_unlock(&hub->guard); 664 489 665 490 return EOK; 666 491 667 492 err_usb_dev: 668 usb_dev_destroy(usb_dev);493 hcd_ddf_device_destroy(dev); 669 494 return err; 670 495 } … … 681 506 assert(hc); 682 507 assert(hcd); 683 684 if ((err = hcd_reserve_default_address(hcd, USB_SPEED_MAX))) { 508 assert(hcd->bus); 509 510 if ((err = bus_reserve_default_address(hcd->bus, USB_SPEED_MAX))) { 685 511 usb_log_error("Failed to reserve default address for roothub setup: %s", str_error(err)); 686 512 return err; 687 513 } 688 514 689 usb_dev_t *usb_dev = usb_dev_create(hc, USB_SPEED_MAX);690 if (! usb_dev) {515 device_t *dev = hcd_ddf_device_create(hc, USB_SPEED_MAX); 516 if (!dev) { 691 517 usb_log_error("Failed to create function for the root hub."); 692 518 goto err_default_address; 693 519 } 694 520 695 usb_dev->tt.address = -1; 696 usb_dev->tt.port = 0; 521 ddf_fun_set_name(dev->fun, "roothub"); 522 523 dev->tt = (usb_tt_address_t) { 524 .address = -1, 525 .port = 0, 526 }; 697 527 698 528 /* Assign an address to the device */ 699 if ((err = hcd_address_device(hcd, usb_dev))) {700 usb_log_error("Failed to setup roothub address: %s", str_error(err));529 if ((err = bus_enumerate_device(hcd->bus, hcd, dev))) { 530 usb_log_error("Failed to enumerate roothub device: %s", str_error(err)); 701 531 goto err_usb_dev; 702 532 } 703 533 704 /* Read the device descriptor, derive the match ids */ 705 if ((err = usb_dev_explore(hcd, usb_dev))) { 706 usb_log_error("Failed to explore roothub: %s", str_error(err)); 707 goto err_usb_dev; 708 } 709 710 ddf_fun_set_name(usb_dev->fun, "roothub"); 711 712 if ((err = ddf_fun_bind(usb_dev->fun))) { 534 if ((err = ddf_fun_bind(dev->fun))) { 713 535 usb_log_error("Failed to register roothub: %s.", str_error(err)); 714 536 goto err_usb_dev; 715 537 } 716 538 717 hcd_release_default_address(hcd);539 bus_release_default_address(hcd->bus); 718 540 return EOK; 719 541 720 542 err_usb_dev: 721 usb_dev_destroy(usb_dev);543 hcd_ddf_device_destroy(dev); 722 544 err_default_address: 723 hcd_release_default_address(hcd);545 bus_release_default_address(hcd->bus); 724 546 return err; 725 547 } … … 1043 865 } 1044 866 1045 struct hcd_roothub {1046 hcd_t *hcd;1047 ddf_dev_t *hc_dev;1048 usb_dev_t rh_usb;1049 };1050 1051 hcd_roothub_t *hcd_roothub_create(hcd_t *hcd, ddf_dev_t *dev, usb_speed_t speed)1052 {1053 hcd_roothub_t *rh = malloc(sizeof(*rh));1054 1055 rh->hcd = hcd;1056 rh->hc_dev = dev;1057 usb_dev_init(&rh->rh_usb, speed);1058 1059 rh->rh_usb.tt.address = -1;1060 return rh;1061 }1062 1063 int hcd_roothub_new_device(hcd_roothub_t *rh, unsigned port) {1064 return hcd_ddf_new_device(rh->hcd, rh->hc_dev, &rh->rh_usb, port);1065 }1066 867 /** 1067 868 * @} -
uspace/lib/usbhost/src/hcd.c
r867b375 r20eaa82 45 45 46 46 47 /*[>* Calls ep_add_hook upon endpoint registration.48 * @param ep Endpoint to be registered.49 * @param arg hcd_t in disguise.50 * @return Error code.51 * OH TODO: remove52 <]53 static int register_helper(endpoint_t *ep, void *arg)54 {55 hcd_t *hcd = arg;56 assert(ep);57 assert(hcd);58 if (hcd->ops.ep_add_hook)59 return hcd->ops.ep_add_hook(hcd, ep);60 return EOK;61 }62 63 [>* Calls ep_remove_hook upon endpoint removal.64 * @param ep Endpoint to be unregistered.65 * @param arg hcd_t in disguise.66 * OH TODO: remove67 <]68 static void unregister_helper(endpoint_t *ep, void *arg)69 {70 hcd_t *hcd = arg;71 assert(ep);72 assert(hcd);73 if (hcd->ops.ep_remove_hook)74 hcd->ops.ep_remove_hook(hcd, ep);75 }76 77 [>* Calls ep_remove_hook upon endpoint removal. Prints warning.78 * * @param ep Endpoint to be unregistered.79 * * @param arg hcd_t in disguise.80 * OH TODO: remove81 * <]82 static void unregister_helper_warn(endpoint_t *ep, void *arg)83 {84 assert(ep);85 usb_log_warning("Endpoint %d:%d %s was left behind, removing.\n",86 ep->target.address, ep->target.endpoint, usb_str_direction(ep->direction));87 unregister_helper(ep, arg);88 }89 */90 91 47 /** Initialize hcd_t structure. 92 48 * Initializes device and endpoint managers. Sets data and hook pointer to NULL. … … 112 68 return address; 113 69 } 114 115 int hcd_release_address(hcd_t *hcd, usb_address_t address)116 {117 assert(hcd);118 return bus_release_address(hcd->bus, address);119 // OH TODO removed helper120 }121 122 int hcd_reserve_default_address(hcd_t *hcd, usb_speed_t speed)123 {124 assert(hcd);125 usb_address_t address = 0;126 return bus_request_address(hcd->bus, &address, true, speed);127 }128 129 int hcd_add_ep(hcd_t *hcd, usb_target_t target, usb_direction_t dir,130 usb_transfer_type_t type, size_t max_packet_size, unsigned packets,131 size_t size, usb_tt_address_t tt)132 {133 assert(hcd);134 135 /* Temporary reference */136 endpoint_t *ep = bus_create_endpoint(hcd->bus);137 if (!ep)138 return ENOMEM;139 140 ep->target = target;141 ep->direction = dir;142 ep->transfer_type = type;143 ep->max_packet_size = max_packet_size;144 ep->packets = packets;145 ep->tt = tt;146 147 ep->bandwidth = bus_count_bw(ep, size);148 149 const int err = bus_register_endpoint(hcd->bus, ep);150 151 /* drop Temporary reference */152 endpoint_del_ref(ep);153 154 return err;155 }156 157 int hcd_remove_ep(hcd_t *hcd, usb_target_t target, usb_direction_t dir)158 {159 assert(hcd);160 endpoint_t *ep = bus_find_endpoint(hcd->bus, target, dir);161 if (!ep)162 return ENOENT;163 164 return bus_release_endpoint(hcd->bus, ep);165 // OH TODO removed helper166 }167 168 70 169 71 typedef struct { -
uspace/lib/usbhost/src/usb2_bus.c
r867b375 r20eaa82 36 36 #include <usb/host/usb2_bus.h> 37 37 #include <usb/host/endpoint.h> 38 #include <usb/host/ddf_helpers.h> 38 39 #include <usb/debug.h> 40 #include <usb/request.h> 41 #include <usb/descriptor.h> 42 #include <usb/usb.h> 39 43 40 44 #include <assert.h> 41 45 #include <errno.h> 42 46 #include <macros.h> 47 #include <str_error.h> 43 48 #include <stdlib.h> 44 49 #include <stdbool.h> … … 61 66 assert(addr >= 0); 62 67 return &bus->devices[addr % ARRAY_SIZE(bus->devices)].endpoint_list; 68 } 69 70 /** Get speed assigned to USB address. 71 * 72 * @param[in] bus Device manager structure to use. 73 * @param[in] address Address the caller wants to find. 74 * @param[out] speed Assigned speed. 75 * @return Error code. 76 */ 77 static int usb2_bus_get_speed(bus_t *bus_base, usb_address_t address, usb_speed_t *speed) 78 { 79 usb2_bus_t *bus = bus_to_usb2_bus(bus_base); 80 81 if (!usb_address_is_valid(address)) { 82 return EINVAL; 83 } 84 85 const int ret = bus->devices[address].occupied ? EOK : ENOENT; 86 if (speed && bus->devices[address].occupied) { 87 *speed = bus->devices[address].speed; 88 } 89 90 return ret; 91 } 92 93 static int usb2_bus_address_device(bus_t *bus, hcd_t *hcd, device_t *dev) 94 { 95 int err; 96 97 static const usb_target_t default_target = {{ 98 .address = USB_ADDRESS_DEFAULT, 99 .endpoint = 0, 100 }}; 101 102 /** Reserve address early, we want pretty log messages */ 103 const usb_address_t address = bus_reserve_default_address(bus, dev->speed); 104 if (address < 0) { 105 usb_log_error("Failed to reserve new address: %s.", 106 str_error(address)); 107 return address; 108 } 109 usb_log_debug("Device(%d): Reserved new address.", address); 110 111 /* Add default pipe on default address */ 112 usb_log_debug("Device(%d): Adding default target (0:0)", address); 113 err = bus_add_ep(bus, dev, 0, USB_DIRECTION_BOTH, USB_TRANSFER_CONTROL, 114 CTRL_PIPE_MIN_PACKET_SIZE, CTRL_PIPE_MIN_PACKET_SIZE, 1); 115 if (err != EOK) { 116 usb_log_error("Device(%d): Failed to add default target: %s.", 117 address, str_error(err)); 118 goto err_address; 119 } 120 121 /* Get max packet size for default pipe */ 122 usb_standard_device_descriptor_t desc = { 0 }; 123 const usb_device_request_setup_packet_t get_device_desc_8 = 124 GET_DEVICE_DESC(CTRL_PIPE_MIN_PACKET_SIZE); 125 126 usb_log_debug("Device(%d): Requesting first 8B of device descriptor.", 127 address); 128 ssize_t got = hcd_send_batch_sync(hcd, default_target, USB_DIRECTION_IN, 129 &desc, CTRL_PIPE_MIN_PACKET_SIZE, *(uint64_t *)&get_device_desc_8, 130 "read first 8 bytes of dev descriptor"); 131 132 if (got != CTRL_PIPE_MIN_PACKET_SIZE) { 133 err = got < 0 ? got : EOVERFLOW; 134 usb_log_error("Device(%d): Failed to get 8B of dev descr: %s.", 135 address, str_error(err)); 136 goto err_default_target; 137 } 138 139 /* Set new address */ 140 const usb_device_request_setup_packet_t set_address = SET_ADDRESS(address); 141 142 usb_log_debug("Device(%d): Setting USB address.", address); 143 err = hcd_send_batch_sync(hcd, default_target, USB_DIRECTION_OUT, 144 NULL, 0, *(uint64_t *)&set_address, "set address"); 145 if (err != 0) { 146 usb_log_error("Device(%d): Failed to set new address: %s.", 147 address, str_error(got)); 148 goto err_default_target; 149 } 150 151 dev->address = address; 152 153 /* Register EP on the new address */ 154 usb_log_debug("Device(%d): Registering control EP.", address); 155 err = bus_add_ep(bus, dev, 0, USB_DIRECTION_BOTH, USB_TRANSFER_CONTROL, 156 ED_MPS_PACKET_SIZE_GET(uint16_usb2host(desc.max_packet_size)), 157 ED_MPS_TRANS_OPPORTUNITIES_GET(uint16_usb2host(desc.max_packet_size)), 158 ED_MPS_PACKET_SIZE_GET(uint16_usb2host(desc.max_packet_size))); 159 if (err != EOK) { 160 usb_log_error("Device(%d): Failed to register EP0: %s", 161 address, str_error(err)); 162 goto err_default_target; 163 } 164 165 bus_remove_ep(bus, default_target, USB_DIRECTION_BOTH); 166 return EOK; 167 168 err_default_target: 169 bus_remove_ep(bus, default_target, USB_DIRECTION_BOTH); 170 err_address: 171 bus_release_address(bus, address); 172 return err; 173 } 174 175 /** Enumerate a new USB device 176 */ 177 static int usb2_bus_enumerate_device(bus_t *bus, hcd_t *hcd, device_t *dev) 178 { 179 int err; 180 181 /* The speed of the new device was reported by the hub when reserving 182 * default address. 183 */ 184 if ((err = usb2_bus_get_speed(bus, USB_ADDRESS_DEFAULT, &dev->speed))) { 185 usb_log_error("Failed to verify speed: %s.", str_error(err)); 186 return err; 187 } 188 usb_log_debug("Found new %s speed USB device.", usb_str_speed(dev->speed)); 189 190 /* Manage TT */ 191 if (dev->hub->speed == USB_SPEED_HIGH && usb_speed_is_11(dev->speed)) { 192 /* For LS devices under HS hub */ 193 /* TODO: How about SS hubs? */ 194 dev->tt.address = dev->hub->address; 195 dev->tt.port = dev->port; 196 } 197 else { 198 /* Inherit hub's TT */ 199 dev->tt = dev->hub->tt; 200 } 201 202 /* Assign an address to the device */ 203 if ((err = usb2_bus_address_device(bus, hcd, dev))) { 204 usb_log_error("Failed to setup address of the new device: %s", str_error(err)); 205 return err; 206 } 207 208 /* Read the device descriptor, derive the match ids */ 209 if ((err = hcd_ddf_device_explore(hcd, dev))) { 210 usb_log_error("Device(%d): Failed to explore device: %s", dev->address, str_error(err)); 211 bus_release_address(bus, dev->address); 212 return err; 213 } 214 215 return EOK; 63 216 } 64 217 … … 190 343 * @param endpoint USB endpoint number. 191 344 * @param direction Communication direction. 192 * @param callback Function to call after unregister, before destruction.193 * @arg Argument to pass to the callback function.194 345 * @return Error code. 195 346 */ … … 211 362 list_remove(&ep->link); 212 363 364 usb_log_warning("Endpoint %d:%d %s was left behind, removing.\n", 365 ep->target.address, ep->target.endpoint, usb_str_direction(ep->direction)); 366 213 367 /* Drop bus reference */ 214 368 endpoint_del_ref(ep); … … 258 412 } 259 413 260 /** Get speed assigned to USB address.261 *262 * @param[in] bus Device manager structure to use.263 * @param[in] address Address the caller wants to find.264 * @param[out] speed Assigned speed.265 * @return Error code.266 */267 static int usb2_bus_get_speed(bus_t *bus_base, usb_address_t address, usb_speed_t *speed)268 {269 usb2_bus_t *bus = bus_to_usb2_bus(bus_base);270 271 if (!usb_address_is_valid(address)) {272 return EINVAL;273 }274 275 const int ret = bus->devices[address].occupied ? EOK : ENOENT;276 if (speed && bus->devices[address].occupied) {277 *speed = bus->devices[address].speed;278 }279 280 return ret;281 }282 283 414 static const bus_ops_t usb2_bus_ops = { 415 .enumerate_device = usb2_bus_enumerate_device, 284 416 .create_endpoint = usb2_bus_create_ep, 285 417 .find_endpoint = usb2_bus_find_ep, … … 289 421 .release_address = usb2_bus_release_address, 290 422 .reset_toggle = usb2_bus_reset_toggle, 291 .get_speed = usb2_bus_get_speed,292 423 }; 293 424 … … 303 434 assert(bus); 304 435 305 bus_init(&bus->base );436 bus_init(&bus->base, sizeof(device_t)); 306 437 307 438 bus->base.ops = usb2_bus_ops;
Note:
See TracChangeset
for help on using the changeset viewer.