Changeset 56257ba in mainline
- Timestamp:
- 2018-01-07T01:01:42Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 63431db
- Parents:
- 9efad54
- git-author:
- Ondřej Hlavatý <aearsis@…> (2018-01-07 01:01:41)
- git-committer:
- Ondřej Hlavatý <aearsis@…> (2018-01-07 01:01:42)
- Location:
- uspace
- Files:
-
- 18 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/vuhid/virthid.h
r9efad54 r56257ba 40 40 #include <fibril_synch.h> 41 41 42 #define VUHID_ENDPOINT_MAX USB 11_ENDPOINT_MAX42 #define VUHID_ENDPOINT_MAX USB_ENDPOINT_MAX 43 43 #define VUHID_INTERFACE_MAX 8 44 44 -
uspace/drv/bus/usb/ehci/ehci_bus.c
r9efad54 r56257ba 48 48 * @param[in] toggle new value of toggle bit 49 49 */ 50 static void ehci_ep_toggle_ set(endpoint_t *ep, bool toggle)50 static void ehci_ep_toggle_reset(endpoint_t *ep) 51 51 { 52 52 ehci_endpoint_t *instance = ehci_endpoint_get(ep); 53 assert(instance);54 assert(instance->qh);55 ep->toggle = toggle;56 53 if (qh_toggle_from_td(instance->qh)) 57 usb_log_warning("EP(%p): Setting toggle bit for transfer "58 "directed EP", instance);59 qh_toggle_set(instance->qh, toggle);54 usb_log_warning("EP(%p): Resetting toggle bit for transfer directed EP", instance); 55 qh_toggle_set(instance->qh, 0); 56 ep->toggle = 0; 60 57 } 61 58 62 /** Callback to get value of toggle bit.63 *64 * @param[in] hcd_ep hcd endpoint structure65 * @return Current value of toggle bit.66 */67 static bool ehci_ep_toggle_get(endpoint_t *ep)68 {69 ehci_endpoint_t *instance = ehci_endpoint_get(ep);70 assert(instance);71 assert(instance->qh);72 73 if (qh_toggle_from_td(instance->qh))74 usb_log_warning("EP(%p): Reading useless toggle bit", instance);75 return qh_toggle_get(instance->qh);76 }77 59 78 60 /** Creates new hcd endpoint representation. … … 166 148 .endpoint_register = ehci_register_ep, 167 149 .endpoint_unregister = ehci_unregister_ep, 168 .endpoint_set_toggle = ehci_ep_toggle_set, 169 .endpoint_get_toggle = ehci_ep_toggle_get, 150 .endpoint_toggle_reset = ehci_ep_toggle_reset, 170 151 .endpoint_count_bw = bandwidth_count_usb11, 171 152 .batch_create = ehci_create_batch, -
uspace/drv/bus/usb/ohci/ohci_bus.c
r9efad54 r56257ba 43 43 #include "hc.h" 44 44 45 /** Callback to set toggle on ED.45 /** Callback to reset toggle on ED. 46 46 * 47 47 * @param[in] hcd_ep hcd endpoint structure 48 48 * @param[in] toggle new value of toggle bit 49 49 */ 50 static void ohci_ep_toggle_ set(endpoint_t *ep, bool toggle)50 static void ohci_ep_toggle_reset(endpoint_t *ep) 51 51 { 52 52 ohci_endpoint_t *instance = ohci_endpoint_get(ep); 53 53 assert(instance); 54 54 assert(instance->ed); 55 ep->toggle = toggle; 56 ed_toggle_set(instance->ed, toggle); 57 } 58 59 /** Callback to get value of toggle bit. 60 * 61 * @param[in] hcd_ep hcd endpoint structure 62 * @return Current value of toggle bit. 63 */ 64 static bool ohci_ep_toggle_get(endpoint_t *ep) 65 { 66 ohci_endpoint_t *instance = ohci_endpoint_get(ep); 67 assert(instance); 68 assert(instance->ed); 69 return ed_toggle_get(instance->ed); 55 ep->toggle = 0; 56 ed_toggle_set(instance->ed, 0); 70 57 } 71 58 … … 166 153 .endpoint_unregister = ohci_unregister_ep, 167 154 .endpoint_count_bw = bandwidth_count_usb11, 168 .endpoint_set_toggle = ohci_ep_toggle_set, 169 .endpoint_get_toggle = ohci_ep_toggle_get, 155 .endpoint_toggle_reset = ohci_ep_toggle_reset, 170 156 .batch_create = ohci_create_batch, 171 157 .batch_destroy = ohci_destroy_batch, -
uspace/drv/bus/usb/uhci/uhci_batch.c
r9efad54 r56257ba 178 178 td_print_status(&uhci_batch->tds[i]); 179 179 180 endpoint_toggle_set(batch->ep, 181 td_toggle(&uhci_batch->tds[i])); 180 batch->ep->toggle = td_toggle(&uhci_batch->tds[i]); 182 181 if (i > 0) 183 182 goto substract_ret; … … 195 194 196 195 fibril_mutex_lock(&batch->ep->guard); 197 usb_transfer_batch_reset_toggle(batch);198 196 endpoint_deactivate_locked(batch->ep); 199 197 fibril_mutex_unlock(&batch->ep->guard); … … 236 234 const size_t mps = uhci_batch->base.ep->max_packet_size; 237 235 238 int toggle = endpoint_toggle_get(uhci_batch->base.ep);236 int toggle = uhci_batch->base.ep->toggle; 239 237 assert(toggle == 0 || toggle == 1); 240 238 … … 260 258 } 261 259 td_set_ioc(&uhci_batch->tds[td - 1]); 262 endpoint_toggle_set(uhci_batch->base.ep, toggle);260 uhci_batch->base.ep->toggle = toggle; 263 261 usb_log_debug2( 264 262 "Batch %p %s %s " USB_TRANSFER_BATCH_FMT " initialized.\n", \ -
uspace/drv/bus/usb/xhci/bus.c
r9efad54 r56257ba 77 77 goto err_slot; 78 78 79 /* Temporaryreference */79 /* Bus reference */ 80 80 endpoint_add_ref(ep0_base); 81 dev->base.endpoints[0] = ep0_base; 81 82 82 83 xhci_endpoint_t *ep0 = xhci_endpoint_get(ep0_base); 83 84 84 85 if ((err = xhci_endpoint_alloc_transfer_ds(ep0))) 85 goto err_ep; 86 87 /* Register EP0 */ 88 if ((err = xhci_device_add_endpoint(dev, ep0))) 89 goto err_prepared; 86 goto err_added; 90 87 91 88 /* Address device */ 92 89 if ((err = hc_address_device(bus->hc, dev, ep0))) 93 goto err_added; 94 95 /* Temporary reference */ 96 endpoint_del_ref(ep0_base); 97 return EOK; 98 99 err_added: 100 xhci_device_remove_endpoint(ep0); 90 goto err_prepared; 91 92 return EOK; 93 101 94 err_prepared: 102 95 xhci_endpoint_free_transfer_ds(ep0); 103 err_ ep:104 /* Temporaryreference */96 err_added: 97 /* Bus reference */ 105 98 endpoint_del_ref(ep0_base); 99 dev->base.endpoints[0] = NULL; 106 100 err_slot: 107 101 hc_disable_slot(bus->hc, dev); … … 123 117 return err; 124 118 125 xhci_endpoint_t *ep0 = dev->endpoints[0];119 xhci_endpoint_t *ep0 = xhci_device_get_endpoint(dev, 0); 126 120 assert(ep0); 127 121 … … 218 212 /* Abort running transfers. */ 219 213 usb_log_debug2("Aborting all active transfers to device " XHCI_DEV_FMT ".", XHCI_DEV_ARGS(*xhci_dev)); 220 for ( size_t i = 0; i < ARRAY_SIZE(xhci_dev->endpoints); ++i) {221 xhci_endpoint_t *ep = xhci_dev ->endpoints[i];214 for (usb_endpoint_t i = 0; i < USB_ENDPOINT_MAX; ++i) { 215 xhci_endpoint_t *ep = xhci_device_get_endpoint(xhci_dev, i); 222 216 if (!ep) 223 217 continue; … … 244 238 245 239 /* Unregister remaining endpoints, freeing memory. */ 246 for (u nsigned i = 0; i < ARRAY_SIZE(xhci_dev->endpoints); ++i) {247 if (! xhci_dev->endpoints[i])240 for (usb_endpoint_t i = 0; i < USB_ENDPOINT_MAX; ++i) { 241 if (!dev->endpoints[i]) 248 242 continue; 249 243 250 if ((err = endpoint_unregister( &xhci_dev->endpoints[i]->base))) {244 if ((err = endpoint_unregister(dev->endpoints[i]))) { 251 245 usb_log_warning("Failed to unregister endpoint " XHCI_EP_FMT ": %s", 252 XHCI_EP_ARGS(*xhci_dev ->endpoints[i]), str_error(err));246 XHCI_EP_ARGS(*xhci_device_get_endpoint(xhci_dev, i)), str_error(err)); 253 247 } 254 248 } … … 332 326 333 327 /* We will need the endpoint array later for DS deallocation. */ 334 xhci_endpoint_t *endpoints[ARRAY_SIZE(dev->endpoints)]; 335 memcpy(endpoints, dev->endpoints, sizeof(dev->endpoints)); 336 337 /* Remove all endpoints except zero. */ 338 for (unsigned i = 1; i < ARRAY_SIZE(endpoints); ++i) { 339 if (!endpoints[i]) 340 continue; 341 328 endpoint_t *endpoints[USB_ENDPOINT_MAX]; 329 memcpy(endpoints, dev->base.endpoints, sizeof(endpoints)); 330 331 for (usb_endpoint_t i = 1; i < USB_ENDPOINT_MAX; ++i) { 342 332 /* FIXME: Asserting here that the endpoint is not active. If not, EBUSY? */ 343 344 xhci_device_remove_endpoint(endpoints[i]); 333 dev->base.endpoints[i] = NULL; 345 334 } 346 335 … … 356 345 continue; 357 346 358 xhci_endpoint_free_transfer_ds( endpoints[i]);359 }360 361 /* FIXME: What happens to unregistered endpoints now? Destroy them? */347 xhci_endpoint_free_transfer_ds(xhci_endpoint_get(endpoints[i])); 348 /* Bus reference */ 349 endpoint_del_ref(endpoints[i]); 350 } 362 351 363 352 return EOK; … … 397 386 return err; 398 387 399 if ((err = xhci_device_add_endpoint(dev, ep)))400 goto err_prepared;401 402 388 usb_log_info("Endpoint " XHCI_EP_FMT " registered to XHCI bus.", XHCI_EP_ARGS(*ep)); 403 389 … … 406 392 407 393 if ((err = hc_add_endpoint(bus->hc, dev->slot_id, xhci_endpoint_index(ep), &ep_ctx))) 408 goto err_added; 409 410 return EOK; 411 412 err_added: 413 xhci_device_remove_endpoint(ep); 394 goto err_prepared; 395 396 return EOK; 397 414 398 err_prepared: 415 399 xhci_endpoint_free_transfer_ds(ep); … … 425 409 426 410 usb_log_info("Endpoint " XHCI_EP_FMT " unregistered from XHCI bus.", XHCI_EP_ARGS(*ep)); 427 428 xhci_device_remove_endpoint(ep);429 411 430 412 /* If device slot is still available, drop the endpoint. */ … … 444 426 } 445 427 446 static endpoint_t* device_find_endpoint(device_t *dev_base, usb_target_t target, usb_direction_t direction)447 {448 xhci_device_t *dev = xhci_device_get(dev_base);449 450 xhci_endpoint_t *ep = xhci_device_get_endpoint(dev, target.endpoint);451 if (!ep)452 return NULL;453 454 return &ep->base;455 }456 457 static int reset_toggle(bus_t *bus_base, usb_target_t target, toggle_reset_mode_t mode)458 {459 // TODO: Implement me!460 return ENOTSUP;461 }462 463 /* Endpoint ops, optional (have generic fallback) */464 static bool endpoint_get_toggle(endpoint_t *ep)465 {466 // TODO: Implement me!467 return ENOTSUP;468 }469 470 static void endpoint_set_toggle(endpoint_t *ep, bool toggle)471 {472 // TODO: Implement me!473 }474 475 428 static int reserve_default_address(bus_t *bus_base, usb_speed_t speed) 476 429 { … … 510 463 BIND_OP(reserve_default_address) 511 464 BIND_OP(release_default_address) 512 BIND_OP(reset_toggle)513 465 514 466 BIND_OP(device_enumerate) … … 516 468 BIND_OP(device_online) 517 469 BIND_OP(device_offline) 518 BIND_OP(device_find_endpoint)519 470 520 471 BIND_OP(endpoint_create) … … 522 473 BIND_OP(endpoint_register) 523 474 BIND_OP(endpoint_unregister) 524 BIND_OP(endpoint_get_toggle)525 BIND_OP(endpoint_set_toggle)526 475 527 476 BIND_OP(batch_create) -
uspace/drv/bus/usb/xhci/endpoint.c
r9efad54 r56257ba 469 469 } 470 470 471 /** Add a new XHCI endpoint to a device. The device must be online unless472 * the added endpoint is number 0.473 * @param[in] dev XHCI device, to which to add the endpoint474 * @param[in] ep XHCI endpoint to add.475 *476 * @return Error code.477 */478 int xhci_device_add_endpoint(xhci_device_t *dev, xhci_endpoint_t *ep)479 {480 assert(dev);481 assert(ep);482 483 /* Offline devices don't create new endpoints other than EP0. */484 if (!dev->base.online && ep->base.endpoint > 0) {485 return EAGAIN;486 }487 488 const usb_endpoint_t ep_num = ep->base.endpoint;489 490 if (dev->endpoints[ep_num])491 return EEXIST;492 493 /* Device reference */494 endpoint_add_ref(&ep->base);495 ep->base.device = &dev->base;496 dev->endpoints[ep_num] = ep;497 498 return EOK;499 }500 501 /** Remove XHCI endpoint from a device.502 * @param[in] ep XHCI endpoint to remove.503 */504 void xhci_device_remove_endpoint(xhci_endpoint_t *ep)505 {506 assert(ep);507 xhci_device_t *dev = xhci_device_get(ep->base.device);508 509 assert(dev->endpoints[ep->base.endpoint]);510 dev->endpoints[ep->base.endpoint] = NULL;511 ep->base.device = NULL;512 }513 514 471 /** Retrieve XHCI endpoint from a device by the endpoint number. 515 472 * @param[in] dev XHCI device to query. … … 520 477 xhci_endpoint_t *xhci_device_get_endpoint(xhci_device_t *dev, usb_endpoint_t ep) 521 478 { 522 return dev->endpoints[ep];479 return xhci_endpoint_get(dev->base.endpoints[ep]); 523 480 } 524 481 -
uspace/drv/bus/usb/xhci/endpoint.h
r9efad54 r56257ba 139 139 dma_buffer_t dev_ctx; 140 140 141 /** All endpoints of the device. Dropped ones are NULL */142 xhci_endpoint_t *endpoints[XHCI_EP_COUNT];143 144 141 /** Flag indicating whether the device is USB3 (it's USB2 otherwise). */ 145 142 bool usb3; … … 161 158 void xhci_setup_endpoint_context(xhci_endpoint_t *, xhci_ep_ctx_t *); 162 159 163 int xhci_device_add_endpoint(xhci_device_t *, xhci_endpoint_t *);164 void xhci_device_remove_endpoint(xhci_endpoint_t *);165 160 xhci_endpoint_t * xhci_device_get_endpoint(xhci_device_t *, usb_endpoint_t); 166 161 -
uspace/drv/bus/usb/xhci/transfers.c
r9efad54 r56257ba 513 513 } 514 514 515 usb_transfer_batch_reset_toggle(batch);516 515 endpoint_deactivate_locked(&ep->base); 517 516 fibril_mutex_unlock(&ep->base.guard); -
uspace/lib/usb/include/usb/usb.h
r9efad54 r56257ba 103 103 #define USB_ENDPOINT_DEFAULT_CONTROL 0 104 104 105 /** Maximum endpoint number in USB 1.1.*/106 #define USB 11_ENDPOINT_MAX 16105 /** Maximum endpoint number in USB */ 106 #define USB_ENDPOINT_MAX 16 107 107 108 108 /** Check USB endpoint for allowed values. … … 116 116 { 117 117 return (ep >= USB_ENDPOINT_DEFAULT_CONTROL) && 118 (ep < USB 11_ENDPOINT_MAX);118 (ep < USB_ENDPOINT_MAX); 119 119 } 120 120 -
uspace/lib/usbhost/include/usb/host/bus.h
r9efad54 r56257ba 76 76 usb_speed_t speed; 77 77 usb_address_t address; 78 endpoint_t *endpoints [USB_ENDPOINT_MAX]; 78 79 79 80 /* Managing bus */ … … 101 102 int (*reserve_default_address)(bus_t *, usb_speed_t); 102 103 int (*release_default_address)(bus_t *); 103 int (*reset_toggle)(bus_t *, usb_target_t, toggle_reset_mode_t);104 104 105 105 /* Operations on device */ … … 108 108 int (*device_online)(device_t *); /**< Optional */ 109 109 int (*device_offline)(device_t *); /**< Optional */ 110 endpoint_t *(*device_find_endpoint)(device_t*, usb_target_t, usb_direction_t);111 110 endpoint_t *(*endpoint_create)(device_t *, const usb_endpoint_descriptors_t *); 112 111 … … 115 114 int (*endpoint_unregister)(endpoint_t *); 116 115 void (*endpoint_destroy)(endpoint_t *); /**< Optional */ 117 bool (*endpoint_get_toggle)(endpoint_t *); /**< Optional */ 118 void (*endpoint_set_toggle)(endpoint_t *, bool); /**< Optional */ 119 ssize_t (*endpoint_count_bw) (endpoint_t *, size_t); 116 void (*endpoint_toggle_reset)(endpoint_t *); /**< Optional */ 117 ssize_t (*endpoint_count_bw) (endpoint_t *, size_t); /**< Optional */ 120 118 usb_transfer_batch_t *(*batch_create)(endpoint_t *); /**< Optional */ 121 119 … … 164 162 165 163 int bus_endpoint_add(device_t *, const usb_endpoint_descriptors_t *, endpoint_t **); 166 endpoint_t *bus_find_endpoint(device_t *, usb_ target_t, usb_direction_t);164 endpoint_t *bus_find_endpoint(device_t *, usb_endpoint_t); 167 165 int bus_endpoint_remove(endpoint_t *); 168 166 … … 170 168 int bus_release_default_address(bus_t *); 171 169 172 int bus_reset_toggle(bus_t *, usb_target_t, bool);173 174 170 #endif 175 171 /** -
uspace/lib/usbhost/include/usb/host/endpoint.h
r9efad54 r56257ba 62 62 /** Reserved bandwidth. */ 63 63 size_t bandwidth; 64 /** Value of the toggle bit. */64 /** Value of the toggle bit. Untouched by the library. */ 65 65 unsigned toggle:1; 66 66 /** The currently active transfer batch. Write using methods, read under guard. */ … … 107 107 void endpoint_abort(endpoint_t *); 108 108 109 /* Manage the toggle bit */110 extern int endpoint_toggle_get(endpoint_t *);111 extern void endpoint_toggle_set(endpoint_t *, bool);112 113 109 /* Calculate bandwidth */ 114 110 ssize_t endpoint_count_bw(endpoint_t *, size_t); -
uspace/lib/usbhost/include/usb/host/usb2_bus.h
r9efad54 r56257ba 50 50 bus_t base; /**< Inheritance - keep this first */ 51 51 52 /* Device bookkeeping*/53 struct {54 usb_speed_t speed; /**< Device speed */ 55 bool occupied; /**< The address is in use.*/56 // TODO: This can be stored in usb2_bus-specific device_t57 list_t endpoint_list; /**< Store endpoint_t instances */58 } devices[USB_ADDRESS_COUNT];52 /** The speed which reserved default address. Invalid unless reserved. */ 53 usb_speed_t default_address_speed; 54 55 /** Map of occupied addresses */ 56 bool address_occupied [USB_ADDRESS_COUNT]; 57 /** The last reserved address */ 58 usb_address_t last_address; 59 59 60 60 /** Size of the bandwidth pool */ 61 61 size_t free_bw; 62 /** The last reserved address */63 usb_address_t last_address;64 62 } usb2_bus_t; 65 63 -
uspace/lib/usbhost/include/usb/host/usb_transfer_batch.h
r9efad54 r56257ba 111 111 void usb_transfer_batch_init(usb_transfer_batch_t *, endpoint_t *); 112 112 113 /** Call after status is known, but before releasing endpoint */114 int usb_transfer_batch_reset_toggle(usb_transfer_batch_t *);115 116 113 /** Batch finalization. */ 117 114 void usb_transfer_batch_abort(usb_transfer_batch_t *); -
uspace/lib/usbhost/src/bus.c
r9efad54 r56257ba 99 99 100 100 const bus_ops_t *ops = BUS_OPS_LOOKUP(dev->bus->ops, device_remove); 101 102 101 if (!ops) 103 102 return ENOTSUP; … … 162 161 163 162 fibril_mutex_lock(&bus->guard); 164 err = register_ops->endpoint_register(ep); 165 fibril_mutex_unlock(&bus->guard); 163 if (!device->online && ep->endpoint != 0) { 164 err = EAGAIN; 165 } else if (device->endpoints[ep->endpoint] != NULL) { 166 err = EEXIST; 167 } else { 168 err = register_ops->endpoint_register(ep); 169 if (!err) 170 device->endpoints[ep->endpoint] = ep; 171 } 172 fibril_mutex_unlock(&bus->guard); 173 if (err) { 174 endpoint_del_ref(ep); 175 return err; 176 } 166 177 167 178 if (out_ep) { … … 171 182 } 172 183 173 return err;184 return EOK; 174 185 } 175 186 176 187 /** Searches for an endpoint. Returns a reference. 177 188 */ 178 endpoint_t *bus_find_endpoint(device_t *device, usb_ target_t endpoint, usb_direction_t dir)189 endpoint_t *bus_find_endpoint(device_t *device, usb_endpoint_t endpoint) 179 190 { 180 191 assert(device); … … 182 193 bus_t *bus = device->bus; 183 194 184 const bus_ops_t *ops = BUS_OPS_LOOKUP(bus->ops, device_find_endpoint); 185 if (!ops) 186 return NULL; 187 188 fibril_mutex_lock(&bus->guard); 189 endpoint_t *ep = ops->device_find_endpoint(device, endpoint, dir); 195 fibril_mutex_lock(&bus->guard); 196 endpoint_t *ep = device->endpoints[endpoint]; 190 197 if (ep) { 191 198 /* Exporting reference */ 192 199 endpoint_add_ref(ep); 193 200 } 194 195 201 fibril_mutex_unlock(&bus->guard); 196 202 return ep; … … 201 207 assert(ep); 202 208 assert(ep->device); 203 assert(ep->device->bus);204 assert(ep->device->bus->ops);205 209 206 210 bus_t *bus = endpoint_get_bus(ep); … … 218 222 fibril_mutex_lock(&bus->guard); 219 223 const int r = ops->endpoint_unregister(ep); 224 if (!r) 225 ep->device->endpoints[ep->endpoint] = NULL; 220 226 fibril_mutex_unlock(&bus->guard); 221 227 … … 253 259 fibril_mutex_lock(&bus->guard); 254 260 const int r = ops->release_default_address(bus); 255 fibril_mutex_unlock(&bus->guard);256 return r;257 }258 259 int bus_reset_toggle(bus_t *bus, usb_target_t target, bool all)260 {261 assert(bus);262 263 const bus_ops_t *ops = BUS_OPS_LOOKUP(bus->ops, reset_toggle);264 if (!ops)265 return ENOTSUP;266 267 fibril_mutex_lock(&bus->guard);268 const int r = ops->reset_toggle(bus, target, all);269 261 fibril_mutex_unlock(&bus->guard); 270 262 return r; … … 288 280 289 281 /* Temporary reference */ 290 endpoint_t *ep = bus_find_endpoint(device, target , direction);282 endpoint_t *ep = bus_find_endpoint(device, target.endpoint); 291 283 if (ep == NULL) { 292 284 usb_log_error("Endpoint(%d:%d) not registered for %s.\n", -
uspace/lib/usbhost/src/ddf_helpers.c
r9efad54 r56257ba 106 106 assert(dev); 107 107 108 const usb_target_t target = {{ 109 .address = dev->address, 110 .endpoint = endpoint_desc->endpoint_no 111 }}; 112 113 endpoint_t *ep = bus_find_endpoint(dev, target, endpoint_desc->direction); 108 endpoint_t *ep = bus_find_endpoint(dev, endpoint_desc->endpoint_no); 114 109 if (!ep) 115 110 return ENOENT; -
uspace/lib/usbhost/src/endpoint.c
r9efad54 r56257ba 108 108 } 109 109 110 static void endpoint_toggle_reset(endpoint_t *ep, toggle_reset_mode_t mode); 111 110 112 /** Mark the endpoint as active and block access for further fibrils. 111 113 * @param ep endpoint_t structure. … … 132 134 133 135 if (ep->active_batch && ep->active_batch->error == EOK) 134 usb_transfer_batch_reset_toggle(ep->active_batch);136 endpoint_toggle_reset(ep, ep->active_batch->toggle_reset_mode); 135 137 136 138 ep->active_batch = NULL; … … 155 157 } 156 158 157 /** Get the value of toggle bit. Either uses the toggle_get op, or just returns 158 * the value of the toggle. 159 * @param ep endpoint_t structure. 160 */ 161 int endpoint_toggle_get(endpoint_t *ep) 162 { 163 assert(ep); 164 165 const bus_ops_t *ops = BUS_OPS_LOOKUP(get_bus_ops(ep), endpoint_get_toggle); 166 return ops 167 ? ops->endpoint_get_toggle(ep) 168 : ep->toggle; 169 } 170 171 /** Set the value of toggle bit. Either uses the toggle_set op, or just sets 172 * the toggle inside. 173 * @param ep endpoint_t structure. 174 */ 175 void endpoint_toggle_set(endpoint_t *ep, bool toggle) 176 { 177 assert(ep); 178 179 const bus_ops_t *ops = BUS_OPS_LOOKUP(get_bus_ops(ep), endpoint_set_toggle); 180 if (ops) { 181 ops->endpoint_set_toggle(ep, toggle); 182 } 183 else { 184 ep->toggle = toggle; 159 static void endpoint_toggle_reset(endpoint_t *ep, toggle_reset_mode_t mode) 160 { 161 assert(ep); 162 163 if (mode == RESET_NONE) 164 return; 165 166 const bus_ops_t *ops = BUS_OPS_LOOKUP(get_bus_ops(ep), endpoint_toggle_reset); 167 if (!ops) 168 return; 169 170 device_t *dev = ep->device; 171 172 if (mode == RESET_ALL) { 173 for (usb_endpoint_t i = 0; i < USB_ENDPOINT_MAX; ++i) { 174 if (dev->endpoints[i]) 175 ops->endpoint_toggle_reset(dev->endpoints[i]); 176 } 177 } else { 178 ops->endpoint_toggle_reset(ep); 185 179 } 186 180 } -
uspace/lib/usbhost/src/usb2_bus.c
r9efad54 r56257ba 57 57 } 58 58 59 /** Get list that holds endpoints for given address.60 * @param bus usb2_bus structure, non-null.61 * @param addr USB address, must be >= 0.62 * @return Pointer to the appropriate list.63 */64 static list_t * get_list(usb2_bus_t *bus, usb_address_t addr)65 {66 assert(bus);67 assert(addr >= 0);68 return &bus->devices[addr % ARRAY_SIZE(bus->devices)].endpoint_list;69 }70 71 /** Get speed assigned to USB address.72 *73 * @param[in] bus Device manager structure to use.74 * @param[in] address Address the caller wants to find.75 * @param[out] speed Assigned speed.76 * @return Error code.77 */78 static int get_speed(usb2_bus_t *bus, usb_address_t address, usb_speed_t *speed)79 {80 if (!usb_address_is_valid(address))81 return EINVAL;82 83 if (!bus->devices[address].occupied)84 return ENOENT;85 86 if (speed)87 *speed = bus->devices[address].speed;88 89 return EOK;90 }91 92 59 /** Get a free USB address 93 60 * … … 104 71 if (new_address == bus->last_address) 105 72 return ENOSPC; 106 } while (bus-> devices[new_address].occupied);73 } while (bus->address_occupied[new_address]); 107 74 108 75 assert(new_address != USB_ADDRESS_DEFAULT); … … 125 92 return EINVAL; 126 93 127 const int ret = bus->devices[address].occupied ? EOK : ENOENT; 128 bus->devices[address].occupied = false; 129 130 list_t *list = get_list(bus, address); 131 for (link_t *link = list_first(list); link != NULL; ) { 132 endpoint_t *ep = list_get_instance(link, endpoint_t, link); 133 link = list_next(link, list); 134 135 assert(ep->device->address == address); 136 list_remove(&ep->link); 137 138 usb_log_warning("Endpoint %d:%d %s was left behind, removing.\n", 139 address, ep->endpoint, usb_str_direction(ep->direction)); 140 141 /* Drop bus reference */ 142 endpoint_del_ref(ep); 143 } 144 94 const int ret = bus->address_occupied[address] ? EOK : ENOENT; 95 bus->address_occupied[address] = false; 145 96 return ret; 146 97 } … … 153 104 * @note Default address is only available in strict mode. 154 105 */ 155 static int request_address(usb2_bus_t *bus, usb_address_t *addr, bool strict , usb_speed_t speed)106 static int request_address(usb2_bus_t *bus, usb_address_t *addr, bool strict) 156 107 { 157 108 int err; … … 168 119 return err; 169 120 } 170 else if (bus-> devices[*addr].occupied) {121 else if (bus->address_occupied[*addr]) { 171 122 if (strict) { 172 123 return ENOENT; … … 177 128 178 129 assert(usb_address_is_valid(*addr)); 179 assert(bus-> devices[*addr].occupied== false);130 assert(bus->address_occupied[*addr] == false); 180 131 assert(*addr != USB_ADDRESS_DEFAULT || strict); 181 132 182 bus->devices[*addr].occupied = true; 183 bus->devices[*addr].speed = speed; 133 bus->address_occupied[*addr] = true; 184 134 185 135 return EOK; … … 202 152 /** Reserve address early, we want pretty log messages */ 203 153 usb_address_t address = USB_ADDRESS_DEFAULT; 204 if ((err = request_address(bus, &address, false , dev->speed))) {154 if ((err = request_address(bus, &address, false))) { 205 155 usb_log_error("Failed to reserve new address: %s.", 206 156 str_error(err)); … … 281 231 * default address. 282 232 */ 283 if ((err = get_speed(bus, USB_ADDRESS_DEFAULT, &dev->speed))) { 284 usb_log_error("Failed to verify speed: %s.", str_error(err)); 285 return err; 286 } 233 dev->speed = bus->default_address_speed; 287 234 usb_log_debug("Found new %s speed USB device.", usb_str_speed(dev->speed)); 288 235 … … 313 260 } 314 261 315 /** Find endpoint.316 * @param bus usb_bus structure, non-null.317 * @param target Endpoint address.318 * @param direction Communication direction.319 * @return Pointer to endpoint_t structure representing given communication320 * target, NULL if there is no such endpoint registered.321 * @note Assumes that the internal mutex is locked.322 */323 static endpoint_t *usb2_bus_find_ep(device_t *device, usb_target_t target, usb_direction_t direction)324 {325 usb2_bus_t *bus = bus_to_usb2_bus(device->bus);326 327 assert(device->address == target.address);328 329 list_foreach(*get_list(bus, target.address), link, endpoint_t, ep) {330 if (((direction == ep->direction)331 || (ep->direction == USB_DIRECTION_BOTH)332 || (direction == USB_DIRECTION_BOTH))333 && (target.endpoint == ep->endpoint))334 return ep;335 }336 return NULL;337 }338 339 262 static endpoint_t *usb2_bus_create_ep(device_t *dev, const usb_endpoint_descriptors_t *desc) 340 263 { … … 347 270 } 348 271 349 static usb_target_t usb2_ep_to_target(endpoint_t *ep)350 {351 assert(ep);352 assert(ep->device);353 354 return (usb_target_t) {{355 .address = ep->device->address,356 .endpoint = ep->endpoint,357 }};358 }359 360 272 /** Register an endpoint to the bus. Reserves bandwidth. 361 273 * @param bus usb_bus structure, non-null. … … 368 280 assert(ep); 369 281 370 /* Check for existence */371 if (usb2_bus_find_ep(ep->device, usb2_ep_to_target(ep), ep->direction))372 return EEXIST;373 374 282 /* Check for available bandwidth */ 375 283 if (ep->bandwidth > bus->free_bw) 376 284 return ENOSPC; 377 285 378 endpoint_add_ref(ep);379 list_append(&ep->link, get_list(bus, ep->device->address));380 286 bus->free_bw -= ep->bandwidth; 381 287 … … 390 296 assert(ep); 391 297 392 list_remove(&ep->link);393 394 298 bus->free_bw += ep->bandwidth; 395 endpoint_del_ref(ep); 396 397 return EOK; 398 } 399 400 static int usb2_bus_reset_toggle(bus_t *bus_base, usb_target_t target, toggle_reset_mode_t mode) 401 { 402 usb2_bus_t *bus = bus_to_usb2_bus(bus_base); 403 404 if (!usb_target_is_valid(target)) 405 return EINVAL; 406 407 if (mode == RESET_NONE) 408 return EOK; 409 410 int ret = ENOENT; 411 412 list_foreach(*get_list(bus, target.address), link, endpoint_t, ep) { 413 assert(ep->device->address == target.address); 414 415 if (mode == RESET_ALL || ep->endpoint == target.endpoint) { 416 endpoint_toggle_set(ep, 0); 417 ret = EOK; 418 } 419 } 420 return ret; 299 300 return EOK; 421 301 } 422 302 … … 425 305 usb2_bus_t *bus = bus_to_usb2_bus(bus_base); 426 306 usb_address_t addr = USB_ADDRESS_DEFAULT; 427 return request_address(bus, &addr, true, speed); 307 const int err = request_address(bus, &addr, true); 308 if (err) 309 return err; 310 bus->default_address_speed = speed; 311 return EOK; 428 312 } 429 313 … … 437 321 .reserve_default_address = usb2_bus_register_default_address, 438 322 .release_default_address = usb2_bus_release_default_address, 439 .reset_toggle = usb2_bus_reset_toggle,440 323 .device_enumerate = usb2_bus_device_enumerate, 441 .device_find_endpoint = usb2_bus_find_ep,442 324 .endpoint_create = usb2_bus_create_ep, 443 325 .endpoint_register = usb2_bus_register_ep, … … 460 342 461 343 bus->free_bw = available_bandwidth; 462 bus->last_address = 0; 463 for (unsigned i = 0; i < ARRAY_SIZE(bus->devices); ++i) { 464 list_initialize(&bus->devices[i].endpoint_list); 465 bus->devices[i].speed = USB_SPEED_MAX; 466 bus->devices[i].occupied = false; 467 } 344 468 345 return EOK; 469 346 } -
uspace/lib/usbhost/src/usb_transfer_batch.c
r9efad54 r56257ba 71 71 } 72 72 73 /** Resolve resetting toggle.74 *75 * @param[in] batch Batch structure to use.76 */77 int usb_transfer_batch_reset_toggle(usb_transfer_batch_t *batch)78 {79 assert(batch);80 81 if (batch->error != EOK || batch->toggle_reset_mode == RESET_NONE)82 return EOK;83 84 usb_log_debug2("Batch %p " USB_TRANSFER_BATCH_FMT " resets %s",85 batch, USB_TRANSFER_BATCH_ARGS(*batch),86 batch->toggle_reset_mode == RESET_ALL ? "all EPs toggle" : "EP toggle");87 88 return bus_reset_toggle(endpoint_get_bus(batch->ep), batch->target, batch->toggle_reset_mode);89 }90 91 73 /** Destroy the batch. 92 74 *
Note:
See TracChangeset
for help on using the changeset viewer.