Changeset 9620a54 in mainline
- Timestamp:
- 2017-10-29T10:51:59Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- d33dc780
- Parents:
- 62f8025
- Location:
- uspace/drv/bus/usb/xhci
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/xhci/bus.c
r62f8025 r9620a54 121 121 endpoint_del_ref(ep0_base); 122 122 err_slot: 123 hc_disable_slot(hc, dev ->slot_id);123 hc_disable_slot(hc, dev); 124 124 return err; 125 125 } … … 189 189 190 190 /* Block creation of new endpoints and transfers. */ 191 usb_log_debug2("Device '%s' going offline.", ddf_fun_get_name(dev->fun));191 usb_log_debug2("Device " XHCI_DEV_FMT " going offline.", XHCI_DEV_ARGS(*xhci_dev)); 192 192 fibril_mutex_lock(&dev->guard); 193 193 xhci_dev->online = false; … … 195 195 196 196 /* Abort running transfers. */ 197 usb_log_debug2("Aborting all active transfers to '%s'.", ddf_fun_get_name(dev->fun));197 usb_log_debug2("Aborting all active transfers to device " XHCI_DEV_FMT ".", XHCI_DEV_ARGS(*xhci_dev)); 198 198 for (size_t i = 0; i < ARRAY_SIZE(xhci_dev->endpoints); ++i) { 199 199 xhci_endpoint_t *ep = xhci_dev->endpoints[i]; … … 203 203 /* FIXME: This is racy. */ 204 204 if ((err = xhci_transfer_abort(&ep->active_transfer))) { 205 usb_log_warning("Failed to abort active %s transfer to " 206 " endpoint %d of detached device '%s': %s", 207 usb_str_transfer_type(ep->base.transfer_type), 208 ep->base.endpoint, ddf_fun_get_name(dev->fun), 205 usb_log_warning("Failed to abort active transfer to " 206 " endpoint " XHCI_EP_FMT ": %s", XHCI_EP_ARGS(*ep), 209 207 str_error(err)); 210 208 } … … 215 213 /* Make DDF (and all drivers) forget about the device. */ 216 214 if ((err = ddf_fun_unbind(dev->fun))) { 217 usb_log_warning("Failed to unbind DDF function of device '%s': %s", 218 ddf_fun_get_name(dev->fun), str_error(err)); 219 } 220 221 /* Unregister remaining endpoints. */ 215 usb_log_warning("Failed to unbind DDF function of device " XHCI_DEV_FMT ": %s", 216 XHCI_DEV_ARGS(*xhci_dev), str_error(err)); 217 } 218 219 /* Disable the slot, dropping all endpoints. */ 220 const uint32_t slot_id = xhci_dev->slot_id; 221 if ((err = hc_disable_slot(hc, xhci_dev))) { 222 usb_log_warning("Failed to disable slot of device " XHCI_DEV_FMT ": %s", 223 XHCI_DEV_ARGS(*xhci_dev), str_error(err)); 224 } 225 226 bus->devices_by_slot[slot_id] = NULL; 227 228 /* Unregister remaining endpoints, freeing memory. */ 222 229 for (unsigned i = 0; i < ARRAY_SIZE(xhci_dev->endpoints); ++i) { 223 230 if (!xhci_dev->endpoints[i]) … … 225 232 226 233 if ((err = unregister_endpoint(&bus->base, &xhci_dev->endpoints[i]->base))) { 227 usb_log_warning("Failed to unregister EP (%u:%u): %s", dev->address, i, str_error(err)); 234 usb_log_warning("Failed to unregister endpoint " XHCI_EP_FMT ": %s", 235 XHCI_EP_ARGS(*xhci_dev->endpoints[i]), str_error(err)); 228 236 } 229 237 } 230 231 // XXX: Ugly here. Move to device_destroy at endpoint.c?232 if ((err = hc_disable_slot(hc, xhci_dev->slot_id))) {233 usb_log_warning("Failed to disable slot %d for device '%s': %s",234 xhci_dev->slot_id, ddf_fun_get_name(dev->fun), str_error(err));235 }236 237 free32(xhci_dev->dev_ctx);238 hc->dcbaa[xhci_dev->slot_id] = 0;239 240 bus->devices_by_slot[xhci_dev->slot_id] = NULL;241 238 242 239 /* Destroy DDF device. */ … … 291 288 /* Transition the device from the Addressed to the Configured state. */ 292 289 if ((err = hc_configure_device(hc, dev->slot_id))) { 293 usb_log_warning("Failed to configure device %d.", dev_base->address);290 usb_log_warning("Failed to configure device " XHCI_DEV_FMT ".", XHCI_DEV_ARGS(*dev)); 294 291 } 295 292 296 293 /* Block creation of new endpoints and transfers. */ 297 usb_log_debug2("Device '%s' going online.", ddf_fun_get_name(dev_base->fun));294 usb_log_debug2("Device " XHCI_DEV_FMT " going online.", XHCI_DEV_ARGS(*dev)); 298 295 fibril_mutex_lock(&dev_base->guard); 299 296 dev->online = true; … … 326 323 327 324 /* Block creation of new endpoints and transfers. */ 328 usb_log_debug2("Device '%s' going offline.", ddf_fun_get_name(dev_base->fun));325 usb_log_debug2("Device " XHCI_DEV_FMT " going offline.", XHCI_DEV_ARGS(*dev)); 329 326 fibril_mutex_lock(&dev_base->guard); 330 327 dev->online = false; … … 347 344 /* Issue one HC command to simultaneously drop all endpoints except zero. */ 348 345 if ((err = hc_deconfigure_device(hc, dev->slot_id))) { 349 usb_log_warning("Failed to deconfigure device %d.", dev_base->address); 346 usb_log_warning("Failed to deconfigure device " XHCI_DEV_FMT ".", 347 XHCI_DEV_ARGS(*dev)); 350 348 } 351 349 352 350 /* Tear down TRB ring / PSA. */ 353 /* TODO: Make this method "noexcept" */354 351 for (unsigned i = 1; i < ARRAY_SIZE(endpoints); ++i) { 355 352 if (!endpoints[i]) 356 353 continue; 357 354 358 if ((err = xhci_endpoint_free_transfer_ds(endpoints[i]))) { 359 usb_log_warning("Failed to free resources of EP (%u:%u): %s", dev_base->address, i, str_error(err)); 360 } 355 xhci_endpoint_free_transfer_ds(endpoints[i]); 361 356 } 362 357 … … 404 399 goto err_prepared; 405 400 406 usb_log_info("Endpoint (%d:%d) registered to XHCI bus.", dev->base.address, ep->base.endpoint);401 usb_log_info("Endpoint " XHCI_EP_FMT " registered to XHCI bus.", XHCI_EP_ARGS(*ep)); 407 402 408 403 xhci_ep_ctx_t ep_ctx; … … 428 423 xhci_device_t *dev = xhci_device_get(ep_base->device); 429 424 430 usb_log_info("Endpoint (%d:%d) unregistered from XHCI bus.", dev->base.address, ep->base.endpoint);425 usb_log_info("Endpoint " XHCI_EP_FMT " unregistered from XHCI bus.", XHCI_EP_ARGS(*ep)); 431 426 432 427 xhci_device_remove_endpoint(ep); 433 428 434 /* Drop the endpoint. */ 435 if ((err = hc_drop_endpoint(bus->hc, dev->slot_id, xhci_endpoint_index(ep)))) { 436 usb_log_error("Failed to drop endpoint: %s", str_error(err)); 429 /* If device slot is still available, drop the endpoint. */ 430 if (dev->slot_id) { 431 if ((err = hc_drop_endpoint(bus->hc, dev->slot_id, xhci_endpoint_index(ep)))) { 432 usb_log_error("Failed to drop endpoint " XHCI_EP_FMT ": %s", XHCI_EP_ARGS(*ep), str_error(err)); 433 } 434 } else { 435 usb_log_debug("Not going to drop endpoint " XHCI_EP_FMT " because" 436 " the slot has already been disabled.", XHCI_EP_ARGS(*ep)); 437 437 } 438 438 439 439 /* Tear down TRB ring / PSA. */ 440 /* TODO: Make this method "noexcept" */ 441 if ((err = xhci_endpoint_free_transfer_ds(ep))) { 442 usb_log_error("Failed to free resources of an endpoint."); 443 } 440 xhci_endpoint_free_transfer_ds(ep); 444 441 445 442 return EOK; -
uspace/drv/bus/usb/xhci/endpoint.c
r62f8025 r9620a54 188 188 int xhci_endpoint_alloc_transfer_ds(xhci_endpoint_t *xhci_ep) 189 189 { 190 191 usb_log_debug2("Allocating main transfer ring for endpoint %u", xhci_ep->base.endpoint);190 /* Can't use XHCI_EP_FMT because the endpoint may not have device. */ 191 usb_log_debug2("Allocating main transfer ring for endpoint " XHCI_EP_FMT, XHCI_EP_ARGS(*xhci_ep)); 192 192 193 193 xhci_ep->primary_stream_ctx_array = NULL; … … 201 201 } 202 202 203 int xhci_endpoint_free_transfer_ds(xhci_endpoint_t *xhci_ep) 204 { 205 /* FIXME: For some reason (possibly memory corruption), this crashes. */ 206 return EOK; 207 203 void xhci_endpoint_free_transfer_ds(xhci_endpoint_t *xhci_ep) 204 { 208 205 if (endpoint_using_streams(xhci_ep)) { 209 usb_log_debug2("Freeing primary stream context array forendpoint " XHCI_EP_FMT, XHCI_EP_ARGS(*xhci_ep));206 usb_log_debug2("Freeing primary stream context array of endpoint " XHCI_EP_FMT, XHCI_EP_ARGS(*xhci_ep)); 210 207 211 208 // maybe check if LSA, then skip? … … 223 220 free32(xhci_ep->primary_stream_ctx_array); 224 221 } else { 225 usb_log_debug2("Freeing main transfer ring for endpoint " XHCI_EP_FMT, XHCI_EP_ARGS(*xhci_ep)); 226 227 int err; 228 if ((err = xhci_trb_ring_fini(&xhci_ep->ring))) { 229 return err; 230 } 231 } 232 233 return EOK; 222 usb_log_debug2("Freeing main transfer ring of endpoint " XHCI_EP_FMT, XHCI_EP_ARGS(*xhci_ep)); 223 224 xhci_trb_ring_fini(&xhci_ep->ring); 225 } 234 226 } 235 227 … … 344 336 endpoint_add_ref(&ep->base); 345 337 ep->base.device = &dev->base; 346 347 338 dev->endpoints[ep_num] = ep; 348 ++dev->active_endpoint_count;349 339 350 340 return EOK; … … 357 347 358 348 assert(dev->endpoints[ep->base.endpoint]); 359 360 349 dev->endpoints[ep->base.endpoint] = NULL; 361 --dev->active_endpoint_count;362 350 ep->base.device = NULL; 363 351 -
uspace/drv/bus/usb/xhci/endpoint.h
r62f8025 r9620a54 91 91 92 92 #define XHCI_EP_FMT "(%d:%d %s)" 93 /* FIXME: "Device -1" messes up log messages, figure out a better way. */ 93 94 #define XHCI_EP_ARGS(ep) \ 94 ((ep).base.device ->address), \95 ((ep).base.device ? (ep).base.device->address : -1), \ 95 96 ((ep).base.endpoint), \ 96 97 (usb_str_transfer_type((ep).base.transfer_type)) … … 114 115 xhci_device_ctx_t *dev_ctx; 115 116 116 /** All endpoints of the device. Inactiveones are NULL */117 /** All endpoints of the device. Dropped ones are NULL */ 117 118 xhci_endpoint_t *endpoints[XHCI_EP_COUNT]; 118 119 /** Number of non-NULL endpoints. Reference count of sorts. */120 uint8_t active_endpoint_count;121 119 122 120 /** Flag indicating whether the device is USB3 (it's USB2 otherwise). */ … … 127 125 } xhci_device_t; 128 126 127 #define XHCI_DEV_FMT "(%s, slot %d)" 128 #define XHCI_DEV_ARGS(dev) ddf_fun_get_name((dev).base.fun), (dev).slot_id 129 129 130 int xhci_endpoint_init(xhci_endpoint_t *, xhci_bus_t *); 130 131 void xhci_endpoint_fini(xhci_endpoint_t *); 131 132 int xhci_endpoint_alloc_transfer_ds(xhci_endpoint_t *); 132 intxhci_endpoint_free_transfer_ds(xhci_endpoint_t *);133 void xhci_endpoint_free_transfer_ds(xhci_endpoint_t *); 133 134 134 135 int xhci_endpoint_request_streams(xhci_hc_t *, xhci_device_t *, xhci_endpoint_t *, unsigned); -
uspace/drv/bus/usb/xhci/hc.c
r62f8025 r9620a54 617 617 } 618 618 619 int hc_disable_slot(xhci_hc_t *hc, uint32_t slot_id) 620 { 619 int hc_disable_slot(xhci_hc_t *hc, xhci_device_t *dev) 620 { 621 int err; 621 622 assert(hc); 622 return xhci_cmd_sync_inline(hc, DISABLE_SLOT, .slot_id = slot_id); 623 624 if ((err = xhci_cmd_sync_inline(hc, DISABLE_SLOT, .slot_id = dev->slot_id))) { 625 return err; 626 } 627 628 /* Free the device context. */ 629 hc->dcbaa[dev->slot_id] = 0; 630 if (dev->dev_ctx) { 631 free32(dev->dev_ctx); 632 dev->dev_ctx = NULL; 633 } 634 635 /* Mark the slot as invalid. */ 636 dev->slot_id = 0; 637 638 return EOK; 623 639 } 624 640 … … 654 670 * we have to rely on reverse mapping on others. */ 655 671 if (!hc->speed_to_psiv[dev->base.speed]) { 656 usb_log_error("Device reported an usbspeed that cannot be mapped to HC port speed.");672 usb_log_error("Device reported an USB speed that cannot be mapped to HC port speed."); 657 673 return EINVAL; 658 674 } -
uspace/drv/bus/usb/xhci/hc.h
r62f8025 r9620a54 102 102 int hc_ring_doorbell(xhci_hc_t *, unsigned, unsigned); 103 103 int hc_enable_slot(xhci_hc_t *, uint32_t *); 104 int hc_disable_slot(xhci_hc_t *, uint32_t);104 int hc_disable_slot(xhci_hc_t *, xhci_device_t *); 105 105 int hc_address_device(xhci_hc_t *, xhci_device_t *, xhci_endpoint_t *); 106 106 int hc_configure_device(xhci_hc_t *, uint32_t); -
uspace/drv/bus/usb/xhci/rh.c
r62f8025 r9620a54 119 119 120 120 if ((err = ddf_fun_bind(dev->fun))) { 121 usb_log_error("Device(%d): Failed to register: %s.", dev->address, str_error(err)); 121 usb_log_error("Failed to register device " XHCI_DEV_FMT " DDF function: %s.", 122 XHCI_DEV_ARGS(*xhci_dev), str_error(err)); 122 123 goto err_usb_dev; 123 124 } … … 185 186 } 186 187 187 usb_log_info("Device '%s' at port %u has been disconnected.", ddf_fun_get_name(dev->base.fun), port_id); 188 usb_log_info("Device " XHCI_DEV_FMT " at port %u has been disconnected.", 189 XHCI_DEV_ARGS(*dev), port_id); 188 190 189 191 /* Mark the device as detached. */ … … 195 197 /* Remove device from XHCI bus. */ 196 198 if ((err = xhci_bus_remove_device(&rh->hc->bus, rh->hc, &dev->base))) { 197 usb_log_warning("Failed to remove device '%s'from XHCI bus: %s",198 ddf_fun_get_name(dev->base.fun), str_error(err));199 usb_log_warning("Failed to remove device " XHCI_DEV_FMT " from XHCI bus: %s", 200 XHCI_DEV_ARGS(*dev), str_error(err)); 199 201 } 200 202 -
uspace/drv/bus/usb/xhci/transfers.c
r62f8025 r9620a54 265 265 xhci_device_t *dev = hc->bus.devices_by_slot[slot_id]; 266 266 if (!dev) { 267 usb_log_error("Transfer event on unknown device slot %u!", slot_id);267 usb_log_error("Transfer event on disabled slot %u", slot_id); 268 268 return ENOENT; 269 269 } … … 272 272 xhci_endpoint_t *ep = xhci_device_get_endpoint(dev, ep_num); 273 273 if (!ep) { 274 usb_log_error("Transfer event on unknown endpoint num %u, device slot %u!", ep_num, slot_id); 274 usb_log_error("Transfer event on dropped endpoint %u of device " 275 XHCI_DEV_FMT, ep_num, XHCI_DEV_ARGS(*dev)); 275 276 return ENOENT; 276 277 } … … 322 323 // FIXME: find a better way to check if the ring is not initialized 323 324 if (!xhci_ep->ring.segment_count) { 324 usb_log_error("Ring not initialized for endpoint num %u!", xhci_ep->base.endpoint); 325 usb_log_error("Ring not initialized for endpoint " XHCI_EP_FMT, 326 XHCI_EP_ARGS(*xhci_ep)); 325 327 return EINVAL; 326 328 } -
uspace/drv/bus/usb/xhci/trb_ring.c
r62f8025 r9620a54 121 121 } 122 122 123 intxhci_trb_ring_fini(xhci_trb_ring_t *ring)123 void xhci_trb_ring_fini(xhci_trb_ring_t *ring) 124 124 { 125 125 assert(ring); … … 129 129 dmamem_unmap_anonymous(segment); 130 130 } 131 132 return EOK;133 131 } 134 132 … … 292 290 } 293 291 294 intxhci_event_ring_fini(xhci_event_ring_t *ring)292 void xhci_event_ring_fini(xhci_event_ring_t *ring) 295 293 { 296 294 list_foreach_safe(ring->segments, cur, next) { … … 301 299 if (ring->erst) 302 300 free32(ring->erst); 303 304 return EOK;305 301 } 306 302 -
uspace/drv/bus/usb/xhci/trb_ring.h
r62f8025 r9620a54 74 74 75 75 int xhci_trb_ring_init(xhci_trb_ring_t *); 76 intxhci_trb_ring_fini(xhci_trb_ring_t *);76 void xhci_trb_ring_fini(xhci_trb_ring_t *); 77 77 int xhci_trb_ring_enqueue(xhci_trb_ring_t *, xhci_trb_t *, uintptr_t *); 78 78 int xhci_trb_ring_enqueue_multiple(xhci_trb_ring_t *, xhci_trb_t *, size_t, uintptr_t *); … … 112 112 113 113 int xhci_event_ring_init(xhci_event_ring_t *); 114 intxhci_event_ring_fini(xhci_event_ring_t *);114 void xhci_event_ring_fini(xhci_event_ring_t *); 115 115 int xhci_event_ring_dequeue(xhci_event_ring_t *, xhci_trb_t *); 116 116
Note:
See TracChangeset
for help on using the changeset viewer.