Changeset 40a3bfa in mainline
- Timestamp:
- 2017-10-28T11:25:11Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- d46ceb2b
- Parents:
- 58ac3ec
- Location:
- uspace/drv/bus/usb/xhci
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/xhci/bus.c
r58ac3ec r40a3bfa 185 185 int xhci_bus_remove_device(xhci_bus_t *bus, xhci_hc_t *hc, device_t *dev) 186 186 { 187 int err; 187 188 xhci_device_t *xhci_dev = xhci_device_get(dev); 189 190 /* Block creation of new endpoints and transfers. */ 191 usb_log_debug2("Device '%s' going offline.", ddf_fun_get_name(dev->fun)); 192 fibril_mutex_lock(&dev->guard); 193 xhci_dev->online = false; 194 fibril_mutex_unlock(&dev->guard); 195 196 /* Abort running transfers. */ 197 usb_log_debug2("Aborting all active transfers to '%s'.", ddf_fun_get_name(dev->fun)); 198 for (size_t i = 0; i < ARRAY_SIZE(xhci_dev->endpoints); ++i) { 199 xhci_endpoint_t *ep = xhci_dev->endpoints[i]; 200 if (!ep || !ep->base.active) 201 continue; 202 203 /* FIXME: This is racy. */ 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), 209 str_error(err)); 210 } 211 } 212 213 /* TODO: Figure out how to handle errors here. So far, they are reported and skipped. */ 214 215 /* Make DDF (and all drivers) forget about the device. */ 216 if ((err = ddf_fun_unbind(dev->fun))) { 217 usb_log_warning("Failed to unbind DDF function of detached device '%s': %s", 218 ddf_fun_get_name(dev->fun), str_error(err)); 219 } 220 221 /* Deconfigure device if it's still attached. */ 222 if (!xhci_dev->detached) { 223 if ((err = hc_deconfigure_device(hc, xhci_dev->slot_id))) { 224 usb_log_warning("Failed to deconfigure detached device '%s': %s", 225 ddf_fun_get_name(dev->fun), str_error(err)); 226 } 227 } 188 228 189 229 /* Unregister remaining endpoints. */ … … 192 232 continue; 193 233 194 const int err = unregister_endpoint(&bus->base, &xhci_dev->endpoints[i]->base); 195 if (err) 234 if ((err = unregister_endpoint(&bus->base, &xhci_dev->endpoints[i]->base))) { 196 235 usb_log_warning("Failed to unregister EP (%u:%u): %s", dev->address, i, str_error(err)); 236 } 197 237 } 198 238 199 239 // XXX: Ugly here. Move to device_destroy at endpoint.c? 240 if ((err = hc_disable_slot(hc, xhci_dev->slot_id))) { 241 usb_log_warning("Failed to disable slot %d for device '%s': %s", 242 xhci_dev->slot_id, ddf_fun_get_name(dev->fun), str_error(err)); 243 } 244 200 245 free32(xhci_dev->dev_ctx); 201 246 hc->dcbaa[xhci_dev->slot_id] = 0; 247 248 bus->devices_by_slot[xhci_dev->slot_id] = NULL; 249 202 250 return EOK; 203 251 } … … 305 353 /* Tear down TRB ring / PSA. */ 306 354 /* TODO: Make this method "noexcept" */ 307 if ((err = xhci_endpoint_free_transfer_ds(ep))) { 355 /* FIXME: There is some memory corruption going on, causing this to crash. */ 356 /*if ((err = xhci_endpoint_free_transfer_ds(ep))) { 308 357 usb_log_error("Failed to free resources of an endpoint."); 309 } 358 }*/ 310 359 311 360 return EOK; -
uspace/drv/bus/usb/xhci/endpoint.h
r58ac3ec r40a3bfa 125 125 /** True if the device can add new endpoints and schedule transfers. */ 126 126 volatile bool online; 127 128 /** True if the device has been physically detached from the socket. */ 129 volatile bool detached; 127 130 } xhci_device_t; 128 131 -
uspace/drv/bus/usb/xhci/rh.c
r58ac3ec r40a3bfa 187 187 usb_log_info("Device '%s' at port %u has been disconnected.", ddf_fun_get_name(dev->base.fun), port_id); 188 188 189 /* Block creation of new endpoints and transfers. */189 /* Mark the device as detached. */ 190 190 fibril_mutex_lock(&dev->base.guard); 191 dev-> online = false;191 dev->detached = true; 192 192 fibril_mutex_unlock(&dev->base.guard); 193 193 … … 197 197 fibril_mutex_unlock(&rh->device.base.guard); 198 198 199 usb_log_debug2("Aborting all active transfers to '%s'.", ddf_fun_get_name(dev->base.fun));200 201 /* Abort running transfers. */202 for (size_t i = 0; i < ARRAY_SIZE(dev->endpoints); ++i) {203 xhci_endpoint_t *ep = dev->endpoints[i];204 if (!ep || !ep->base.active)205 continue;206 207 /* FIXME: This is racy. */208 if ((err = xhci_transfer_abort(&ep->active_transfer))) {209 usb_log_warning("Failed to abort active %s transfer to "210 " endpoint %d of detached device '%s': %s",211 usb_str_transfer_type(ep->base.transfer_type),212 ep->base.endpoint, ddf_fun_get_name(dev->base.fun),213 str_error(err));214 }215 }216 217 /* TODO: Figure out how to handle errors here. So far, they are reported and skipped. */218 /* TODO: Move parts of the code below to xhci_bus_remove_device() */219 220 /* Make DDF (and all drivers) forget about the device. */221 if ((err = ddf_fun_unbind(dev->base.fun))) {222 usb_log_warning("Failed to unbind DDF function of detached device '%s': %s",223 ddf_fun_get_name(dev->base.fun), str_error(err));224 }225 226 /* Unregister EP0. */227 if ((err = bus_remove_endpoint(&rh->hc->bus.base, &dev->endpoints[0]->base))) {228 usb_log_warning("Failed to unregister configuration endpoint of device '%s' from XHCI bus: %s",229 ddf_fun_get_name(dev->base.fun), str_error(err));230 }231 232 /* Deconfigure device. */233 if ((err = hc_deconfigure_device(rh->hc, dev->slot_id))) {234 usb_log_warning("Failed to deconfigure detached device '%s': %s",235 ddf_fun_get_name(dev->base.fun), str_error(err));236 }237 238 /* TODO: Free EP0 structures. */239 /* TODO: Destroy EP0 by removing its last reference. */240 241 199 /* Remove device from XHCI bus. */ 242 200 if ((err = xhci_bus_remove_device(&rh->hc->bus, rh->hc, &dev->base))) { … … 245 203 } 246 204 247 /* Disable device slot. */248 if ((err = hc_disable_slot(rh->hc, dev->slot_id))) {249 usb_log_warning("Failed to disable slot for device '%s': %s",250 ddf_fun_get_name(dev->base.fun), str_error(err));251 }252 253 205 /* Destroy DDF device. */ 254 206 hcd_ddf_device_destroy(&dev->base); 255 207 256 // TODO: Free device context. 257 // TODO: Free TRB rings. 258 // TODO: Figure out what was forgotten and free that as well. 208 /* TODO: Figure out what was forgotten and free that as well. */ 259 209 260 210 return EOK;
Note:
See TracChangeset
for help on using the changeset viewer.