Changeset 6832245 in mainline for uspace/lib/usbhost
- Timestamp:
- 2017-12-14T23:01:57Z (8 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 837d53d
- Parents:
- bd05140
- git-author:
- Ondřej Hlavatý <aearsis@…> (2017-12-14 23:01:54)
- git-committer:
- Ondřej Hlavatý <aearsis@…> (2017-12-14 23:01:57)
- Location:
- uspace/lib/usbhost
- Files:
-
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/usbhost/include/usb/host/bandwidth.h
rbd05140 r6832245 51 51 typedef struct endpoint endpoint_t; 52 52 53 extern s ize_t bandwidth_count_usb11(endpoint_t *, size_t);53 extern ssize_t bandwidth_count_usb11(endpoint_t *, size_t); 54 54 55 extern s ize_t bandwidth_count_usb20(endpoint_t *, size_t);55 extern ssize_t bandwidth_count_usb20(endpoint_t *, size_t); 56 56 57 57 #endif -
uspace/lib/usbhost/include/usb/host/bus.h
rbd05140 r6832245 77 77 usb_address_t address; 78 78 79 /* Managing bus */ 80 bus_t *bus; 81 79 82 /* This structure is meant to be extended by overriding. */ 80 83 } device_t; 81 84 82 typedef struct { 83 int (*enumerate_device)(bus_t *, hcd_t *, device_t *); 84 int (*remove_device)(bus_t *, hcd_t *, device_t *); 85 typedef struct bus_ops bus_ops_t; 85 86 86 int (*online_device)(bus_t *, hcd_t *, device_t *); /**< Optional */ 87 int (*offline_device)(bus_t *, hcd_t *, device_t *); /**< Optional */ 87 /** 88 * Operations structure serving as an interface of hc driver for the library 89 * (and the rest of the system). 90 */ 91 struct bus_ops { 92 /* Undefined operations will be delegated to parent ops */ 93 const bus_ops_t *parent; 88 94 89 /* The following operations are protected by a bus guard. */ 90 endpoint_t *(*create_endpoint)(bus_t *); 91 int (*register_endpoint)(bus_t *, device_t *, endpoint_t *, const usb_endpoint_desc_t *); 92 int (*unregister_endpoint)(bus_t *, endpoint_t *); 93 endpoint_t *(*find_endpoint)(bus_t *, device_t*, usb_target_t, usb_direction_t); 94 void (*destroy_endpoint)(endpoint_t *); /**< Optional */ 95 /* Global operations on the bus */ 96 int (*reserve_default_address)(bus_t *, usb_speed_t); 97 int (*release_default_address)(bus_t *); 98 int (*reset_toggle)(bus_t *, usb_target_t, toggle_reset_mode_t); 99 100 /* Operations on device */ 101 int (*device_enumerate)(device_t *); 102 int (*device_remove)(device_t *); 103 int (*device_online)(device_t *); /**< Optional */ 104 int (*device_offline)(device_t *); /**< Optional */ 105 endpoint_t *(*device_find_endpoint)(device_t*, usb_target_t, usb_direction_t); 106 endpoint_t *(*endpoint_create)(device_t *, const usb_endpoint_desc_t *); 107 108 /* Operations on endpoint */ 109 int (*endpoint_register)(endpoint_t *); 110 int (*endpoint_unregister)(endpoint_t *); 111 void (*endpoint_destroy)(endpoint_t *); /**< Optional */ 95 112 bool (*endpoint_get_toggle)(endpoint_t *); /**< Optional */ 96 113 void (*endpoint_set_toggle)(endpoint_t *, bool); /**< Optional */ 114 ssize_t (*endpoint_count_bw) (endpoint_t *, size_t); 115 usb_transfer_batch_t *(*batch_create)(endpoint_t *); /**< Optional */ 97 116 98 int (*reserve_default_address)(bus_t *, usb_speed_t); 99 int (*release_default_address)(bus_t *); 117 /* Operations on batch */ 118 void (*batch_destroy)(usb_transfer_batch_t *); /**< Optional */ 119 }; 100 120 101 int (*reset_toggle)(bus_t *, usb_target_t, toggle_reset_mode_t); 102 103 size_t (*count_bw) (endpoint_t *, size_t); 104 105 usb_transfer_batch_t *(*create_batch)(bus_t *, endpoint_t *); /**< Optional */ 106 void (*destroy_batch)(usb_transfer_batch_t *); /**< Optional */ 107 } bus_ops_t; 121 /** 122 * Use this macro to lookup virtual function. 123 */ 124 #define BUS_OPS_LOOKUP(start, fn) ({ bus_ops_t const * ops = (start); while (ops && ops->fn == NULL) ops = ops->parent; ops; }) 108 125 109 126 /** Endpoint management structure */ … … 112 129 fibril_mutex_t guard; 113 130 131 /* TODO: get rid of this one. */ 132 hcd_t *hcd; 133 114 134 size_t device_size; 115 135 116 136 /* Do not call directly, ops are synchronized. */ 117 bus_ops_tops;137 const bus_ops_t *ops; 118 138 119 139 /* This structure is meant to be extended by overriding. */ 120 140 } bus_t; 121 141 122 void bus_init(bus_t *, size_t);123 int device_init(device_t *);142 void bus_init(bus_t *, hcd_t *, size_t); 143 int bus_device_init(device_t *, bus_t *); 124 144 125 int device_set_default_name(device_t *);145 int bus_device_set_default_name(device_t *); 126 146 127 int bus_ enumerate_device(bus_t *, hcd_t *,device_t *);128 int bus_ remove_device(bus_t *, hcd_t *,device_t *);147 int bus_device_enumerate(device_t *); 148 int bus_device_remove(device_t *); 129 149 130 int bus_ online_device(bus_t *, hcd_t *,device_t *);131 int bus_ offline_device(bus_t *, hcd_t *,device_t *);150 int bus_device_online(device_t *); 151 int bus_device_offline(device_t *); 132 152 133 int bus_add_endpoint(bus_t *, device_t *, const usb_endpoint_desc_t *, endpoint_t **); 134 endpoint_t *bus_find_endpoint(bus_t *, device_t *, usb_target_t, usb_direction_t); 135 int bus_remove_endpoint(bus_t *, endpoint_t *); 136 137 size_t bus_count_bw(endpoint_t *, size_t); 153 int bus_endpoint_add(device_t *, const usb_endpoint_desc_t *, endpoint_t **); 154 endpoint_t *bus_find_endpoint(device_t *, usb_target_t, usb_direction_t); 155 int bus_endpoint_remove(endpoint_t *); 138 156 139 157 int bus_reserve_default_address(bus_t *, usb_speed_t); -
uspace/lib/usbhost/include/usb/host/ddf_helpers.h
rbd05140 r6832245 81 81 int hcd_setup_virtual_root_hub(hcd_t *, ddf_dev_t *); 82 82 83 device_t *hcd_ddf_device_create(ddf_dev_t *, size_t);83 device_t *hcd_ddf_device_create(ddf_dev_t *, bus_t *); 84 84 void hcd_ddf_device_destroy(device_t *); 85 int hcd_ddf_device_explore( hcd_t *,device_t *);85 int hcd_ddf_device_explore(device_t *); 86 86 int hcd_ddf_device_online(ddf_fun_t *); 87 87 int hcd_ddf_device_offline(ddf_fun_t *); -
uspace/lib/usbhost/include/usb/host/endpoint.h
rbd05140 r6832245 45 45 #include <stdbool.h> 46 46 #include <usb/usb.h> 47 #include <usb/host/bus.h> 47 48 48 49 typedef struct bus bus_t; … … 54 55 /** Part of linked list. */ 55 56 link_t link; 56 /** Managing bus*/57 bus_t *bus;57 /** USB device */ 58 device_t *device; 58 59 /** Reference count. */ 59 60 atomic_t refcnt; 60 /** USB device */61 device_t *device;62 61 /** Enpoint number */ 63 62 usb_endpoint_t endpoint; … … 84 83 } endpoint_t; 85 84 86 extern void endpoint_init(endpoint_t *, bus_t *);85 extern void endpoint_init(endpoint_t *, device_t *, const usb_endpoint_desc_t *); 87 86 88 87 extern void endpoint_add_ref(endpoint_t *); … … 103 102 void endpoint_abort(endpoint_t *); 104 103 104 /* Manage the toggle bit */ 105 105 extern int endpoint_toggle_get(endpoint_t *); 106 106 extern void endpoint_toggle_set(endpoint_t *, bool); 107 108 /* Calculate bandwidth */ 109 ssize_t endpoint_count_bw(endpoint_t *, size_t); 110 111 static inline bus_t *endpoint_get_bus(endpoint_t *ep) 112 { 113 return ep->device->bus; 114 } 107 115 108 116 /** list_get_instance wrapper. -
uspace/lib/usbhost/include/usb/host/usb2_bus.h
rbd05140 r6832245 46 46 typedef struct endpoint endpoint_t; 47 47 48 typedef size_t (*count_bw_func_t)(endpoint_t *, size_t);49 50 48 /** Endpoint management structure */ 51 49 typedef struct usb2_bus { … … 66 64 } usb2_bus_t; 67 65 68 extern int usb2_bus_init(usb2_bus_t *, size_t, count_bw_func_t); 66 extern const bus_ops_t usb2_bus_ops; 67 68 extern int usb2_bus_init(usb2_bus_t *, hcd_t *, size_t); 69 69 70 70 #endif -
uspace/lib/usbhost/src/bandwidth.c
rbd05140 r6832245 48 48 * @param max_packet_size Maximum bytes in one packet. 49 49 */ 50 s ize_t bandwidth_count_usb11(endpoint_t *ep, size_t size)50 ssize_t bandwidth_count_usb11(endpoint_t *ep, size_t size) 51 51 { 52 52 assert(ep); … … 102 102 * @param max_packet_size Maximum bytes in one packet. 103 103 */ 104 s ize_t bandwidth_count_usb20(endpoint_t *ep, size_t size)104 ssize_t bandwidth_count_usb20(endpoint_t *ep, size_t size) 105 105 { 106 106 assert(ep); -
uspace/lib/usbhost/src/bus.c
rbd05140 r6832245 46 46 * Initializes the bus structure. 47 47 */ 48 void bus_init(bus_t *bus, size_t device_size) 49 { 50 assert(bus); 48 void bus_init(bus_t *bus, hcd_t *hcd, size_t device_size) 49 { 50 assert(bus); 51 assert(hcd); 51 52 assert(device_size >= sizeof(device_t)); 52 53 memset(bus, 0, sizeof(bus_t)); 53 54 54 55 fibril_mutex_initialize(&bus->guard); 56 bus->hcd = hcd; 55 57 bus->device_size = device_size; 56 58 } 57 59 58 int device_init(device_t *dev) 59 { 60 int bus_device_init(device_t *dev, bus_t *bus) 61 { 62 assert(bus); 63 assert(bus->hcd); 64 60 65 memset(dev, 0, sizeof(*dev)); 66 67 dev->bus = bus; 61 68 62 69 link_initialize(&dev->link); … … 67 74 } 68 75 69 int device_set_default_name(device_t *dev)76 int bus_device_set_default_name(device_t *dev) 70 77 { 71 78 assert(dev); … … 79 86 } 80 87 81 int bus_enumerate_device(bus_t *bus, hcd_t *hcd, device_t *dev) 82 { 83 assert(bus); 84 assert(hcd); 85 assert(dev); 86 87 if (!bus->ops.enumerate_device) 88 return ENOTSUP; 89 90 return bus->ops.enumerate_device(bus, hcd, dev); 91 } 92 93 int bus_remove_device(bus_t *bus, hcd_t *hcd, device_t *dev) 94 { 95 assert(bus); 96 assert(dev); 97 98 if (!bus->ops.remove_device) 99 return ENOTSUP; 100 101 return bus->ops.remove_device(bus, hcd, dev); 102 } 103 104 int bus_online_device(bus_t *bus, hcd_t *hcd, device_t *dev) 105 { 106 assert(bus); 107 assert(hcd); 108 assert(dev); 109 110 if (!bus->ops.online_device) 111 return ENOTSUP; 112 113 return bus->ops.online_device(bus, hcd, dev); 114 } 115 116 int bus_offline_device(bus_t *bus, hcd_t *hcd, device_t *dev) 117 { 118 assert(bus); 119 assert(hcd); 120 assert(dev); 121 122 if (!bus->ops.offline_device) 123 return ENOTSUP; 124 125 return bus->ops.offline_device(bus, hcd, dev); 126 } 127 128 int bus_add_endpoint(bus_t *bus, device_t *device, const usb_endpoint_desc_t *desc, endpoint_t **out_ep) 129 { 130 assert(bus); 88 int bus_device_enumerate(device_t *dev) 89 { 90 assert(dev); 91 92 const bus_ops_t *ops = BUS_OPS_LOOKUP(dev->bus->ops, device_enumerate); 93 if (!ops) 94 return ENOTSUP; 95 96 return ops->device_enumerate(dev); 97 } 98 99 int bus_device_remove(device_t *dev) 100 { 101 assert(dev); 102 103 const bus_ops_t *ops = BUS_OPS_LOOKUP(dev->bus->ops, device_remove); 104 105 if (!ops) 106 return ENOTSUP; 107 108 return ops->device_remove(dev); 109 } 110 111 int bus_device_online(device_t *dev) 112 { 113 assert(dev); 114 115 const bus_ops_t *ops = BUS_OPS_LOOKUP(dev->bus->ops, device_online); 116 if (!ops) 117 return ENOTSUP; 118 119 return ops->device_online(dev); 120 } 121 122 int bus_device_offline(device_t *dev) 123 { 124 assert(dev); 125 126 const bus_ops_t *ops = BUS_OPS_LOOKUP(dev->bus->ops, device_offline); 127 if (!ops) 128 return ENOTSUP; 129 130 return ops->device_offline(dev); 131 } 132 133 int bus_endpoint_add(device_t *device, const usb_endpoint_desc_t *desc, endpoint_t **out_ep) 134 { 135 int err; 131 136 assert(device); 137 138 bus_t *bus = device->bus; 132 139 133 140 if (desc->max_packet_size == 0 || desc->packets == 0) { … … 136 143 } 137 144 138 fibril_mutex_lock(&bus->guard); 139 140 int err = ENOMEM; 141 endpoint_t *ep = bus->ops.create_endpoint(bus); 145 const bus_ops_t *create_ops = BUS_OPS_LOOKUP(bus->ops, endpoint_create); 146 const bus_ops_t *register_ops = BUS_OPS_LOOKUP(bus->ops, endpoint_register); 147 if (!create_ops || !register_ops) 148 return ENOTSUP; 149 150 endpoint_t *ep = create_ops->endpoint_create(device, desc); 142 151 if (!ep) 143 goto err;144 145 /* Busreference */152 return ENOMEM; 153 154 /* Temporary reference */ 146 155 endpoint_add_ref(ep); 147 156 148 if ((err = bus->ops.register_endpoint(bus, device, ep, desc))) 149 goto err_ep; 157 fibril_mutex_lock(&bus->guard); 158 err = register_ops->endpoint_register(ep); 159 fibril_mutex_unlock(&bus->guard); 150 160 151 161 if (out_ep) { 162 /* Exporting reference */ 152 163 endpoint_add_ref(ep); 153 164 *out_ep = ep; 154 165 } 155 166 156 fibril_mutex_unlock(&bus->guard); 157 return EOK; 158 159 err_ep: 167 /* Temporary reference */ 160 168 endpoint_del_ref(ep); 161 err:162 fibril_mutex_unlock(&bus->guard);163 169 return err; 164 170 } … … 166 172 /** Searches for an endpoint. Returns a reference. 167 173 */ 168 endpoint_t *bus_find_endpoint(bus_t *bus, device_t *device, usb_target_t endpoint, usb_direction_t dir) 169 { 170 assert(bus); 171 172 fibril_mutex_lock(&bus->guard); 173 endpoint_t *ep = bus->ops.find_endpoint(bus, device, endpoint, dir); 174 endpoint_t *bus_find_endpoint(device_t *device, usb_target_t endpoint, usb_direction_t dir) 175 { 176 assert(device); 177 178 bus_t *bus = device->bus; 179 180 const bus_ops_t *ops = BUS_OPS_LOOKUP(bus->ops, device_find_endpoint); 181 if (!ops) 182 return NULL; 183 184 fibril_mutex_lock(&bus->guard); 185 endpoint_t *ep = ops->device_find_endpoint(device, endpoint, dir); 174 186 if (ep) { 175 187 /* Exporting reference */ … … 181 193 } 182 194 183 int bus_remove_endpoint(bus_t *bus, endpoint_t *ep) 184 { 185 assert(bus); 195 int bus_endpoint_remove(endpoint_t *ep) 196 { 186 197 assert(ep); 187 198 188 fibril_mutex_lock(&bus->guard); 189 const int r = bus->ops.unregister_endpoint(bus, ep); 199 bus_t *bus = endpoint_get_bus(ep); 200 201 const bus_ops_t *ops = BUS_OPS_LOOKUP(ep->device->bus->ops, endpoint_unregister); 202 if (!ops) 203 return ENOTSUP; 204 205 fibril_mutex_lock(&bus->guard); 206 const int r = ops->endpoint_unregister(ep); 190 207 fibril_mutex_unlock(&bus->guard); 191 208 … … 203 220 assert(bus); 204 221 205 if (!bus->ops.reserve_default_address) 206 return ENOTSUP; 207 208 fibril_mutex_lock(&bus->guard); 209 const int r = bus->ops.reserve_default_address(bus, speed); 222 const bus_ops_t *ops = BUS_OPS_LOOKUP(bus->ops, reserve_default_address); 223 if (!ops) 224 return ENOTSUP; 225 226 fibril_mutex_lock(&bus->guard); 227 const int r = ops->reserve_default_address(bus, speed); 210 228 fibril_mutex_unlock(&bus->guard); 211 229 return r; … … 216 234 assert(bus); 217 235 218 /* If this op is not set, allow everything */219 if (! bus->ops.release_default_address)220 return ENOTSUP; 221 222 fibril_mutex_lock(&bus->guard); 223 const int r = bus->ops.release_default_address(bus);236 const bus_ops_t *ops = BUS_OPS_LOOKUP(bus->ops, release_default_address); 237 if (!ops) 238 return ENOTSUP; 239 240 fibril_mutex_lock(&bus->guard); 241 const int r = ops->release_default_address(bus); 224 242 fibril_mutex_unlock(&bus->guard); 225 243 return r; … … 230 248 assert(bus); 231 249 232 if (!bus->ops.reset_toggle) 233 return ENOTSUP; 234 235 fibril_mutex_lock(&bus->guard); 236 const int r = bus->ops.reset_toggle(bus, target, all); 250 const bus_ops_t *ops = BUS_OPS_LOOKUP(bus->ops, reset_toggle); 251 if (!ops) 252 return ENOTSUP; 253 254 fibril_mutex_lock(&bus->guard); 255 const int r = ops->reset_toggle(bus, target, all); 237 256 fibril_mutex_unlock(&bus->guard); 238 257 return r; 239 }240 241 size_t bus_count_bw(endpoint_t *ep, size_t size)242 {243 assert(ep);244 245 fibril_mutex_lock(&ep->guard);246 const size_t bw = ep->bus->ops.count_bw(ep, size);247 fibril_mutex_unlock(&ep->guard);248 return bw;249 258 } 250 259 -
uspace/lib/usbhost/src/ddf_helpers.c
rbd05140 r6832245 101 101 endpoint_desc->max_packet_size, endpoint_desc->usb2.polling_interval); 102 102 103 return bus_ add_endpoint(hcd->bus,dev, endpoint_desc, NULL);103 return bus_endpoint_add(dev, endpoint_desc, NULL); 104 104 } 105 105 … … 128 128 usb_str_direction(endpoint_desc->direction)); 129 129 130 endpoint_t *ep = bus_find_endpoint( hcd->bus,dev, target, endpoint_desc->direction);130 endpoint_t *ep = bus_find_endpoint(dev, target, endpoint_desc->direction); 131 131 if (!ep) 132 132 return ENOENT; 133 133 134 return bus_ remove_endpoint(hcd->bus,ep);134 return bus_endpoint_remove(ep); 135 135 } 136 136 … … 362 362 const int ret = ddf_fun_unbind(victim->fun); 363 363 if (ret == EOK) { 364 bus_ remove_device(hcd->bus, hcd,victim);364 bus_device_remove(victim); 365 365 ddf_fun_destroy(victim->fun); 366 366 } else { … … 374 374 } 375 375 376 device_t *hcd_ddf_device_create(ddf_dev_t *hc, size_t device_size)376 device_t *hcd_ddf_device_create(ddf_dev_t *hc, bus_t *bus) 377 377 { 378 378 /* Create DDF function for the new device */ … … 384 384 385 385 /* Create USB device node for the new device */ 386 device_t *dev = ddf_fun_data_alloc(fun, device_size);386 device_t *dev = ddf_fun_data_alloc(fun, bus->device_size); 387 387 if (!dev) { 388 388 ddf_fun_destroy(fun); … … 390 390 } 391 391 392 device_init(dev);392 bus_device_init(dev, bus); 393 393 dev->fun = fun; 394 394 return dev; … … 402 402 } 403 403 404 int hcd_ddf_device_explore( hcd_t *hcd,device_t *device)404 int hcd_ddf_device_explore(device_t *device) 405 405 { 406 406 int err; … … 421 421 usb_log_debug("Device(%d): Requesting full device descriptor.", 422 422 device->address); 423 ssize_t got = hcd_send_batch_sync( hcd, device, control_ep, USB_DIRECTION_IN,423 ssize_t got = hcd_send_batch_sync(device->bus->hcd, device, control_ep, USB_DIRECTION_IN, 424 424 (char *) &desc, sizeof(desc), *(uint64_t *)&get_device_desc, 425 425 "read device descriptor"); … … 458 458 usb_log_info("Device(%d): Requested to be brought online.", dev->address); 459 459 460 return bus_ online_device(hcd->bus, hcd,dev);460 return bus_device_online(dev); 461 461 } 462 462 … … 472 472 usb_log_info("Device(%d): Requested to be taken offline.", dev->address); 473 473 474 return bus_ offline_device(hcd->bus, hcd,dev);474 return bus_device_offline(dev); 475 475 } 476 476 … … 483 483 assert(hc); 484 484 485 device_t *dev = hcd_ddf_device_create(hc, hcd->bus ->device_size);485 device_t *dev = hcd_ddf_device_create(hc, hcd->bus); 486 486 if (!dev) { 487 487 usb_log_error("Failed to create USB device function."); … … 492 492 dev->port = port; 493 493 494 if ((err = bus_ enumerate_device(hcd->bus, hcd,dev))) {494 if ((err = bus_device_enumerate(dev))) { 495 495 usb_log_error("Failed to initialize USB dev memory structures."); 496 496 return err; … … 501 501 */ 502 502 if (!ddf_fun_get_name(dev->fun)) { 503 device_set_default_name(dev);503 bus_device_set_default_name(dev); 504 504 } 505 505 … … 538 538 } 539 539 540 device_t *dev = hcd_ddf_device_create(hc, hcd->bus ->device_size);540 device_t *dev = hcd_ddf_device_create(hc, hcd->bus); 541 541 if (!dev) { 542 542 usb_log_error("Failed to create function for the root hub."); … … 547 547 548 548 /* Assign an address to the device */ 549 if ((err = bus_ enumerate_device(hcd->bus, hcd,dev))) {549 if ((err = bus_device_enumerate(dev))) { 550 550 usb_log_error("Failed to enumerate roothub device: %s", str_error(err)); 551 551 goto err_usb_dev; -
uspace/lib/usbhost/src/endpoint.c
rbd05140 r6832245 47 47 /** Initialize provided endpoint structure. 48 48 */ 49 void endpoint_init(endpoint_t *ep, bus_t *bus)49 void endpoint_init(endpoint_t *ep, device_t *dev, const usb_endpoint_desc_t *desc) 50 50 { 51 51 memset(ep, 0, sizeof(endpoint_t)); 52 52 53 ep->bus = bus; 53 assert(dev); 54 ep->device = dev; 55 54 56 atomic_set(&ep->refcnt, 0); 55 57 link_initialize(&ep->link); 56 58 fibril_mutex_initialize(&ep->guard); 57 59 fibril_condvar_initialize(&ep->avail); 60 61 ep->endpoint = desc->endpoint_no; 62 ep->direction = desc->direction; 63 ep->transfer_type = desc->transfer_type; 64 ep->max_packet_size = desc->max_packet_size; 65 ep->packets = desc->packets; 66 67 ep->bandwidth = endpoint_count_bw(ep, desc->max_packet_size); 68 } 69 70 static inline const bus_ops_t *get_bus_ops(endpoint_t *ep) 71 { 72 return ep->device->bus->ops; 58 73 } 59 74 … … 63 78 } 64 79 80 static inline void endpoint_destroy(endpoint_t *ep) 81 { 82 const bus_ops_t *ops = BUS_OPS_LOOKUP(get_bus_ops(ep), endpoint_destroy); 83 if (ops) { 84 ops->endpoint_destroy(ep); 85 } else { 86 assert(ep->active_batch == NULL); 87 88 /* Assume mostly the eps will be allocated by malloc. */ 89 free(ep); 90 } 91 } 92 65 93 void endpoint_del_ref(endpoint_t *ep) 66 94 { 67 95 if (atomic_predec(&ep->refcnt) == 0) { 68 if (ep->bus->ops.destroy_endpoint) { 69 ep->bus->ops.destroy_endpoint(ep); 70 } 71 else { 72 assert(ep->active_batch == NULL); 73 74 /* Assume mostly the eps will be allocated by malloc. */ 75 free(ep); 76 } 96 endpoint_destroy(ep); 77 97 } 78 98 } … … 133 153 assert(ep); 134 154 135 return ep->bus->ops.endpoint_get_toggle 136 ? ep->bus->ops.endpoint_get_toggle(ep) 155 const bus_ops_t *ops = BUS_OPS_LOOKUP(get_bus_ops(ep), endpoint_get_toggle); 156 return ops 157 ? ops->endpoint_get_toggle(ep) 137 158 : ep->toggle; 138 159 } … … 146 167 assert(ep); 147 168 148 if (ep->bus->ops.endpoint_set_toggle) { 149 ep->bus->ops.endpoint_set_toggle(ep, toggle); 169 const bus_ops_t *ops = BUS_OPS_LOOKUP(get_bus_ops(ep), endpoint_set_toggle); 170 if (ops) { 171 ops->endpoint_set_toggle(ep, toggle); 150 172 } 151 173 else { … … 154 176 } 155 177 178 ssize_t endpoint_count_bw(endpoint_t *ep, size_t packet_size) 179 { 180 assert(ep); 181 182 const bus_ops_t *ops = BUS_OPS_LOOKUP(get_bus_ops(ep), endpoint_count_bw); 183 if (!ops) 184 return 0; 185 186 return ops->endpoint_count_bw(ep, packet_size); 187 } 188 156 189 /** 157 190 * @} -
uspace/lib/usbhost/src/hcd.c
rbd05140 r6832245 208 208 } 209 209 210 endpoint_t *ep = bus_find_endpoint( hcd->bus,device, target, direction);210 endpoint_t *ep = bus_find_endpoint(device, target, direction); 211 211 if (ep == NULL) { 212 212 usb_log_error("Endpoint(%d:%d) not registered for %s.\n", … … 216 216 217 217 // TODO cut here aka provide helper to call with instance of endpoint_t in hand 218 assert(ep->device == device); 218 219 219 220 usb_log_debug2("%s %d:%d %zu(%zu).\n", 220 221 name, target.address, target.endpoint, size, ep->max_packet_size); 221 222 222 const size_t bw = bus_count_bw(ep, size);223 const size_t bw = endpoint_count_bw(ep, size); 223 224 /* Check if we have enough bandwidth reserved */ 224 225 if (ep->bandwidth < bw) { -
uspace/lib/usbhost/src/usb2_bus.c
rbd05140 r6832245 200 200 }}; 201 201 202 static int address_device( usb2_bus_t *bus, hcd_t *hcd,device_t *dev)202 static int address_device(device_t *dev) 203 203 { 204 204 int err; 205 206 usb2_bus_t *bus = (usb2_bus_t *) dev->bus; 207 hcd_t *hcd = (hcd_t *) bus->base.hcd; 205 208 206 209 /* The default address is currently reserved for this device */ … … 220 223 221 224 endpoint_t *default_ep; 222 err = bus_ add_endpoint(&bus->base,dev, &usb2_default_control_ep, &default_ep);225 err = bus_endpoint_add(dev, &usb2_default_control_ep, &default_ep); 223 226 if (err != EOK) { 224 227 usb_log_error("Device(%d): Failed to add default target: %s.", … … 244 247 245 248 /* We need to remove ep before we change the address */ 246 if ((err = bus_ remove_endpoint(&bus->base,default_ep))) {249 if ((err = bus_endpoint_remove(default_ep))) { 247 250 usb_log_error("Device(%d): Failed to unregister default target: %s", address, str_error(err)); 248 251 goto err_address; … … 262 265 /* Register EP on the new address */ 263 266 usb_log_debug("Device(%d): Registering control EP.", address); 264 err = bus_ add_endpoint(&bus->base,dev, &control_ep, NULL);267 err = bus_endpoint_add(dev, &control_ep, NULL); 265 268 if (err != EOK) { 266 269 usb_log_error("Device(%d): Failed to register EP0: %s", … … 272 275 273 276 err_default_control_ep: 274 bus_ remove_endpoint(&bus->base,default_ep);277 bus_endpoint_remove(default_ep); 275 278 endpoint_del_ref(default_ep); 276 279 err_address: … … 281 284 /** Enumerate a new USB device 282 285 */ 283 static int usb2_bus_ enumerate_device(bus_t *bus_base, hcd_t *hcd,device_t *dev)286 static int usb2_bus_device_enumerate(device_t *dev) 284 287 { 285 288 int err; 286 usb2_bus_t *bus = bus_to_usb2_bus( bus_base);289 usb2_bus_t *bus = bus_to_usb2_bus(dev->bus); 287 290 288 291 /* The speed of the new device was reported by the hub when reserving … … 306 309 307 310 /* Assign an address to the device */ 308 if ((err = address_device( bus, hcd,dev))) {311 if ((err = address_device(dev))) { 309 312 usb_log_error("Failed to setup address of the new device: %s", str_error(err)); 310 313 return err; … … 312 315 313 316 /* Read the device descriptor, derive the match ids */ 314 if ((err = hcd_ddf_device_explore( hcd,dev))) {317 if ((err = hcd_ddf_device_explore(dev))) { 315 318 usb_log_error("Device(%d): Failed to explore device: %s", dev->address, str_error(err)); 316 319 release_address(bus, dev->address); … … 329 332 * @note Assumes that the internal mutex is locked. 330 333 */ 331 static endpoint_t *usb2_bus_find_ep( bus_t *bus_base,device_t *device, usb_target_t target, usb_direction_t direction)332 { 333 usb2_bus_t *bus = bus_to_usb2_bus( bus_base);334 static endpoint_t *usb2_bus_find_ep(device_t *device, usb_target_t target, usb_direction_t direction) 335 { 336 usb2_bus_t *bus = bus_to_usb2_bus(device->bus); 334 337 335 338 assert(device->address == target.address); … … 345 348 } 346 349 347 static endpoint_t *usb2_bus_create_ep( bus_t *bus)350 static endpoint_t *usb2_bus_create_ep(device_t *dev, const usb_endpoint_desc_t *desc) 348 351 { 349 352 endpoint_t *ep = malloc(sizeof(endpoint_t)); … … 351 354 return NULL; 352 355 353 endpoint_init(ep, bus);356 endpoint_init(ep, dev, desc); 354 357 return ep; 355 358 } … … 370 373 * @param endpoint USB endpoint number. 371 374 */ 372 static int usb2_bus_register_ep(bus_t *bus_base, device_t *device, endpoint_t *ep, const usb_endpoint_desc_t *desc) 373 { 374 usb2_bus_t *bus = bus_to_usb2_bus(bus_base); 375 static int usb2_bus_register_ep(endpoint_t *ep) 376 { 377 usb2_bus_t *bus = bus_to_usb2_bus(ep->device->bus); 378 assert(fibril_mutex_is_locked(&bus->base.guard)); 375 379 assert(ep); 376 380 377 ep->device = device;378 379 /* Extract USB2-related information from endpoint_desc */380 ep->endpoint = desc->endpoint_no;381 ep->direction = desc->direction;382 ep->transfer_type = desc->transfer_type;383 ep->max_packet_size = desc->max_packet_size;384 ep->packets = desc->packets;385 386 ep->bandwidth = bus_base->ops.count_bw(ep, desc->max_packet_size);387 388 381 /* Check for existence */ 389 if (usb2_bus_find_ep( bus_base,ep->device, usb2_ep_to_target(ep), ep->direction))382 if (usb2_bus_find_ep(ep->device, usb2_ep_to_target(ep), ep->direction)) 390 383 return EEXIST; 391 384 … … 394 387 return ENOSPC; 395 388 389 endpoint_add_ref(ep); 396 390 list_append(&ep->link, get_list(bus, ep->device->address)); 397 391 bus->free_bw -= ep->bandwidth; … … 400 394 } 401 395 402 403 396 /** Release bandwidth reserved by the given endpoint. 404 397 */ 405 static int usb2_bus_unregister_ep( bus_t *bus_base,endpoint_t *ep)406 { 407 usb2_bus_t *bus = bus_to_usb2_bus( bus_base);398 static int usb2_bus_unregister_ep(endpoint_t *ep) 399 { 400 usb2_bus_t *bus = bus_to_usb2_bus(ep->device->bus); 408 401 assert(ep); 409 402 410 403 list_remove(&ep->link); 411 ep->device = NULL;412 404 413 405 bus->free_bw += ep->bandwidth; 406 endpoint_del_ref(ep); 414 407 415 408 return EOK; … … 452 445 } 453 446 454 staticconst bus_ops_t usb2_bus_ops = {447 const bus_ops_t usb2_bus_ops = { 455 448 .reserve_default_address = usb2_bus_register_default_address, 456 449 .release_default_address = usb2_bus_release_default_address, 457 .enumerate_device = usb2_bus_enumerate_device,458 .create_endpoint = usb2_bus_create_ep,459 .find_endpoint = usb2_bus_find_ep,460 .unregister_endpoint = usb2_bus_unregister_ep,461 .register_endpoint = usb2_bus_register_ep,462 450 .reset_toggle = usb2_bus_reset_toggle, 451 .device_enumerate = usb2_bus_device_enumerate, 452 .device_find_endpoint = usb2_bus_find_ep, 453 .endpoint_create= usb2_bus_create_ep, 454 .endpoint_register= usb2_bus_register_ep, 455 .endpoint_unregister= usb2_bus_unregister_ep, 463 456 }; 464 457 … … 470 463 * @return Error code. 471 464 */ 472 int usb2_bus_init(usb2_bus_t *bus, size_t available_bandwidth, count_bw_func_t count_bw)465 int usb2_bus_init(usb2_bus_t *bus, hcd_t *hcd, size_t available_bandwidth) 473 466 { 474 467 assert(bus); 475 468 476 bus_init(&bus->base, sizeof(device_t)); 477 478 bus->base.ops = usb2_bus_ops; 479 bus->base.ops.count_bw = count_bw; 469 bus_init(&bus->base, hcd, sizeof(device_t)); 470 bus->base.ops = &usb2_bus_ops; 480 471 481 472 bus->free_bw = available_bandwidth; -
uspace/lib/usbhost/src/usb_transfer_batch.c
rbd05140 r6832245 49 49 { 50 50 assert(ep); 51 assert(ep->bus);52 51 53 usb_transfer_batch_t *batch; 54 if (ep->bus->ops.create_batch) 55 batch = ep->bus->ops.create_batch(ep->bus, ep); 56 else 57 batch = calloc(1, sizeof(usb_transfer_batch_t)); 52 bus_t *bus = endpoint_get_bus(ep); 53 const bus_ops_t *ops = BUS_OPS_LOOKUP(bus->ops, batch_create); 58 54 59 return batch; 55 if (!ops) { 56 usb_transfer_batch_t *batch = calloc(1, sizeof(usb_transfer_batch_t)); 57 usb_transfer_batch_init(batch, ep); 58 return batch; 59 } 60 61 return ops->batch_create(ep); 60 62 } 61 63 … … 64 66 void usb_transfer_batch_init(usb_transfer_batch_t *batch, endpoint_t *ep) 65 67 { 68 assert(ep); 69 endpoint_add_ref(ep); 66 70 batch->ep = ep; 67 71 } … … 82 86 batch->toggle_reset_mode == RESET_ALL ? "all EPs toggle" : "EP toggle"); 83 87 84 return bus_reset_toggle( batch->ep->bus, batch->target, batch->toggle_reset_mode);88 return bus_reset_toggle(endpoint_get_bus(batch->ep), batch->target, batch->toggle_reset_mode); 85 89 } 86 90 … … 93 97 assert(batch); 94 98 assert(batch->ep); 95 assert(batch->ep->bus);96 99 97 bus_t *bus = batch->ep->bus; 98 if (bus->ops.destroy_batch) { 100 bus_t *bus = endpoint_get_bus(batch->ep); 101 const bus_ops_t *ops = BUS_OPS_LOOKUP(bus->ops, batch_destroy); 102 103 endpoint_del_ref(batch->ep); 104 105 if (ops) { 99 106 usb_log_debug2("Batch %p " USB_TRANSFER_BATCH_FMT " destroying.\n", 100 107 batch, USB_TRANSFER_BATCH_ARGS(*batch)); 101 bus->ops.destroy_batch(batch);108 ops->batch_destroy(batch); 102 109 } 103 110 else {
Note:
See TracChangeset
for help on using the changeset viewer.